changeset 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 eed44652346d
children b7eaad593cb9
files kallithea/lib/helpers.py kallithea/lib/webutils.py
diffstat 2 files changed, 56 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/helpers.py	Fri Nov 06 21:15:20 2020 +0100
+++ b/kallithea/lib/helpers.py	Sat Nov 07 18:27:33 2020 +0100
@@ -18,7 +18,6 @@
 available to Controllers. This module is available to both as 'h'.
 """
 import hashlib
-import json
 import logging
 import re
 import textwrap
@@ -47,15 +46,16 @@
 # SCM FILTERS available via h.
 #==============================================================================
 from kallithea.lib.vcs.utils import author_email, author_name
-from kallithea.lib.webutils import (HTML, Option, canonical_url, checkbox, chop_at, end_form, escape, form, format_byte_size, hidden, html_escape, link_to,
-                                    literal, password, pop_flash_messages, radio, reset, safeid, select, session_csrf_secret_name, session_csrf_secret_token,
-                                    submit, text, textarea, truncate, url, wrap_paragraphs)
+from kallithea.lib.webutils import (HTML, Option, canonical_url, checkbox, chop_at, end_form, escape, form, format_byte_size, hidden, html_escape, js, jshtml,
+                                    link_to, literal, password, pop_flash_messages, radio, reset, safeid, select, session_csrf_secret_name,
+                                    session_csrf_secret_token, submit, text, textarea, truncate, url, wrap_paragraphs)
 from kallithea.model import db
 from kallithea.model.changeset_status import ChangesetStatusModel
 
 
 # mute pyflakes "imported but unused"
 # from webutils
+assert HTML
 assert Option
 assert canonical_url
 assert checkbox
@@ -64,6 +64,8 @@
 assert form
 assert format_byte_size
 assert hidden
+assert js
+assert jshtml
 assert password
 assert pop_flash_messages
 assert radio
@@ -93,51 +95,6 @@
 log = logging.getLogger(__name__)
 
 
-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))
-
-
 def FID(raw_id, path):
     """
     Creates a unique ID for filenode based on it's hash of path and revision
--- 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))