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::SafeBuffer
was 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
gsub
is 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_str
rather thanto_s
.SafeBuffer inherits from String and overrides
to_s
to 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?