diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:24:06 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:41:34 +0300 |
commit | e0e3e1717e3d33762ce61950504f9637a6e669ed (patch) | |
tree | bca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/MarkupSafe/py2 | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/python/MarkupSafe/py2')
-rw-r--r-- | contrib/python/MarkupSafe/py2/.dist-info/METADATA | 103 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/.dist-info/top_level.txt | 1 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/LICENSE.rst | 28 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/README.rst | 69 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/markupsafe/__init__.py | 327 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/markupsafe/_compat.py | 33 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/markupsafe/_constants.py | 264 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/markupsafe/_native.py | 69 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/conftest.py | 37 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/test_escape.py | 30 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py | 21 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/test_leak.py | 29 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/test_markupsafe.py | 196 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/tests/ya.make | 17 | ||||
-rw-r--r-- | contrib/python/MarkupSafe/py2/ya.make | 37 |
15 files changed, 1261 insertions, 0 deletions
diff --git a/contrib/python/MarkupSafe/py2/.dist-info/METADATA b/contrib/python/MarkupSafe/py2/.dist-info/METADATA new file mode 100644 index 0000000000..b6d72a81d2 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 1.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: The Pallets Team +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Code, https://github.com/pallets/markupsafe +Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + >>> # escape replaces special characters and wraps in Markup + >>> escape('<script>alert(document.cookie);</script>') + Markup(u'<script>alert(document.cookie);</script>') + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup('<strong>Hello</strong>') + Markup('<strong>hello</strong>') + >>> escape(Markup('<strong>Hello</strong>')) + Markup('<strong>hello</strong>') + >>> # Markup is a text subclass (str on Python 3, unicode on Python 2) + >>> # methods and operators escape their arguments + >>> template = Markup("Hello <em>%s</em>") + >>> template % '"World"' + Markup('Hello <em>"World"</em>') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +libraries that use it. In order to grow the community of contributors +and users, and allow the maintainers to devote more time to the +projects, `please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/markupsafe/ +* Documentation: https://markupsafe.palletsprojects.com/ +* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_ +* Releases: https://pypi.org/project/MarkupSafe/ +* Code: https://github.com/pallets/markupsafe +* Issue tracker: https://github.com/pallets/markupsafe/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/markupsafe + * Windows: https://ci.appveyor.com/project/pallets/markupsafe + +* Test coverage: https://codecov.io/gh/pallets/markupsafe + + diff --git a/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt new file mode 100644 index 0000000000..75bf729258 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/contrib/python/MarkupSafe/py2/LICENSE.rst b/contrib/python/MarkupSafe/py2/LICENSE.rst new file mode 100644 index 0000000000..9d227a0cc4 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/contrib/python/MarkupSafe/py2/README.rst b/contrib/python/MarkupSafe/py2/README.rst new file mode 100644 index 0000000000..3548b8d1f7 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/README.rst @@ -0,0 +1,69 @@ +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + >>> # escape replaces special characters and wraps in Markup + >>> escape('<script>alert(document.cookie);</script>') + Markup(u'<script>alert(document.cookie);</script>') + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup('<strong>Hello</strong>') + Markup('<strong>hello</strong>') + >>> escape(Markup('<strong>Hello</strong>')) + Markup('<strong>hello</strong>') + >>> # Markup is a text subclass (str on Python 3, unicode on Python 2) + >>> # methods and operators escape their arguments + >>> template = Markup("Hello <em>%s</em>") + >>> template % '"World"' + Markup('Hello <em>"World"</em>') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +libraries that use it. In order to grow the community of contributors +and users, and allow the maintainers to devote more time to the +projects, `please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +* Website: https://palletsprojects.com/p/markupsafe/ +* Documentation: https://markupsafe.palletsprojects.com/ +* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_ +* Releases: https://pypi.org/project/MarkupSafe/ +* Code: https://github.com/pallets/markupsafe +* Issue tracker: https://github.com/pallets/markupsafe/issues +* Test status: + + * Linux, Mac: https://travis-ci.org/pallets/markupsafe + * Windows: https://ci.appveyor.com/project/pallets/markupsafe + +* Test coverage: https://codecov.io/gh/pallets/markupsafe diff --git a/contrib/python/MarkupSafe/py2/markupsafe/__init__.py b/contrib/python/MarkupSafe/py2/markupsafe/__init__.py new file mode 100644 index 0000000000..da05ed328a --- /dev/null +++ b/contrib/python/MarkupSafe/py2/markupsafe/__init__.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +""" +markupsafe +~~~~~~~~~~ + +Implements an escape function and a Markup string to replace HTML +special characters with safe representations. + +:copyright: 2010 Pallets +:license: BSD-3-Clause +""" +import re +import string + +from ._compat import int_types +from ._compat import iteritems +from ._compat import Mapping +from ._compat import PY2 +from ._compat import string_types +from ._compat import text_type +from ._compat import unichr + +__version__ = "1.1.1" + +__all__ = ["Markup", "soft_unicode", "escape", "escape_silent"] + +_striptags_re = re.compile(r"(<!--.*?-->|<[^>]*>)") +_entity_re = re.compile(r"&([^& ;]+);") + + +class Markup(text_type): + """A string that is ready to be safely inserted into an HTML or XML + document, either because it was escaped or because it was marked + safe. + + Passing an object to the constructor converts it to text and wraps + it to mark it safe without escaping. To escape the text, use the + :meth:`escape` class method instead. + + >>> Markup('Hello, <em>World</em>!') + Markup('Hello, <em>World</em>!') + >>> Markup(42) + Markup('42') + >>> Markup.escape('Hello, <em>World</em>!') + Markup('Hello <em>World</em>!') + + This implements the ``__html__()`` interface that some frameworks + use. Passing an object that implements ``__html__()`` will wrap the + output of that method, marking it safe. + + >>> class Foo: + ... def __html__(self): + ... return '<a href="/foo">foo</a>' + ... + >>> Markup(Foo()) + Markup('<a href="/foo">foo</a>') + + This is a subclass of the text type (``str`` in Python 3, + ``unicode`` in Python 2). It has the same methods as that type, but + all methods escape their arguments and return a ``Markup`` instance. + + >>> Markup('<em>%s</em>') % 'foo & bar' + Markup('<em>foo & bar</em>') + >>> Markup('<em>Hello</em> ') + '<foo>' + Markup('<em>Hello</em> <foo>') + """ + + __slots__ = () + + def __new__(cls, base=u"", encoding=None, errors="strict"): + if hasattr(base, "__html__"): + base = base.__html__() + if encoding is None: + return text_type.__new__(cls, base) + return text_type.__new__(cls, base, encoding, errors) + + def __html__(self): + return self + + def __add__(self, other): + if isinstance(other, string_types) or hasattr(other, "__html__"): + return self.__class__(super(Markup, self).__add__(self.escape(other))) + return NotImplemented + + def __radd__(self, other): + if hasattr(other, "__html__") or isinstance(other, string_types): + return self.escape(other).__add__(self) + return NotImplemented + + def __mul__(self, num): + if isinstance(num, int_types): + return self.__class__(text_type.__mul__(self, num)) + return NotImplemented + + __rmul__ = __mul__ + + def __mod__(self, arg): + if isinstance(arg, tuple): + arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg) + else: + arg = _MarkupEscapeHelper(arg, self.escape) + return self.__class__(text_type.__mod__(self, arg)) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, text_type.__repr__(self)) + + def join(self, seq): + return self.__class__(text_type.join(self, map(self.escape, seq))) + + join.__doc__ = text_type.join.__doc__ + + def split(self, *args, **kwargs): + return list(map(self.__class__, text_type.split(self, *args, **kwargs))) + + split.__doc__ = text_type.split.__doc__ + + def rsplit(self, *args, **kwargs): + return list(map(self.__class__, text_type.rsplit(self, *args, **kwargs))) + + rsplit.__doc__ = text_type.rsplit.__doc__ + + def splitlines(self, *args, **kwargs): + return list(map(self.__class__, text_type.splitlines(self, *args, **kwargs))) + + splitlines.__doc__ = text_type.splitlines.__doc__ + + def unescape(self): + """Convert escaped markup back into a text string. This replaces + HTML entities with the characters they represent. + + >>> Markup('Main » <em>About</em>').unescape() + 'Main » <em>About</em>' + """ + from ._constants import HTML_ENTITIES + + def handle_match(m): + name = m.group(1) + if name in HTML_ENTITIES: + return unichr(HTML_ENTITIES[name]) + try: + if name[:2] in ("#x", "#X"): + return unichr(int(name[2:], 16)) + elif name.startswith("#"): + return unichr(int(name[1:])) + except ValueError: + pass + # Don't modify unexpected input. + return m.group() + + return _entity_re.sub(handle_match, text_type(self)) + + def striptags(self): + """:meth:`unescape` the markup, remove tags, and normalize + whitespace to single spaces. + + >>> Markup('Main »\t<em>About</em>').striptags() + 'Main » About' + """ + stripped = u" ".join(_striptags_re.sub("", self).split()) + return Markup(stripped).unescape() + + @classmethod + def escape(cls, s): + """Escape a string. Calls :func:`escape` and ensures that for + subclasses the correct type is returned. + """ + rv = escape(s) + if rv.__class__ is not cls: + return cls(rv) + return rv + + def make_simple_escaping_wrapper(name): # noqa: B902 + orig = getattr(text_type, name) + + def func(self, *args, **kwargs): + args = _escape_argspec(list(args), enumerate(args), self.escape) + _escape_argspec(kwargs, iteritems(kwargs), self.escape) + return self.__class__(orig(self, *args, **kwargs)) + + func.__name__ = orig.__name__ + func.__doc__ = orig.__doc__ + return func + + for method in ( + "__getitem__", + "capitalize", + "title", + "lower", + "upper", + "replace", + "ljust", + "rjust", + "lstrip", + "rstrip", + "center", + "strip", + "translate", + "expandtabs", + "swapcase", + "zfill", + ): + locals()[method] = make_simple_escaping_wrapper(method) + + def partition(self, sep): + return tuple(map(self.__class__, text_type.partition(self, self.escape(sep)))) + + def rpartition(self, sep): + return tuple(map(self.__class__, text_type.rpartition(self, self.escape(sep)))) + + def format(self, *args, **kwargs): + formatter = EscapeFormatter(self.escape) + kwargs = _MagicFormatMapping(args, kwargs) + return self.__class__(formatter.vformat(self, args, kwargs)) + + def __html_format__(self, format_spec): + if format_spec: + raise ValueError("Unsupported format specification " "for Markup.") + return self + + # not in python 3 + if hasattr(text_type, "__getslice__"): + __getslice__ = make_simple_escaping_wrapper("__getslice__") + + del method, make_simple_escaping_wrapper + + +class _MagicFormatMapping(Mapping): + """This class implements a dummy wrapper to fix a bug in the Python + standard library for string formatting. + + See http://bugs.python.org/issue13598 for information about why + this is necessary. + """ + + def __init__(self, args, kwargs): + self._args = args + self._kwargs = kwargs + self._last_index = 0 + + def __getitem__(self, key): + if key == "": + idx = self._last_index + self._last_index += 1 + try: + return self._args[idx] + except LookupError: + pass + key = str(idx) + return self._kwargs[key] + + def __iter__(self): + return iter(self._kwargs) + + def __len__(self): + return len(self._kwargs) + + +if hasattr(text_type, "format"): + + class EscapeFormatter(string.Formatter): + def __init__(self, escape): + self.escape = escape + + def format_field(self, value, format_spec): + if hasattr(value, "__html_format__"): + rv = value.__html_format__(format_spec) + elif hasattr(value, "__html__"): + if format_spec: + raise ValueError( + "Format specifier {0} given, but {1} does not" + " define __html_format__. A class that defines" + " __html__ must define __html_format__ to work" + " with format specifiers.".format(format_spec, type(value)) + ) + rv = value.__html__() + else: + # We need to make sure the format spec is unicode here as + # otherwise the wrong callback methods are invoked. For + # instance a byte string there would invoke __str__ and + # not __unicode__. + rv = string.Formatter.format_field(self, value, text_type(format_spec)) + return text_type(self.escape(rv)) + + +def _escape_argspec(obj, iterable, escape): + """Helper for various string-wrapped functions.""" + for key, value in iterable: + if hasattr(value, "__html__") or isinstance(value, string_types): + obj[key] = escape(value) + return obj + + +class _MarkupEscapeHelper(object): + """Helper for Markup.__mod__""" + + def __init__(self, obj, escape): + self.obj = obj + self.escape = escape + + def __getitem__(self, item): + return _MarkupEscapeHelper(self.obj[item], self.escape) + + def __str__(self): + return text_type(self.escape(self.obj)) + + __unicode__ = __str__ + + def __repr__(self): + return str(self.escape(repr(self.obj))) + + def __int__(self): + return int(self.obj) + + def __float__(self): + return float(self.obj) + + +# we have to import it down here as the speedups and native +# modules imports the markup type which is define above. +try: + from ._speedups import escape, escape_silent, soft_unicode +except ImportError: + from ._native import escape, escape_silent, soft_unicode + +if not PY2: + soft_str = soft_unicode + __all__.append("soft_str") diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_compat.py b/contrib/python/MarkupSafe/py2/markupsafe/_compat.py new file mode 100644 index 0000000000..bc05090f9e --- /dev/null +++ b/contrib/python/MarkupSafe/py2/markupsafe/_compat.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" +markupsafe._compat +~~~~~~~~~~~~~~~~~~ + +:copyright: 2010 Pallets +:license: BSD-3-Clause +""" +import sys + +PY2 = sys.version_info[0] == 2 + +if not PY2: + text_type = str + string_types = (str,) + unichr = chr + int_types = (int,) + + def iteritems(x): + return iter(x.items()) + + from collections.abc import Mapping + +else: + text_type = unicode + string_types = (str, unicode) + unichr = unichr + int_types = (int, long) + + def iteritems(x): + return x.iteritems() + + from collections import Mapping diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_constants.py b/contrib/python/MarkupSafe/py2/markupsafe/_constants.py new file mode 100644 index 0000000000..7c57c2d294 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/markupsafe/_constants.py @@ -0,0 +1,264 @@ +# -*- coding: utf-8 -*- +""" +markupsafe._constants +~~~~~~~~~~~~~~~~~~~~~ + +:copyright: 2010 Pallets +:license: BSD-3-Clause +""" + +HTML_ENTITIES = { + "AElig": 198, + "Aacute": 193, + "Acirc": 194, + "Agrave": 192, + "Alpha": 913, + "Aring": 197, + "Atilde": 195, + "Auml": 196, + "Beta": 914, + "Ccedil": 199, + "Chi": 935, + "Dagger": 8225, + "Delta": 916, + "ETH": 208, + "Eacute": 201, + "Ecirc": 202, + "Egrave": 200, + "Epsilon": 917, + "Eta": 919, + "Euml": 203, + "Gamma": 915, + "Iacute": 205, + "Icirc": 206, + "Igrave": 204, + "Iota": 921, + "Iuml": 207, + "Kappa": 922, + "Lambda": 923, + "Mu": 924, + "Ntilde": 209, + "Nu": 925, + "OElig": 338, + "Oacute": 211, + "Ocirc": 212, + "Ograve": 210, + "Omega": 937, + "Omicron": 927, + "Oslash": 216, + "Otilde": 213, + "Ouml": 214, + "Phi": 934, + "Pi": 928, + "Prime": 8243, + "Psi": 936, + "Rho": 929, + "Scaron": 352, + "Sigma": 931, + "THORN": 222, + "Tau": 932, + "Theta": 920, + "Uacute": 218, + "Ucirc": 219, + "Ugrave": 217, + "Upsilon": 933, + "Uuml": 220, + "Xi": 926, + "Yacute": 221, + "Yuml": 376, + "Zeta": 918, + "aacute": 225, + "acirc": 226, + "acute": 180, + "aelig": 230, + "agrave": 224, + "alefsym": 8501, + "alpha": 945, + "amp": 38, + "and": 8743, + "ang": 8736, + "apos": 39, + "aring": 229, + "asymp": 8776, + "atilde": 227, + "auml": 228, + "bdquo": 8222, + "beta": 946, + "brvbar": 166, + "bull": 8226, + "cap": 8745, + "ccedil": 231, + "cedil": 184, + "cent": 162, + "chi": 967, + "circ": 710, + "clubs": 9827, + "cong": 8773, + "copy": 169, + "crarr": 8629, + "cup": 8746, + "curren": 164, + "dArr": 8659, + "dagger": 8224, + "darr": 8595, + "deg": 176, + "delta": 948, + "diams": 9830, + "divide": 247, + "eacute": 233, + "ecirc": 234, + "egrave": 232, + "empty": 8709, + "emsp": 8195, + "ensp": 8194, + "epsilon": 949, + "equiv": 8801, + "eta": 951, + "eth": 240, + "euml": 235, + "euro": 8364, + "exist": 8707, + "fnof": 402, + "forall": 8704, + "frac12": 189, + "frac14": 188, + "frac34": 190, + "frasl": 8260, + "gamma": 947, + "ge": 8805, + "gt": 62, + "hArr": 8660, + "harr": 8596, + "hearts": 9829, + "hellip": 8230, + "iacute": 237, + "icirc": 238, + "iexcl": 161, + "igrave": 236, + "image": 8465, + "infin": 8734, + "int": 8747, + "iota": 953, + "iquest": 191, + "isin": 8712, + "iuml": 239, + "kappa": 954, + "lArr": 8656, + "lambda": 955, + "lang": 9001, + "laquo": 171, + "larr": 8592, + "lceil": 8968, + "ldquo": 8220, + "le": 8804, + "lfloor": 8970, + "lowast": 8727, + "loz": 9674, + "lrm": 8206, + "lsaquo": 8249, + "lsquo": 8216, + "lt": 60, + "macr": 175, + "mdash": 8212, + "micro": 181, + "middot": 183, + "minus": 8722, + "mu": 956, + "nabla": 8711, + "nbsp": 160, + "ndash": 8211, + "ne": 8800, + "ni": 8715, + "not": 172, + "notin": 8713, + "nsub": 8836, + "ntilde": 241, + "nu": 957, + "oacute": 243, + "ocirc": 244, + "oelig": 339, + "ograve": 242, + "oline": 8254, + "omega": 969, + "omicron": 959, + "oplus": 8853, + "or": 8744, + "ordf": 170, + "ordm": 186, + "oslash": 248, + "otilde": 245, + "otimes": 8855, + "ouml": 246, + "para": 182, + "part": 8706, + "permil": 8240, + "perp": 8869, + "phi": 966, + "pi": 960, + "piv": 982, + "plusmn": 177, + "pound": 163, + "prime": 8242, + "prod": 8719, + "prop": 8733, + "psi": 968, + "quot": 34, + "rArr": 8658, + "radic": 8730, + "rang": 9002, + "raquo": 187, + "rarr": 8594, + "rceil": 8969, + "rdquo": 8221, + "real": 8476, + "reg": 174, + "rfloor": 8971, + "rho": 961, + "rlm": 8207, + "rsaquo": 8250, + "rsquo": 8217, + "sbquo": 8218, + "scaron": 353, + "sdot": 8901, + "sect": 167, + "shy": 173, + "sigma": 963, + "sigmaf": 962, + "sim": 8764, + "spades": 9824, + "sub": 8834, + "sube": 8838, + "sum": 8721, + "sup": 8835, + "sup1": 185, + "sup2": 178, + "sup3": 179, + "supe": 8839, + "szlig": 223, + "tau": 964, + "there4": 8756, + "theta": 952, + "thetasym": 977, + "thinsp": 8201, + "thorn": 254, + "tilde": 732, + "times": 215, + "trade": 8482, + "uArr": 8657, + "uacute": 250, + "uarr": 8593, + "ucirc": 251, + "ugrave": 249, + "uml": 168, + "upsih": 978, + "upsilon": 965, + "uuml": 252, + "weierp": 8472, + "xi": 958, + "yacute": 253, + "yen": 165, + "yuml": 255, + "zeta": 950, + "zwj": 8205, + "zwnj": 8204, +} diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_native.py b/contrib/python/MarkupSafe/py2/markupsafe/_native.py new file mode 100644 index 0000000000..cd08752cd8 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/markupsafe/_native.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +""" +markupsafe._native +~~~~~~~~~~~~~~~~~~ + +Native Python implementation used when the C module is not compiled. + +:copyright: 2010 Pallets +:license: BSD-3-Clause +""" +from . import Markup +from ._compat import text_type + + +def escape(s): + """Replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in + the string with HTML-safe sequences. Use this if you need to display + text that might contain such characters in HTML. + + If the object has an ``__html__`` method, it is called and the + return value is assumed to already be safe for HTML. + + :param s: An object to be converted to a string and escaped. + :return: A :class:`Markup` string with the escaped text. + """ + if hasattr(s, "__html__"): + return Markup(s.__html__()) + return Markup( + text_type(s) + .replace("&", "&") + .replace(">", ">") + .replace("<", "<") + .replace("'", "'") + .replace('"', """) + ) + + +def escape_silent(s): + """Like :func:`escape` but treats ``None`` as the empty string. + Useful with optional values, as otherwise you get the string + ``'None'`` when the value is ``None``. + + >>> escape(None) + Markup('None') + >>> escape_silent(None) + Markup('') + """ + if s is None: + return Markup() + return escape(s) + + +def soft_unicode(s): + """Convert an object to a string if it isn't already. This preserves + a :class:`Markup` string rather than converting it back to a basic + string, so it will still be marked as safe and won't be escaped + again. + + >>> value = escape('<User 1>') + >>> value + Markup('<User 1>') + >>> escape(str(value)) + Markup('&lt;User 1&gt;') + >>> escape(soft_unicode(value)) + Markup('<User 1>') + """ + if not isinstance(s, text_type): + s = text_type(s) + return s diff --git a/contrib/python/MarkupSafe/py2/tests/conftest.py b/contrib/python/MarkupSafe/py2/tests/conftest.py new file mode 100644 index 0000000000..296cd58f5f --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/conftest.py @@ -0,0 +1,37 @@ +import pytest + +from markupsafe import _native + +try: + from markupsafe import _speedups +except ImportError: + _speedups = None + + +@pytest.fixture( + scope="session", + params=( + _native, + pytest.param( + _speedups, + marks=pytest.mark.skipif(_speedups is None, reason="speedups unavailable"), + ), + ), +) +def _mod(request): + return request.param + + +@pytest.fixture(scope="session") +def escape(_mod): + return _mod.escape + + +@pytest.fixture(scope="session") +def escape_silent(_mod): + return _mod.escape_silent + + +@pytest.fixture(scope="session") +def soft_str(_mod): + return _mod.soft_unicode diff --git a/contrib/python/MarkupSafe/py2/tests/test_escape.py b/contrib/python/MarkupSafe/py2/tests/test_escape.py new file mode 100644 index 0000000000..788134aeaa --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/test_escape.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +import pytest + +from markupsafe import Markup + + +@pytest.mark.parametrize( + ("value", "expect"), + ( + # empty + (u"", u""), + # ascii + (u"abcd&><'\"efgh", u"abcd&><'"efgh"), + (u"&><'\"efgh", u"&><'"efgh"), + (u"abcd&><'\"", u"abcd&><'""), + # 2 byte + (u"こんにちは&><'\"こんばんは", u"こんにちは&><'"こんばんは"), + (u"&><'\"こんばんは", u"&><'"こんばんは"), + (u"こんにちは&><'\"", u"こんにちは&><'""), + # 4 byte + ( + u"\U0001F363\U0001F362&><'\"\U0001F37A xyz", + u"\U0001F363\U0001F362&><'"\U0001F37A xyz", + ), + (u"&><'\"\U0001F37A xyz", u"&><'"\U0001F37A xyz"), + (u"\U0001F363\U0001F362&><'\"", u"\U0001F363\U0001F362&><'""), + ), +) +def test_escape(escape, value, expect): + assert escape(value) == Markup(expect) diff --git a/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py b/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py new file mode 100644 index 0000000000..5f9ffde438 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +import pytest + +from markupsafe import escape + + +class CustomHtmlThatRaises(object): + def __html__(self): + raise ValueError(123) + + +def test_exception_custom_html(): + """Checks whether exceptions in custom __html__ implementations are + propagated correctly. + + There was a bug in the native implementation at some point: + https://github.com/pallets/markupsafe/issues/108 + """ + obj = CustomHtmlThatRaises() + with pytest.raises(ValueError): + escape(obj) diff --git a/contrib/python/MarkupSafe/py2/tests/test_leak.py b/contrib/python/MarkupSafe/py2/tests/test_leak.py new file mode 100644 index 0000000000..b36a4ce4bc --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/test_leak.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +import gc +import sys + +import pytest + +from markupsafe import escape + + +@pytest.mark.skipif( + escape.__module__ == "markupsafe._native", + reason="only test memory leak with speedups", +) +def test_markup_leaks(): + counts = set() + + for _i in range(20): + for _j in range(1000): + escape("foo") + escape("<foo>") + escape(u"foo") + escape(u"<foo>") + + if hasattr(sys, "pypy_version_info"): + gc.collect() + + counts.add(len(gc.get_objects())) + + assert len(counts) == 1 diff --git a/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py b/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py new file mode 100644 index 0000000000..5b08006262 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- +import pytest + +from markupsafe import escape +from markupsafe import escape_silent +from markupsafe import Markup +from markupsafe._compat import PY2 +from markupsafe._compat import text_type + + +def test_adding(): + unsafe = '<script type="application/x-some-script">alert("foo");</script>' + safe = Markup("<em>username</em>") + assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe) + + +@pytest.mark.parametrize( + ("template", "data", "expect"), + ( + ("<em>%s</em>", "<bad user>", "<em><bad user></em>"), + ( + "<em>%(username)s</em>", + {"username": "<bad user>"}, + "<em><bad user></em>", + ), + ("%i", 3.14, "3"), + ("%.2f", 3.14, "3.14"), + ), +) +def test_string_interpolation(template, data, expect): + assert Markup(template) % data == expect + + +def test_type_behavior(): + assert type(Markup("foo") + "bar") is Markup + x = Markup("foo") + assert x.__html__() is x + + +def test_html_interop(): + class Foo(object): + def __html__(self): + return "<em>awesome</em>" + + def __unicode__(self): + return "awesome" + + __str__ = __unicode__ + + assert Markup(Foo()) == "<em>awesome</em>" + result = Markup("<strong>%s</strong>") % Foo() + assert result == "<strong><em>awesome</em></strong>" + + +def test_tuple_interpol(): + result = Markup("<em>%s:%s</em>") % ("<foo>", "<bar>") + expect = Markup(u"<em><foo>:<bar></em>") + assert result == expect + + +def test_dict_interpol(): + result = Markup("<em>%(foo)s</em>") % {"foo": "<foo>"} + expect = Markup(u"<em><foo></em>") + assert result == expect + + result = Markup("<em>%(foo)s:%(bar)s</em>") % {"foo": "<foo>", "bar": "<bar>"} + expect = Markup(u"<em><foo>:<bar></em>") + assert result == expect + + +def test_escaping(): + assert escape("\"<>&'") == ""<>&'" + assert Markup("<em>Foo & Bar</em>").striptags() == "Foo & Bar" + + +def test_unescape(): + assert Markup("<test>").unescape() == "<test>" + + result = Markup("jack & tavi are cooler than mike & russ").unescape() + expect = "jack & tavi are cooler than mike & russ" + assert result == expect + + original = "&foo;" + once = Markup(original).unescape() + twice = Markup(once).unescape() + expect = "&foo;" + assert once == expect + assert twice == expect + + +def test_format(): + result = Markup("<em>{awesome}</em>").format(awesome="<awesome>") + assert result == "<em><awesome></em>" + + result = Markup("{0[1][bar]}").format([0, {"bar": "<bar/>"}]) + assert result == "<bar/>" + + result = Markup("{0[1][bar]}").format([0, {"bar": Markup("<bar/>")}]) + assert result == "<bar/>" + + +def test_formatting_empty(): + formatted = Markup("{}").format(0) + assert formatted == Markup("0") + + +def test_custom_formatting(): + class HasHTMLOnly(object): + def __html__(self): + return Markup("<foo>") + + class HasHTMLAndFormat(object): + def __html__(self): + return Markup("<foo>") + + def __html_format__(self, spec): + return Markup("<FORMAT>") + + assert Markup("{0}").format(HasHTMLOnly()) == Markup("<foo>") + assert Markup("{0}").format(HasHTMLAndFormat()) == Markup("<FORMAT>") + + +def test_complex_custom_formatting(): + class User(object): + def __init__(self, id, username): + self.id = id + self.username = username + + def __html_format__(self, format_spec): + if format_spec == "link": + return Markup('<a href="/user/{0}">{1}</a>').format( + self.id, self.__html__() + ) + elif format_spec: + raise ValueError("Invalid format spec") + + return self.__html__() + + def __html__(self): + return Markup("<span class=user>{0}</span>").format(self.username) + + user = User(1, "foo") + result = Markup("<p>User: {0:link}").format(user) + expect = Markup('<p>User: <a href="/user/1"><span class=user>foo</span></a>') + assert result == expect + + +def test_formatting_with_objects(): + class Stringable(object): + def __unicode__(self): + return u"строка" + + if PY2: + + def __str__(self): + return "some other value" + + else: + __str__ = __unicode__ + + assert Markup("{s}").format(s=Stringable()) == Markup(u"строка") + + +def test_all_set(): + import markupsafe as markup + + for item in markup.__all__: + getattr(markup, item) + + +def test_escape_silent(): + assert escape_silent(None) == Markup() + assert escape(None) == Markup(None) + assert escape_silent("<foo>") == Markup(u"<foo>") + + +def test_splitting(): + expect = [Markup("a"), Markup("b")] + assert Markup("a b").split() == expect + assert Markup("a b").rsplit() == expect + assert Markup("a\nb").splitlines() == expect + + +def test_mul(): + assert Markup("a") * 3 == Markup("aaa") + + +def test_escape_return_type(): + assert isinstance(escape("a"), Markup) + assert isinstance(escape(Markup("a")), Markup) + + class Foo: + def __html__(self): + return "<strong>Foo</strong>" + + assert isinstance(escape(Foo()), Markup) diff --git a/contrib/python/MarkupSafe/py2/tests/ya.make b/contrib/python/MarkupSafe/py2/tests/ya.make new file mode 100644 index 0000000000..62ea965260 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/tests/ya.make @@ -0,0 +1,17 @@ +PY2TEST() + +PEERDIR( + contrib/python/MarkupSafe +) + +TEST_SRCS( + conftest.py + test_escape.py + test_exception_custom_html.py + test_leak.py + test_markupsafe.py +) + +NO_LINT() + +END() diff --git a/contrib/python/MarkupSafe/py2/ya.make b/contrib/python/MarkupSafe/py2/ya.make new file mode 100644 index 0000000000..fa01deed75 --- /dev/null +++ b/contrib/python/MarkupSafe/py2/ya.make @@ -0,0 +1,37 @@ +PY2_LIBRARY() + +LICENSE(BSD-3-Clause) + +VERSION(1.1.1) + +PY_SRCS( + TOP_LEVEL + markupsafe/_compat.py + markupsafe/_constants.py + markupsafe/__init__.py + markupsafe/_native.py +) + +#SRCS( +# markupsafe/_speedups.c +#) + +#PY_REGISTER( +# markupsafe._speedups +#) + +NO_LINT() + +NO_COMPILER_WARNINGS() + +RESOURCE_FILES( + PREFIX contrib/python/MarkupSafe/py2/ + .dist-info/METADATA + .dist-info/top_level.txt +) + +END() + +RECURSE_FOR_TESTS( + tests +) |