Bug #14732
closedCGI.unescape returns different instance between Ruby 2.3 and 2.4
Description
In Ruby 2.3, CGI.unescape always returns String object:
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("a")).class'
ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-darwin17]
String
But in Ruby 2.4, it might return non-String object when the argument value is not a String instance:
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("a")).class'
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]
S
This change triggered the following issue:
https://github.com/rest-client/rest-client/issues/662
Is this change intentional?
Updated by normalperson (Eric Wong) almost 6 years ago
me@jnito.com wrote:
Bug #14732: CGI.unescape returns different instance between Ruby 2.3 and 2.4
https://bugs.ruby-lang.org/issues/14732
Fixing...
Updated by normalperson (Eric Wong) almost 6 years ago
- Backport changed from 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN to 2.3: REQUIRED, 2.4: REQUIRED, 2.5: REQUIRED
Updated by normalperson (Eric Wong) almost 6 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r63328.
ext/cgi/escape: preserve String subclass in result
- ext/cgi/escape/escape.c (optimized_escape_html): use rb_str_new_with_class
(optimized_unescape_html): ditto
(optimized_escape): ditto
(optimized_unescape): ditto - test/cgi/test_cgi_util.rb (test_escape_string_subclass): new test
[ruby-core:86847] [Bug #14732]
Updated by normalperson (Eric Wong) almost 6 years ago
r63328 This also affects 2.3 for unescapeHTML.
Updated by jnchito (Junichi Ito) almost 6 years ago
normalperson (Eric Wong) wrote:
r63328 This also affects 2.3 for unescapeHTML.
I confirmed r63328, but could not understand the valid specification.
In Ruby 2.3, CGI.escape and CGI.unescape always return String instance regardless of class and value:
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.escape(S.new("a")).class'
ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-darwin17]
String
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.escape(S.new(">")).class'
ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-darwin17]
String
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("a")).class'
ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-darwin17]
String
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("%3E")).class'
ruby 2.3.6p384 (2017-12-14 revision 61254) [x86_64-darwin17]
String
In Ruby 2.4, results differ according to argument values:
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.escape(S.new("a")).class'
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]
S
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.escape(S.new(">")).class'
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]
String
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("a")).class'
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]
S
$ ruby -v -rcgi/util -e 'class S < String; end; puts CGI.unescape(S.new("%3E")).class'
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]
String
With r63328, I feel the all results would be the instance of "S" and this behavior is different from Ruby 2.3. But is this valid in Ruby 2.4?
Updated by normalperson (Eric Wong) almost 6 years ago
- Status changed from Closed to Open
I'm actually not sure what the correct behavior should be...
Updated by normalperson (Eric Wong) almost 6 years ago
me@jnito.com wrote:
normalperson (Eric Wong) wrote:
r63328 This also affects 2.3 for unescapeHTML.
I confirmed r63328, but could not understand the valid specification.
In Ruby 2.3, CGI.escape and CGI.unescape always return String instance regardless of class and value:
Wait, sorry, I misread your original. I guess it's the use of
String#b in the pure Ruby version.
With r63328, I feel the all results would be the instance of
"S" and this behavior is different from Ruby 2.3. But is this
valid in Ruby 2.4?
Sorry, I'm not sure, anymore. I revert r63328
Updated by jeremyevans0 (Jeremy Evans) almost 4 years ago
- Status changed from Open to Closed
I'm not sure if this behavior change between Ruby 2.3 and 2.4 was originally expected. However, I don't see why we would want to revert to the previous, and the current behavior doesn't seem to be a bug. Please submit a feature request if you would like to return to the Ruby <2.4 behavior.