#9396 closed defect (fixed)
[PATCH] Data that are passed to `add_script_data` are escaped by Genshi
Reported by: | Jun Omae | Owned by: | Jun Omae |
---|---|---|---|
Priority: | normal | Milestone: | 0.12 |
Component: | rendering | Version: | 0.12dev |
Severity: | normal | Keywords: | javascript |
Cc: | Branch: | ||
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Description
The Data that are passed to add_script_data
are escaped by Genshi.
Code;
add_script_data(req, {'test': '&<>"\''})
Result in html;
<script type="text/javascript"> var test="&<>\"'"; </script>
The two values are not the same.
I think that to_json()
should encode &
, <
and >
to \u0026
, \u003c
and \u003e
. And these characters are not escaped by Genshi. javascript_quote()
has the same issue.
Attachments (4)
Change History (19)
by , 14 years ago
Attachment: | javascript-genshi.diff added |
---|
comment:1 by , 14 years ago
by , 14 years ago
Attachment: | test-var.png added |
---|
comment:2 by , 14 years ago
comment:3 by , 14 years ago
Owner: | set to |
---|
Ok, I thought I had tested this, but obviously I didn't quite succeed :) Could it be browser-specific? Anyway, I'll look into it.
comment:4 by , 14 years ago
I think it isn't browser-specific. I tried in some browsers, the same happens in IE7, Firefox 3.6, Google Chrome 5, Safari 4 and Opera 10.
by , 14 years ago
Attachment: | 9396-js-escape-r9816.patch added |
---|
Fixed an issue with query field labels, refactored.
follow-up: 6 comment:5 by , 14 years ago
The patch above is slightly refactored and fixes an issue with query field labels:
- Moved escaping out of
$.template()
, as that function is generic and can be used for other purposes than generating HTML to be passed to$()
. - Escaped the text passed to
createLabel()
. - Simplified a few expressions.
All tests pass (including the new ones), and working with ticket fields whose names and values contain "≠&" characters seems to work well in the custom query.
Would you mind testing the updated patch? Thanks.
comment:6 by , 14 years ago
Replying to rblank:
The patch above is slightly refactored and fixes an issue with query field labels:
- Moved escaping out of
$.template()
, as that function is generic and can be used for other purposes than generating HTML to be passed to$()
.
… but is it really used for something else? I added it for that purpose only and don't expect that we would create HTML piecewise (i.e. pass HTML fragments as template parameters). If the name sounds too generic, we can use htmltemplate
instead. Having to add explicitly htmlEscape
to all parameters like you do in the patch doesn't feel optimal.
follow-up: 8 comment:7 by , 14 years ago
The name is misleading, then. Also, that's what made me notice the missing escaping in createLabel()
. But yeah, it's more typing, and prone to being forgotten.
About not creating HTML piecewise, we do it in Python (although mainly for translations), so I'd expect that to be useful in JavaScript as well at some point. Speaking of that, shouldn't babel.translate()
also escape its arguments? My feeling is yes, except when we do want to insert HTML fragments. Maybe we should escape %s
arguments, and have a separate %h
format string for non-escaped HTML fragments?
Having said that, we could just have both $.template()
and $.htmltemplate()
(or just $.html()
, even shorter), and use the latter instead of string concatenation in createLabel()
. And maybe even rename $.template()
to $.format()
for consistency.
I'll update the patch shortly.
comment:8 by , 14 years ago
Replying to rblank:
Having said that, we could just have both
$.template()
Yes, better keep it anyway unchanged, for backwards compatibility.
and
$.htmltemplate()
(or just$.html()
, even shorter)
$.html()
would be too easily confused with $().html.
even rename
$.template()
to$.format()
for consistency.
Yes, why not, $.format
and $.htmlformat
, with template
kept as a backward compatibility alias for format
.
comment:10 by , 14 years ago
I'm not that fluent in Javascript, but I wonder if we couldn't find a similar approach to the Genshi Markup
trick (special "subclass" of String that wouldn't be escaped). That way, we don't need to do anything special in the common case, but we would still have a possibility to pass markup when we really need it. Failing to do that, "%h" would be my fine as well.
by , 14 years ago
Attachment: | 9396-js-escape-r9821.patch added |
---|
Introduce separate $.format()
and $.htmlformat()
.
comment:11 by , 14 years ago
The patch above has been updated according to comment:8.
About babel.format()
, on second thought I don't think we should do any automatic escaping there, as its result is sometimes used as an argument to $.htmlformat()
, where it would be escaped a second time. So I'd rather leave it as-is, and add explicit escaping if necessary.
Ok to apply?
follow-up: 13 comment:12 by , 14 years ago
Two last nit picks: I've seen that every other methods we already have are capitalized, so we should use htmlFormat
to be consistent.
And we could avoid creating an identify function each time:
-
trac/htdocs/js/trac.js
diff --git a/trac/htdocs/js/trac.js b/trac/htdocs/js/trac.js
a b 83 83 function format(str, args, escape) { 84 84 var kwargs = args[args.length - 1]; 85 85 return str.replace(/\${?(\w+)}?/g, function(_, k) { 86 var repl; 86 87 if (k.length == 1 && k >= '0' && k <= '9') 87 re turn escape(args[k - '0']);88 repl = args[k - '0']; 88 89 else 89 return escape(kwargs[k]); 90 repl = kwargs[k]; 91 return escape ? escape(repl) : repl; 90 92 }); 91 93 } 92 94 93 95 // Expand positional ($1 .. $9) and keyword ($name) arguments in a string. 94 96 // The htmlformat() version HTML-escapes arguments prior to substitution. 95 97 $.format = function(str) { 96 return format(str, arguments , function(s) { return s; });98 return format(str, arguments); 97 99 } 98 100 99 101 $.htmlformat = function(str) {
follow-up: 15 comment:13 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:14 by , 14 years ago
Owner: | changed from | to
---|
Yes, they are escaped by Genshi, but the resulting string in JavaScript is still correct IIRC, as they are expanded by the browser when parsing the page (they are not in a CDATA section).
Do you actually have a use case for
add_script_data()
where a string is not passed correctly (i.e. intact) to JavaScript?