cgi icon indicating copy to clipboard operation
cgi copied to clipboard

The unreleased Ruby 3.5.0 raises NoMethodError: undefined method 'parse' for class CGI

Open piotrmurach opened this issue 7 months ago • 4 comments

I'm running my test suite against ruby-head, jruby-head and truffleruby-head. I experience this failure only on CRuby.

The rouge gem(one of my dependencies) relies on cgi.

My test suite was fully green on the ruby-head until a week ago, when it started and continues to fail consistently with the following error:

      NoMethodError:
        undefined method 'parse' for class CGI
      # ./vendor/bundle/ruby/3.5.0+1/gems/rouge-4.5.2/lib/rouge/lexer.rb:55:in 'Rouge::Lexer.lookup_fancy'

Here is the full job.

I looked at the recent commits to see whether the cgi gem API has changed. The parse method indeed exists on the CGI class on the master branch. However, this may be something to do with how the cgi is bundled with the Ruby release?

piotrmurach avatar May 25 '25 19:05 piotrmurach

CGI.parse will be removed from Ruby 3.5 for our security reason. See https://bugs.ruby-lang.org/issues/21258

I recommend to replace that with URI.decode_www_form. I know URI.decode_www_form is different behavior with CGI.parse especial multiple value.

>> url = "https://example.com/foo?bar=buzz&bar=foo"
>> URI.decode_www_form(URI(url).query)
=> [["bar", "buzz"], ["bar", "foo"]]
>> CGI.parse(URI(url).query)
=> {"bar" => ["buzz", "foo"]}

If you need to CGI.parse with Ruby 3.5 or later, could you add cgi to your dependency?

Sorry for your incovenience.

hsbt avatar May 28 '25 02:05 hsbt

Thank you for the quick response and for providing the related feature report.

I recommend to replace that with URI.decode_www_form. I know URI.decode_www_form is different behavior with CGI.parse especial multiple value.

The cgi is used by a third-party rouge gem that I depend on. There is already a PR submitted with exactly this change.

If you need to CGI.parse with Ruby 3.5 or later, could you add cgi to your dependency?

I can add cgi version 0.4.2 as a development dependency in the Gemfile to make the CI pass for now. I don't want to add it as a dependency. I'd rather the rouge gem accept the change, switching from cgi to uri.

Sorry for your incovenience.

I appreciate you taking care of the Ruby ecosystem. ❤

piotrmurach avatar May 28 '25 20:05 piotrmurach

@hsbt Does this mean that the CGI that remains bundled with Ruby 3.5 will not be this gem? We'll have a split-brain CGI library? The latest release of this gem still has parse, and the latest Ruby 3.5 does not.

Relatedly, if we depend on the gem going forward will it allow us to continue using CGI.parse, or will we have to migrate to URI.decode_www_form?

pboling avatar Jul 08 '25 17:07 pboling

@pboling I want to rename CGI.escape family to like URI.cgi_escape in Ruby 3.5. But some core team member strongly against that proposal.

You can use CGI.escape without cgi gem in Ruby 3.5. If you need CGI.parse, you should use cgi gem or rewrite with URI.decode_www_form.

hsbt avatar Jul 08 '25 22:07 hsbt