Does URI.escape have a bug?

uri = 'http://example.com/[foo\]'

=> "http://example.com/[foo\]"

escaped = URI.escape(uri)

=> "http://example.com/[foo\]"

URI.parse(escaped)

URI::InvalidURIError: bad URI(is not URI?): http://example.com/[foo\]

Shouldn't URI.escape(uri) return "http://example.com/[foo]"? Then
URI.parse wouldn't raise an error.

-Justin

Hi Justin

URI::escape has been deprecated in Ruby 1.9.2, If you use CGI::escape, it works.

But I agree, this looks like a bug...

Cheers,
Milan

···

On 07.11.2015, at 15:40, Justin Coyne <jcoyne@justincoyne.com> wrote:

> uri = 'http://example.com/[foo\]&#39;
=> "http://example.com/[foo\]&quot;
> escaped = URI.escape(uri)
=> "http://example.com/[foo\]&quot;
> URI.parse(escaped)
URI::InvalidURIError: bad URI(is not URI?): http://example.com/[foo\]

Shouldn't URI.escape(uri) return "http://example.com/[foo]&quot;? Then URI.parse wouldn't raise an error.

-Justin

I'm using Ruby 2.2.3. And there's no indication in the docs that it's
deprecated:

Furthermore CGI.escape produces the wrong output because it escapes every
character including slashes and the colin that separates host from port.
For example:

CGI.escape(uri)

=> "http%3A%2F%2Fexample.com%2F%5Bfoo%5D"

-Justin

-Justin

···

On Sat, Nov 7, 2015 at 11:24 AM, Milan van Zanten <milan@milanovi.ch> wrote:

Hi Justin

URI::escape has been deprecated in Ruby 1.9.2, If you use CGI::escape, it
works.

But I agree, this looks like a bug...

Cheers,
Milan

On 07.11.2015, at 15:40, Justin Coyne <jcoyne@justincoyne.com> wrote:

> uri = 'http://example.com/[foo\]&#39;
=> "http://example.com/[foo\]&quot;
> escaped = URI.escape(uri)
=> "http://example.com/[foo\]&quot;
> URI.parse(escaped)
URI::InvalidURIError: bad URI(is not URI?): http://example.com/[foo\]

Shouldn't URI.escape(uri) return "http://example.com/[foo]&quot;? Then
URI.parse wouldn't raise an error.

-Justin

Regardless of the state of URI.escape, shouldn't URI::RFC2396_Parser#escape
properly escape brackets?

-Justin

···

On Sat, Nov 7, 2015 at 2:14 PM, Justin Coyne <jcoyne@justincoyne.com> wrote:

I'm using Ruby 2.2.3. And there's no indication in the docs that it's
deprecated:

Module: URI::Escape (Ruby 2.2.0)

Furthermore CGI.escape produces the wrong output because it escapes every
character including slashes and the colin that separates host from port.
For example:

> CGI.escape(uri)
=> "http%3A%2F%2Fexample.com%2F%5Bfoo%5D"

-Justin

-Justin

On Sat, Nov 7, 2015 at 11:24 AM, Milan van Zanten <milan@milanovi.ch> > wrote:

Hi Justin

URI::escape has been deprecated in Ruby 1.9.2, If you use CGI::escape, it
works.

But I agree, this looks like a bug...

Cheers,
Milan

On 07.11.2015, at 15:40, Justin Coyne <jcoyne@justincoyne.com> wrote:

> uri = 'http://example.com/[foo\]&#39;
=> "http://example.com/[foo\]&quot;
> escaped = URI.escape(uri)
=> "http://example.com/[foo\]&quot;
> URI.parse(escaped)
URI::InvalidURIError: bad URI(is not URI?): http://example.com/[foo\]

Shouldn't URI.escape(uri) return "http://example.com/[foo]&quot;? Then
URI.parse wouldn't raise an error.

-Justin

If you look at the source of URI::escape, it looks like this:

def escape(*arg)
  warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
  DEFAULT_PARSER.escape(*arg)
end

So you'd have to run your code verbose with warnings to be notified about the deprecation.

You are right about the wrong output of CGI::escape, it is meant to encode parameters.
This great post (http://stackoverflow.com/a/13059657\) suggests using the Adressable gem (Class: Addressable::URI — Documentation for addressable (2.2.4)) which does quite a good job at escaping whole urls.

Milan

···

On 07.11.2015, at 20:20, Justin Coyne <jcoyne@justincoyne.com> wrote:

Regardless of the state of URI.escape, shouldn't URI::RFC2396_Parser#escape properly escape brackets?

-Justin

On Sat, Nov 7, 2015 at 2:14 PM, Justin Coyne <jcoyne@justincoyne.com> wrote:
I'm using Ruby 2.2.3. And there's no indication in the docs that it's deprecated:

Module: URI::Escape (Ruby 2.2.0)

Furthermore CGI.escape produces the wrong output because it escapes every character including slashes and the colin that separates host from port. For example:

> CGI.escape(uri)
=> "http%3A%2F%2Fexample.com%2F%5Bfoo%5D"

-Justin

-Justin

On Sat, Nov 7, 2015 at 11:24 AM, Milan van Zanten <milan@milanovi.ch> wrote:
Hi Justin

URI::escape has been deprecated in Ruby 1.9.2, If you use CGI::escape, it works.

But I agree, this looks like a bug...

Cheers,
Milan

On 07.11.2015, at 15:40, Justin Coyne <jcoyne@justincoyne.com> wrote:

> uri = 'http://example.com/[foo\]&#39;
=> "http://example.com/[foo\]&quot;
> escaped = URI.escape(uri)
=> "http://example.com/[foo\]&quot;
> URI.parse(escaped)
URI::InvalidURIError: bad URI(is not URI?): http://example.com/[foo\]

Shouldn't URI.escape(uri) return "http://example.com/[foo]&quot;? Then URI.parse wouldn't raise an error.

-Justin