Re: UriComponent.validate does not allow brackets []?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UriComponent.validate does not allow brackets []?

Paul Sandoz
Administrator
Martin Grotzke wrote:
> Hi,
>
> we have a resource method that accepts some query parameter named fq
> (filter query). The fq param accepts ranges for e.g. a price filter, so
> that the value for the fq param might be "price:[160%20TO%20200]".
>

According to the URI ABNF:

    sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                / "*" / "+" / "," / ";" / "="

    unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
    pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
    query       = *( pchar / "/" / "?" )

'[' and ']' characters are not valid characters of a URI query component.


> When a client performs a request with such a param value, the
> UriComponent.validate says that this is not valid:
>
> [ERROR] 17 Jul 2008 15:50:45,166 btpool0-1 com.sun.jersey.spi.spring.container.servlet.SpringServlet.service:
> Caught exception.
>
> java.lang.IllegalArgumentException: The string 'q=foo&fq=price:[160%20TO%20200]' for the URI component QUERY contains an invalid character, '[', at index 15
> at com.sun.jersey.api.uri.UriComponent.validate(UriComponent.java:95)
> at com.sun.jersey.impl.uri.UriBuilderImpl.encode(UriBuilderImpl.java:353)
> at com.sun.jersey.impl.uri.UriBuilderImpl.replaceQueryParams(UriBuilderImpl.java:286)
> at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:273)
>
> I think this should be valid, even UriComponent.decode handles this
> correctly.
>

The JavaDoc states:

/**
  * Decodes characters of a string that are percent-encoded octets using
  * UTF-8 decoding (if needed).
  * <p>
  * It is assumed that the string is valid according to an (unspecified)
URI
  * component type. If a sequence of contiguous percent-encoded octets is
  * not a valid UTF-8 character then the octets are replaced with '\uFFFD'.
  * <p>
  * If the URI component is of type HOST then any "%" found between "[]" is
  * left alone. It is an IPv6 literal with a scope_id.
  * <p>
  * @param s the string to be decoded.
  * @param t the URI component type, may be null.
  * @return the decoded string.
  * @throws IllegalArgumentException if a malformed percent-encoded octet is
  *         detected
  */

Paul.

> One possible patch I can think of is in
> UriComponent.creatingEncodingTables:
>
> Index: src/api/com/sun/jersey/api/uri/UriComponent.java
> ===================================================================
> --- src/api/com/sun/jersey/api/uri/UriComponent.java    (revision 1166)
> +++ src/api/com/sun/jersey/api/uri/UriComponent.java    (working copy)
> @@ -243,6 +243,8 @@
>          tables[Type.PATH.ordinal()] = creatingEncodingTable(l);
>
>          l.add("?");
> +        l.add("[");
> +        l.add("]");
>
>          tables[Type.QUERY.ordinal()] = creatingEncodingTable(l);
>          tables[Type.FRAGMENT.ordinal()] = tables[Type.QUERY.ordinal()];
>
> This test goes through then:
>
> Index: test/com/sun/jersey/impl/UriComponentValidateTest.java
> ===================================================================
> --- test/com/sun/jersey/impl/UriComponentValidateTest.java      (revision 1166)
> +++ test/com/sun/jersey/impl/UriComponentValidateTest.java      (working copy)
> @@ -54,4 +54,8 @@
>          assertEquals(true, UriComponent.valid("/x20y", UriComponent.Type.PATH));
>          assertEquals(true, UriComponent.valid("/x%20y", UriComponent.Type.PATH));
>      }
> +
> +    public void testQuery() {
> +        assertEquals(true, UriComponent.valid("fq=price:[1%20TO%20100]", UriComponent.Type.QUERY));
> +    }
>  }
>
> Please notice that I took this diff in a branch, so line numbers might
> be wrong.
>
> Any thoughts on this?
>
> Thanx && cheers,
> Martin
>
>

--
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UriComponent.validate does not allow brackets []?

Martin Grotzke-2
Hi Paul,

thanx for your feedback! Now I changed the URI for my test to use
URLCodec and it works :)

 "/products?q=foo&fq=price:" + new URLCodec().encode( "[10 TO 100]" );  

Cheers,
Martin


On Tue, 2008-07-22 at 13:19 +0200, Paul Sandoz wrote:

> Martin Grotzke wrote:
> > Hi,
> >
> > we have a resource method that accepts some query parameter named fq
> > (filter query). The fq param accepts ranges for e.g. a price filter, so
> > that the value for the fq param might be "price:[160%20TO%20200]".
> >
>
> According to the URI ABNF:
>
>     sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
>                 / "*" / "+" / "," / ";" / "="
>
>     unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
>     pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
>     query       = *( pchar / "/" / "?" )
>
> '[' and ']' characters are not valid characters of a URI query component.
>
>
> > When a client performs a request with such a param value, the
> > UriComponent.validate says that this is not valid:
> >
> > [ERROR] 17 Jul 2008 15:50:45,166 btpool0-1 com.sun.jersey.spi.spring.container.servlet.SpringServlet.service:
> > Caught exception.
> >
> > java.lang.IllegalArgumentException: The string 'q=foo&fq=price:[160%20TO%20200]' for the URI component QUERY contains an invalid character, '[', at index 15
> > at com.sun.jersey.api.uri.UriComponent.validate(UriComponent.java:95)
> > at com.sun.jersey.impl.uri.UriBuilderImpl.encode(UriBuilderImpl.java:353)
> > at com.sun.jersey.impl.uri.UriBuilderImpl.replaceQueryParams(UriBuilderImpl.java:286)
> > at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:273)
> >
> > I think this should be valid, even UriComponent.decode handles this
> > correctly.
> >
>
> The JavaDoc states:
>
> /**
>   * Decodes characters of a string that are percent-encoded octets using
>   * UTF-8 decoding (if needed).
>   * <p>
>   * It is assumed that the string is valid according to an (unspecified)
> URI
>   * component type. If a sequence of contiguous percent-encoded octets is
>   * not a valid UTF-8 character then the octets are replaced with '\uFFFD'.
>   * <p>
>   * If the URI component is of type HOST then any "%" found between "[]" is
>   * left alone. It is an IPv6 literal with a scope_id.
>   * <p>
>   * @param s the string to be decoded.
>   * @param t the URI component type, may be null.
>   * @return the decoded string.
>   * @throws IllegalArgumentException if a malformed percent-encoded octet is
>   *         detected
>   */
>
> Paul.
>
> > One possible patch I can think of is in
> > UriComponent.creatingEncodingTables:
> >
> > Index: src/api/com/sun/jersey/api/uri/UriComponent.java
> > ===================================================================
> > --- src/api/com/sun/jersey/api/uri/UriComponent.java    (revision 1166)
> > +++ src/api/com/sun/jersey/api/uri/UriComponent.java    (working copy)
> > @@ -243,6 +243,8 @@
> >          tables[Type.PATH.ordinal()] = creatingEncodingTable(l);
> >
> >          l.add("?");
> > +        l.add("[");
> > +        l.add("]");
> >
> >          tables[Type.QUERY.ordinal()] = creatingEncodingTable(l);
> >          tables[Type.FRAGMENT.ordinal()] = tables[Type.QUERY.ordinal()];
> >
> > This test goes through then:
> >
> > Index: test/com/sun/jersey/impl/UriComponentValidateTest.java
> > ===================================================================
> > --- test/com/sun/jersey/impl/UriComponentValidateTest.java      (revision 1166)
> > +++ test/com/sun/jersey/impl/UriComponentValidateTest.java      (working copy)
> > @@ -54,4 +54,8 @@
> >          assertEquals(true, UriComponent.valid("/x20y", UriComponent.Type.PATH));
> >          assertEquals(true, UriComponent.valid("/x%20y", UriComponent.Type.PATH));
> >      }
> > +
> > +    public void testQuery() {
> > +        assertEquals(true, UriComponent.valid("fq=price:[1%20TO%20100]", UriComponent.Type.QUERY));
> > +    }
> >  }
> >
> > Please notice that I took this diff in a branch, so line numbers might
> > be wrong.
> >
> > Any thoughts on this?
> >
> > Thanx && cheers,
> > Martin
> >
> >


signature.asc (204 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UriComponent.validate does not allow brackets []?

Paul Sandoz
Administrator


Martin Grotzke wrote:
> Hi Paul,
>
> thanx for your feedback! Now I changed the URI for my test to use
> URLCodec and it works :)
>
>  "/products?q=foo&fq=price:" + new URLCodec().encode( "[10 TO 100]" );  
>

You can also use UriBuilder:

   UriBuilder.fromUri("/products").
     queryParam("q", "foo").
     queryParam("fq", "price:[10 TO 100]").
     build();

or

   UriBuilder.fromUri("/products").
     replaceQueryParams("q=foo&fq=price:[10 TO 100]").
     build();

Paul.

> Cheers,
> Martin
>
>
> On Tue, 2008-07-22 at 13:19 +0200, Paul Sandoz wrote:
>> Martin Grotzke wrote:
>>> Hi,
>>>
>>> we have a resource method that accepts some query parameter named fq
>>> (filter query). The fq param accepts ranges for e.g. a price filter, so
>>> that the value for the fq param might be "price:[160%20TO%20200]".
>>>
>> According to the URI ABNF:
>>
>>     sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
>>                 / "*" / "+" / "," / ";" / "="
>>
>>     unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
>>     pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
>>     query       = *( pchar / "/" / "?" )
>>
>> '[' and ']' characters are not valid characters of a URI query component.
>>
>>
>>> When a client performs a request with such a param value, the
>>> UriComponent.validate says that this is not valid:
>>>
>>> [ERROR] 17 Jul 2008 15:50:45,166 btpool0-1 com.sun.jersey.spi.spring.container.servlet.SpringServlet.service:
>>> Caught exception.
>>>
>>> java.lang.IllegalArgumentException: The string 'q=foo&fq=price:[160%20TO%20200]' for the URI component QUERY contains an invalid character, '[', at index 15
>>> at com.sun.jersey.api.uri.UriComponent.validate(UriComponent.java:95)
>>> at com.sun.jersey.impl.uri.UriBuilderImpl.encode(UriBuilderImpl.java:353)
>>> at com.sun.jersey.impl.uri.UriBuilderImpl.replaceQueryParams(UriBuilderImpl.java:286)
>>> at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:273)
>>>
>>> I think this should be valid, even UriComponent.decode handles this
>>> correctly.
>>>
>> The JavaDoc states:
>>
>> /**
>>   * Decodes characters of a string that are percent-encoded octets using
>>   * UTF-8 decoding (if needed).
>>   * <p>
>>   * It is assumed that the string is valid according to an (unspecified)
>> URI
>>   * component type. If a sequence of contiguous percent-encoded octets is
>>   * not a valid UTF-8 character then the octets are replaced with '\uFFFD'.
>>   * <p>
>>   * If the URI component is of type HOST then any "%" found between "[]" is
>>   * left alone. It is an IPv6 literal with a scope_id.
>>   * <p>
>>   * @param s the string to be decoded.
>>   * @param t the URI component type, may be null.
>>   * @return the decoded string.
>>   * @throws IllegalArgumentException if a malformed percent-encoded octet is
>>   *         detected
>>   */
>>
>> Paul.
>>
>>> One possible patch I can think of is in
>>> UriComponent.creatingEncodingTables:
>>>
>>> Index: src/api/com/sun/jersey/api/uri/UriComponent.java
>>> ===================================================================
>>> --- src/api/com/sun/jersey/api/uri/UriComponent.java    (revision 1166)
>>> +++ src/api/com/sun/jersey/api/uri/UriComponent.java    (working copy)
>>> @@ -243,6 +243,8 @@
>>>          tables[Type.PATH.ordinal()] = creatingEncodingTable(l);
>>>
>>>          l.add("?");
>>> +        l.add("[");
>>> +        l.add("]");
>>>
>>>          tables[Type.QUERY.ordinal()] = creatingEncodingTable(l);
>>>          tables[Type.FRAGMENT.ordinal()] = tables[Type.QUERY.ordinal()];
>>>
>>> This test goes through then:
>>>
>>> Index: test/com/sun/jersey/impl/UriComponentValidateTest.java
>>> ===================================================================
>>> --- test/com/sun/jersey/impl/UriComponentValidateTest.java      (revision 1166)
>>> +++ test/com/sun/jersey/impl/UriComponentValidateTest.java      (working copy)
>>> @@ -54,4 +54,8 @@
>>>          assertEquals(true, UriComponent.valid("/x20y", UriComponent.Type.PATH));
>>>          assertEquals(true, UriComponent.valid("/x%20y", UriComponent.Type.PATH));
>>>      }
>>> +
>>> +    public void testQuery() {
>>> +        assertEquals(true, UriComponent.valid("fq=price:[1%20TO%20100]", UriComponent.Type.QUERY));
>>> +    }
>>>  }
>>>
>>> Please notice that I took this diff in a branch, so line numbers might
>>> be wrong.
>>>
>>> Any thoughts on this?
>>>
>>> Thanx && cheers,
>>> Martin
>>>
>>>
>

--
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Loading...