Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveSupport::SafeBuffer#prepend inconsistency #14529

Merged
merged 2 commits into from Apr 2, 2014
Merged

Conversation

@rwz
Copy link
Contributor

rwz commented Mar 30, 2014

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"
assert_equal @string, "otherhello"
end

test "Prepending unsafe unto safe yields escaped safe" do

This comment has been minimized.

Copy link
@ming-kernel

ming-kernel Mar 30, 2014

unto should be onto?

This comment has been minimized.

Copy link
@rwz

rwz Mar 30, 2014

Author Contributor

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

@robin850 robin850 added activemodel and removed activemodel labels Mar 30, 2014
test "Prepending unsafe onto safe yields escaped safe" do
other = "other".html_safe
other.prepend "<foo>"
assert other.html_safe?

This comment has been minimized.

Copy link
@rafaelfranca

rafaelfranca Mar 30, 2014

Member

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.

This comment has been minimized.

Copy link
@rwz

rwz Mar 30, 2014

Author Contributor

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

@rwz
Copy link
Contributor Author

rwz commented Apr 1, 2014

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
Member

rafaelfranca commented Apr 1, 2014

Sorry, many issues to handle. It is missing CHANGELOG

@rwz
Copy link
Contributor Author

rwz commented Apr 1, 2014

Ah, alright, will add changelog then.

@rwz
Copy link
Contributor Author

rwz commented Apr 1, 2014

Done.

@rafaelfranca
Copy link
Member

rafaelfranca commented Apr 1, 2014

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

@rwz
Copy link
Contributor Author

rwz commented Apr 1, 2014

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
Copy link
Contributor Author

rwz commented Apr 1, 2014

Done.

@rafaelfranca
Copy link
Member

rafaelfranca commented Apr 1, 2014

Thank you. I'll merge it

@matthewd
Copy link
Member

matthewd commented Apr 1, 2014

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
Copy link
Contributor Author

rwz commented Apr 1, 2014

@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
Copy link
Member

matthewd commented Apr 1, 2014

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
Copy link
Contributor Author

rwz commented Apr 2, 2014

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
1 check passed
1 check passed
default The Travis CI build passed
Details
@@ -4,6 +4,7 @@
require 'inflector_test_cases'
require 'constantize_test_cases'

require 'active_support/deprecation/reporting'

This comment has been minimized.

Copy link
@carlosantoniodasilva

carlosantoniodasilva Apr 2, 2014

Member

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

This comment has been minimized.

Copy link
@rafaelfranca

rafaelfranca Apr 2, 2014

Member

👍. Fixing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
You can’t perform that action at this time.