# HG changeset patch # User Pierre-Yves David # Date 1318933532 -7200 # Node ID 9ef285eb20f478e5bfae519340201d0395803a15 # Parent e6eb86233e6f2c7f7033211552d82e4b93e7116c [utils] add a ``js_href`` function to generated proper javascript href The main gain is the escaping of % * * * [pagination] use js_href for building javascript link (closes #2035033) This prevent snicky error with url unquoting of javascript code diff -r e6eb86233e6f -r 9ef285eb20f4 utils.py --- a/utils.py Fri Oct 21 14:32:37 2011 +0200 +++ b/utils.py Tue Oct 18 12:25:32 2011 +0200 @@ -25,6 +25,8 @@ import decimal import datetime import random +import re + from operator import itemgetter from inspect import getargspec from itertools import repeat @@ -540,6 +542,29 @@ return something return json_dumps(something) +PERCENT_IN_URLQUOTE_RE = re.compile(r'%(?=[0-9a-fA-F]{2})') +def js_href(javascript_code): + """Generate a "javascript: ..." string for an href attribute. + + Some % which may be interpreted in a href context will be escaped. + + In an href attribute, url-quotes-looking fragments are interpreted before + being given to the javascript engine. Valid url quotes are in the form + ``%xx`` with xx being a byte in hexadecimal form. This means that ``%toto`` + will be unaltered but ``%babar`` will be mangled because ``ba`` is the + hexadecimal representation of 186. + + >>> js_href('alert("babar");') + 'javascript: alert("babar");' + >>> js_href('alert("%babar");') + 'javascript: alert("%25babar");' + >>> js_href('alert("%toto %babar");') + 'javascript: alert("%toto %25babar");' + >>> js_href('alert("%1337%");') + 'javascript: alert("%251337%");' + """ + return 'javascript: ' + PERCENT_IN_URLQUOTE_RE.sub(r'%25', javascript_code) + @deprecated('[3.7] merge_dicts is deprecated') def merge_dicts(dict1, dict2): diff -r e6eb86233e6f -r 9ef285eb20f4 web/component.py --- a/web/component.py Fri Oct 21 14:32:37 2011 +0200 +++ b/web/component.py Tue Oct 18 12:25:32 2011 +0200 @@ -30,7 +30,7 @@ from cubicweb import Unauthorized, role, target, tags from cubicweb.schema import display_name from cubicweb.uilib import js, domid -from cubicweb.utils import json_dumps +from cubicweb.utils import json_dumps, js_href from cubicweb.view import ReloadableMixIn, Component from cubicweb.selectors import (no_cnx, paginated_rset, one_line_rset, non_final_entity, partial_relation_possible, @@ -120,8 +120,8 @@ def ajax_page_url(self, **params): divid = params.setdefault('divid', 'pageContent') params['rql'] = self.cw_rset.printable_rql() - return "javascript: $(%s).loadxhtml('json', %s, 'get', 'swap')" % ( - json_dumps('#'+divid), js.ajaxFuncArgs('view', params)) + return js_href("$(%s).loadxhtml('json', %s, 'get', 'swap')" % ( + json_dumps('#'+divid), js.ajaxFuncArgs('view', params))) def page_link(self, path, params, start, stop, content): url = xml_escape(self.page_url(path, params, start, stop))