Project

General

Profile

Actions

Bug #14732

closed

CGI.unescape returns different instance between Ruby 2.3 and 2.4

Added by jnchito (Junichi Ito) almost 6 years ago. Updated almost 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:86847]
Tags:

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

wrote:

Bug #14732: CGI.unescape returns different instance between Ruby 2.3 and 2.4
https://bugs.ruby-lang.org/issues/14732

Fixing...

Actions #2

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
Actions #3

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

https://bugs.ruby-lang.org/issues/14732

r63328 This also affects 2.3 for unescapeHTML.

Updated by jnchito (Junichi Ito) almost 6 years ago

normalperson (Eric Wong) wrote:

https://bugs.ruby-lang.org/issues/14732

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

wrote:

normalperson (Eric Wong) wrote:

https://bugs.ruby-lang.org/issues/14732

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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0