Skip to content

ActiveSupport::SafeBuffer#prepend inconsistency#14529

Merged
rafaelfranca merged 2 commits into
rails:masterfrom
rwz:master
Apr 2, 2014
Merged

ActiveSupport::SafeBuffer#prepend inconsistency#14529
rafaelfranca merged 2 commits into
rails:masterfrom
rwz:master

Conversation

@rwz

@rwz rwz commented Mar 30, 2014

Copy link
Copy Markdown
Contributor

Native ruby String#prepend modifies instance in-place, while ActiveSupport::SafeBuffer returns modified version, but the initial object remains unchanged.

a = "bar"           # => "bar"
a.prepend "foo"     # => "foobar"
a                   # => "foobar"
b = "bar".html_safe # => "bar"
b.class             # => ActiveSupport::SafeBuffer
b.prepend "foo"     # => "foobar"
b                   # => "bar", expected "foobar"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unto should be onto?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ming-kernel Yep, you're right. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think prepend should even mark an string html safe. We are changing the behavior and also we may opening a XSS vector.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafaelfranca this is how #concat currently works. I guess it'd make sense to use the same behavior for #prepend

@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

What's the status of this? Are we waiting for someone to make a decision or an alternative implementation to show up?

@rafaelfranca

Copy link
Copy Markdown
Member

Sorry, many issues to handle. It is missing CHANGELOG

@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

Ah, alright, will add changelog then.

@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

Done.

@rafaelfranca

Copy link
Copy Markdown
Member

We should not remove prepend! without a deprecation message. Mind to add it?

@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

ok

Make `#prepend` method modify instance in-place and return self
instead of just returning modified value. That is exactly what
`#prepend!` method was doing previously, so it's deprecated from
now on.
@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

Done.

@rafaelfranca

Copy link
Copy Markdown
Member

Thank you. I'll merge it

@matthewd

matthewd commented Apr 1, 2014

Copy link
Copy Markdown
Member

Do we want #concat to be defined via define_method? What about extracting the commonality via a helper...

def concat(value)
  super(maybe_escape(value))
end

def prepend(value)
  super(maybe_escape(value))
end

private
def maybe_escape(value)
  if html_safe? && !value.html_safe?
    ERB::Util.h(value)
  else
    value
  end
end

wdyt?

@rwz

rwz commented Apr 1, 2014

Copy link
Copy Markdown
Contributor Author

@matthewd that'll produce two separate methods with exact same implementation, which might be even more confusing than a define_method approach. Also, I was reluctant to introduce another helper method on a global class just for that.

@matthewd

matthewd commented Apr 1, 2014

Copy link
Copy Markdown
Member

Hmm, I just realised there's actually already html_escape_interpolated_argument.

As for visually matching methods, I personally don't think that's particularly confusing -- especially when the very first word of the method body is 'super'... but I'm just thinking out loud. It's up to @rafaelfranca which he prefers. And the one that someone cared enough to make, sure has a certain argument over my bikeshedding. 💙

@rwz

rwz commented Apr 2, 2014

Copy link
Copy Markdown
Contributor Author

I've added a commit to make use of this helper effectively DRYing the code. Thanks, good catch.

rafaelfranca added a commit that referenced this pull request Apr 2, 2014
ActiveSupport::SafeBuffer#prepend inconsistency
@rafaelfranca rafaelfranca merged commit 8482895 into rails:master Apr 2, 2014

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the require be on the actual file rather than the test?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍. Fixing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants