rails: SafeBuffer#gsub breaks block form match variables $1, $2, $`, $&, and $’
commit 53a2c0baf2b128dd4808eca313256f6f4bb8c4cd introduced a change to ensure gsub returns an unsafe string.
When gsub is used in block form, variables such as $1, $2, $`, $&, and $’ will be set appropriately. Now it seems that SafeBuffer’s intervention loses the context and these variables are no longer available in the block.
This is the simplest test I can make to demonstrate the issue (which currently fails on 3.0-stable)…
class SafeBufferTest < ActiveSupport::TestCase
def setup
@buffer = ActiveSupport::SafeBuffer.new
end
[..]
test "Should not break gsub block form match variables" do
@buffer << 'matchme'
@buffer.gsub(/(matchme)/) { assert_equal 'matchme', $1 }
end
So far it’s know that this breaks escape_javascript since it uses $1 matcher (see https://github.com/rails/rails/issues/1553 ). I presume there may be others also affected.
Investigating what a good fix would be… seems awful heavy handed to have to capture and reset all those variables, but on the other hand, its bad form to leave a ruby core method different from it’s documented behaviour.
About this issue
- Original URL
- State: closed
- Created 13 years ago
- Reactions: 1
- Comments: 34 (24 by maintainers)
Commits related to this issue
- Fix for Integration::Session follow_redirect! headers['location'] bug with Rack [#1555 state:resolved] Signed-off-by: Joshua Peek <josh@joshpeek.com> — committed to jake3030/rails by deleted user 16 years ago
- Workaround rails bug with html_safe and URI.encode See http://stackoverflow.com/a/9470948/670229 and https://github.com/rails/rails/issues/1555 — committed to coletivoEITA/noosfero by brauliobo 8 years ago
- html_safe: workaround rails bug and URI.encode See http://stackoverflow.com/a/9470948/670229 and https://github.com/rails/rails/issues/1555 — committed to noosfero/noosfero by brauliobo 8 years ago
- Monkeypatch ActiveSupport's broken SafeBuffer.gsub method. Solution copied from https://makandracards.com/makandra/11171-how-to-fix-gsub-on-safebuffer-objects. Also see https://github.com/rails/rails/... — committed to thewca/worldcubeassociation.org by jfly 7 years ago
- Monkeypatch ActiveSupport's broken SafeBuffer.gsub method. Solution copied from https://makandracards.com/makandra/11171-how-to-fix-gsub-on-safebuffer-objects. Also see https://github.com/rails/rails/... — committed to thewca/worldcubeassociation.org by jfly 7 years ago
- Work around ActiveSupport's broken SafeBuffer.gsub method. See https://github.com/rails/rails/issues/10598 and https://github.com/rails/rails/issues/1555. — committed to thewca/worldcubeassociation.org by jfly 7 years ago
- Work around ActiveSupport's broken SafeBuffer.gsub method. See https://github.com/rails/rails/issues/10598 and https://github.com/rails/rails/issues/1555. — committed to thewca/worldcubeassociation.org by jfly 7 years ago
- Work around ActiveSupport's broken SafeBuffer.gsub method. See https://github.com/rails/rails/issues/10598 and https://github.com/rails/rails/issues/1555. — committed to thewca/worldcubeassociation.org by jfly 7 years ago
- Fix compatibility issue with Mail 2.7.0 In Mail 2.7.0 in an actual Rails application, HTML part of the body now returns an `ActiveSupport::SafeBuffer` object instead of a String object. This causes a... — committed to sikachu/email-spec by sikachu 7 years ago
- revert the changes from c60995f3 - related to marking sub,gsub as unavailable to use with safe strings — committed to rails/rails by vijaydev 13 years ago
- Fix compatibility issue with Mail 2.7.0 In Mail 2.7.0 in an actual Rails application, HTML part of the body now returns an `ActiveSupport::SafeBuffer` object instead of a String object. This causes a... — committed to email-spec/email-spec by sikachu 7 years ago
- Don't call `gsub` on a `SafeBuffer`. SafeBuffer#gsub doesn't set backreferences ($1, $2, etc...) correctly due to https://github.com/rails/rails/issues/1555 . Avoid that by converting the SafeBuffer... — committed to advancingfaculty/rails-latex by deleted user 5 years ago
- Don't call `gsub` on a `SafeBuffer`. SafeBuffer#gsub doesn't set backreferences ($1, $2, etc...) correctly due to https://github.com/rails/rails/issues/1555 . Avoid that by converting the SafeBuffer... — committed to advancingfaculty/rails-latex by deleted user 5 years ago
- Don't call `gsub` on a `SafeBuffer`. SafeBuffer#gsub doesn't set backreferences ($1, $2, etc...) correctly due to https://github.com/rails/rails/issues/1555 . Avoid that by converting the SafeBuffer... — committed to advancingfaculty/rails-latex by deleted user 5 years ago
@josevalim @tenderlove this issue should not have been closed, as it still exists in rails 5.1.6. I don’t know how many hours have been lost by people chasing down the issue over the years. Please reinstate the warnings that were inexplicably and irresponsibly reverted by https://github.com/rails/rails/commit/e05d4cea69919ed0a2e5832bde120b5d0f12c0ec#diff-f639a79f308e72f54af369291a4d5907
I just ran into this issue again today (using rails 5.1.4) and wasted quite some time debugging before I realized
ActiveSupport::SafeBufferwas the cause. It looks like I am not the only one who continues to get bitten by this.It looks like this issue was closed by https://github.com/rails/rails/pull/2248 but then that fix was reverted (why?). I would suggest reopening this until a solution is finally merged. (Closing the issue suggests that it was resolved. If it was resolved, what was the resolution??)
Perhaps raise an error when
gsubis used on aSafeBuffer, or at least emit a warning?Just ran into this issue again today (using Rails 5.0 and Ruby 2.4.1) and took quite some time before I realized ActiveSupport::SafeBuffer was the cause. I see there were several attempts at fixes, which were uncompleted or reverted. It would however be nice if we could at least show a warning when this is happening to prevent wasting time.
Note: this is also a problem when using
Regexp.last_match(as did I).Just ran into this problem myself, and lucked into finding this thread. Wanted to add one important note for other travelers.
The solution provided by @dmathieu…
worked for me, however note that you must use
to_strrather thanto_s.SafeBuffer inherits from String and overrides
to_sto returnself, but does not touchto_str, which is why it works in this case.I also just spent a good deal of my day tracking down this bug.
Issue #1555 was resolved by pull request #2248 which raises an exception for these methods, but this change was reverted on the same day for some reason. I think raising an exception when called with a block would be far more sensible than knowingly letting it run in a broken state?