") + "Hello
Hello <R&D>
') + >>> Markup("%sHello
")) + Markup('<R&D>Hello
') + >>> escape("Foo %
" % bar) # bad, bar is not escaped + >>> Markup("Foo %
") % bar # good, bar is escaped if text and kept if markup + + >>> link = Markup("%s") % self.name + >>> message = "Click %s" % link # bad, message is text and Markup did nothing + >>> message = escape("Click %s") % link # good, format two markup objects together + + >>> Markup(f"Foo {self.bar}
") # bad, bar is inserted before escaping + >>> Markup("Foo {bar}
").format(bar=self.bar) # good, sorry no fstring + Escaping vs Sanitizing ---------------------- @@ -380,10 +461,10 @@ variable contains *TEXT* and which contains *CODE*. # Escaping turns it into CODE, good! >>> code = html_escape(data) >>> code - '<R&D>' + Markup('<R&D>') # Now you can mix it with other code... - >>> self.message_post(body="%s" % code) + >>> self.website_description = Markup("%s") % code **Sanitizing** converts *CODE* to *SAFER CODE* (but not necessary *safe* code). It does not work on *TEXT*. Sanitizing is only necessary when *CODE* is @@ -398,11 +479,11 @@ expected. # Sanitizing without escaping is BROKEN: data is corrupted! >>> html_sanitize(data) - '' + Markup('') # Sanitizing *after* escaping is OK! >>> html_sanitize(code) - '<R&D>
' + Markup('<R&D>
') Sanitizing can break features, depending on whether the *CODE* is expected to contain patterns that are not safe. That's why `fields.Html` and @@ -414,11 +495,11 @@ likely it is to break things. .. code-block:: python - >>code = "Important Information
" + >>> code = "Important Information
" # this will remove the style, which may break features # but is necessary if the source is untrusted - >> html_sanitize(code, strip_classes=True) - 'Important Information
' + >>> html_sanitize(code, strip_classes=True) + Markup('Important Information
') Evaluating content ------------------ diff --git a/content/developer/reference/frontend/qweb.rst b/content/developer/reference/frontend/qweb.rst index 96d6fec16..6b5b56572 100644 --- a/content/developer/reference/frontend/qweb.rst +++ b/content/developer/reference/frontend/qweb.rst @@ -372,58 +372,6 @@ templates: * :func:`~odoo.tools.pycompat.to_text` does not mark the content as safe, but will not strip that information from safe content. -Creating safe content using :class:`~markupsafe.Markup` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -See the official documentation for explanations, but the big advantage of -:class:`~markupsafe.Markup` is that it's a very rich type overrinding -:class:`str` operations to *automatically escape parameters*. - -This means that it's easy to create *safe* html snippets by using -:class:`~markupsafe.Markup` on a string literal and "formatting in" -user-provided (and thus potentially unsafe) content: - -.. code-block:: pycon - - >>> Markup('Hello ') + '