addressable icon indicating copy to clipboard operation
addressable copied to clipboard

Type mismatch causes Addressable::URI#query_values= to fail on sort! with "comparison of Array with Array failed"

Open rehevkor5 opened this issue 11 years ago • 12 comments

If the data passed to query_values= results in a type mismatch in the value of new_query_values on line 1504 when .sort! is called, such as:

[['a', '1'], ['a', 2]]

the method will fail with ``sort!': comparison of Array with Array failed`

I'd submit a PR fix myself, but I'm not sure what the desired solution is.

rehevkor5 avatar Dec 13 '12 16:12 rehevkor5

What version of Addressable are you using? I can't duplicate.

sporkmonger avatar Dec 13 '12 16:12 sporkmonger

2.3.2

Maybe need to make sure you're passing a hash into query_value=

rehevkor5 avatar Dec 13 '12 17:12 rehevkor5

Nope, still can't duplicate. Provide a minimal working example of the bug please.

sporkmonger avatar Dec 13 '12 17:12 sporkmonger

Try this:

1.9.3p194 :002 > require 'addressable/uri'
 => true 
...
1.9.3p194 :006 > uri = Addressable::URI.parse('http://example.com/?page=1')
 => #<Addressable::URI:0x3fd3f85b8b30 URI:http://example.com/?page=1> 
1.9.3p194 :007 > uri.query_values = uri.query_values.merge(:page => 2)
ArgumentError: comparison of Array with Array failed
    from /Users/shannoncarey/.rvm/gems/ruby-1.9.3-p194@hermes-frontend/gems/addressable-2.3.2/lib/addressable/uri.rb:1504:in `sort!'
    from /Users/shannoncarey/.rvm/gems/ruby-1.9.3-p194@hermes-frontend/gems/addressable-2.3.2/lib/addressable/uri.rb:1504:in `query_values='
    from (irb):7
    from /Users/shannoncarey/.rvm/gems/ruby-1.9.3-p194@hermes-frontend/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
    from /Users/shannoncarey/.rvm/gems/ruby-1.9.3-p194@hermes-frontend/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start'
    from /Users/shannoncarey/.rvm/gems/ruby-1.9.3-p194@hermes-frontend/gems/railties-3.2.9/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

rehevkor5 avatar Dec 13 '12 20:12 rehevkor5

The problem here is query_values always returns a hash keys and values as strings after the parse, and then {"page" => "1"}.merge({:page => 2}) --> {"page" => "1", :page => 2}

that code in lib/addressable/uri.rb:197

new_query_values = new_query_values.to_hash
new_query_values = new_query_values.map do |key, value|
  key = key.to_s if key.kind_of?(Symbol)
  [key, value]
 end

The new_query_values has [["page", "1"], ["page", 2]] and when use new_query_values.sort! first sort by first value (the keys) and if are equal, sort by the second values (the hash values), but you can't compare String with Integer.

csaura avatar Feb 01 '13 15:02 csaura

Could you write a test that reproduces this problem?

sporkmonger avatar Feb 01 '13 21:02 sporkmonger

I'll have one for you shortly.

rehevkor5 avatar Feb 04 '13 16:02 rehevkor5

See associated PR.

rehevkor5 avatar Feb 04 '13 16:02 rehevkor5

Thank you, that helps a lot.

sporkmonger avatar Feb 04 '13 19:02 sporkmonger

Had the same issue, solved by stringify_keys; but I think this one should be solved inside addressable it self.

dmitry avatar Jun 13 '16 07:06 dmitry

@dmitry It's come up before and as before, the answer is essentially no, won't fix. If Ruby adds an indifferent access hash structure to the standard library, I'll revisit that answer, but until then, I prefer for this kind of usage to be explicitly controlled by the user of the library, exactly as you're doing. I strongly argue that principle of least surprise was violated when Rails introduced this pattern in the first place and I reject the idea that once they made bad behavior commonplace that suddenly good behavior became "surprising".

sporkmonger avatar Jun 15 '16 21:06 sporkmonger

@sporkmonger I agree, but in that case the small note should be added to the documentation, as keys should be strings, and not symbols because of the ambiguous while sorting and forming the query. Somewhere here:

https://github.com/sporkmonger/addressable/blob/master/lib/addressable/uri.rb#L1607

dmitry avatar Jun 16 '16 06:06 dmitry