[Catalyst] Escaping of "argument" of private path

Octavian Rasnita orasnita at gmail.com
Tue Mar 15 09:56:51 GMT 2011


From: "John M. Dlugosz" <wxju46gefd at snkmail.com>

> On 3/15/2011 1:38 AM, Octavian Rasnita orasnita-at-gmail.com 
> |Catalyst/Allow to home| wrote:
>> uri_for() escapes each component, but I guess that it doesn't escape it 
>> if it contains a slash in it.
>>
>> For example, you can do:
>>
>> <img src="[% c.uri_for('/static', 'ham and eggs.jpg').path %]">
>>
>> It will print:
>>
>> <img src="/static/ham%20and%20eggs.jpg">
>>
>> Octavian
>>
>
> I see... it wants you to pass separate arguments rather than building the 
> path first.


It just gets the path and the list of arguments, but it escapes the special 
characters only in the arguments, not the path.


> I was thinking that uri_for might be more trouble than it's worth since I 
> don't like fully-qualified URLs in my generated source anyway.  But if it 
> escapes (sometimes?) then that is indeed more helpful.

You don't need to use fully-qualified URLS if you don't like, even though it 
doesn't matter because they are dynamicly generated anyway.
uri_for() returns a URI object, so you can use:

c.uri_for(...).path

This will return only the path, without the scheme, host and port.

or:

c.uri_for(...).path_query

...if the URL also contains a query string (?a=b&c=d)


> <img src="[% c.uri_for("/static/gallery",rec.dirname,rec.filename) %]" 
> alt="photo" />
>
> That works (using Smart_URI settings to leave off the host).  But it did 
> not escape out the '&' in the filename!  Is that a bug?  I notice you 
> changes my example from '&' to 'and' -- that's cheating!

:-)

> <img src="[% "/static/gallery/${rec.dirname}/${ rec.filename | uri }" %]" 
> alt="photo" />
>
> gives the correct answer: ham%20%26%20eggs.jpeg
>

uri_for() escapes only the chars which are not in the following list (from 
URI.pm):

$reserved   = q(;/?:@&=+$,[]);
$mark       = q(-_.!~*'());                                    #'; emacs
$unreserved = "A-Za-z0-9\Q$mark\E";

The char "&" is a valid char in the URI, so it should not be escaped.. With 
other words, the following url is OK:

http://localhost/dir1/dir2/ham%20&%20eggs.jpg

uri_for() generates the URI as it needs to be accessed on the server and not 
as it should be printed in an HTML page. In order to be printed correctly, 
the "&" char must be HTML-encoded, so the html TT filter must be used:

<a href="[% c.uri_for('/path', 'eggs & ham.jpg', {a=1, b=2}).path_query | 
html%]">label</a>

It will give:

<a href="/path/eggs%20&amp;%20ham.jpg?a=1&amp;b=2">label</a>

Octavian





More information about the Catalyst mailing list