Mercurial > kallithea
diff kallithea/lib/webutils.py @ 8781:642fa51e0d0b
lib: move js escaping from helpers to webutils
It was no real problem it lived in helpers: it was only used from templates
anyway.
But for completeness and correctness, move all web utils to webutils.
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Sat, 07 Nov 2020 18:27:33 +0100 |
parents | f8971422795e |
children | f375751fe3fa |
line wrap: on
line diff
--- a/kallithea/lib/webutils.py Fri Nov 06 21:15:20 2020 +0100 +++ b/kallithea/lib/webutils.py Sat Nov 07 18:27:33 2020 +0100 @@ -20,6 +20,7 @@ imported anywhere - just like the global variables can be used everywhere. """ +import json import logging import random @@ -256,3 +257,52 @@ The return value is a list of ``Message`` objects. """ return [_Message(category, message) for category, message in _session_flash_messages(clear=True)] + + +# +# Generic-ish formatting and markup +# + +def js(value): + """Convert Python value to the corresponding JavaScript representation. + + This is necessary to safely insert arbitrary values into HTML <script> + sections e.g. using Mako template expression substitution. + + Note: Rather than using this function, it's preferable to avoid the + insertion of values into HTML <script> sections altogether. Instead, + data should (to the extent possible) be passed to JavaScript using + data attributes or AJAX calls, eliminating the need for JS specific + escaping. + + Note: This is not safe for use in attributes (e.g. onclick), because + quotes are not escaped. + + Because the rules for parsing <script> varies between XHTML (where + normal rules apply for any special characters) and HTML (where + entities are not interpreted, but the literal string "</script>" + is forbidden), the function ensures that the result never contains + '&', '<' and '>', thus making it safe in both those contexts (but + not in attributes). + """ + return literal( + ('(' + json.dumps(value) + ')') + # In JSON, the following can only appear in string literals. + .replace('&', r'\x26') + .replace('<', r'\x3c') + .replace('>', r'\x3e') + ) + + +def jshtml(val): + """HTML escapes a string value, then converts the resulting string + to its corresponding JavaScript representation (see `js`). + + This is used when a plain-text string (possibly containing special + HTML characters) will be used by a script in an HTML context (e.g. + element.innerHTML or jQuery's 'html' method). + + If in doubt, err on the side of using `jshtml` over `js`, since it's + better to escape too much than too little. + """ + return js(escape(val))