You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

safestring.py 2.3KB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """
  2. Functions for working with "safe strings": strings that can be displayed safely
  3. without further escaping in HTML. Marking something as a "safe string" means
  4. that the producer of the string has already turned characters that should not
  5. be interpreted by the HTML engine (e.g. '<') into the appropriate entities.
  6. """
  7. from django.utils.functional import wraps
  8. class SafeData:
  9. def __html__(self):
  10. """
  11. Return the html representation of a string for interoperability.
  12. This allows other template engines to understand Django's SafeData.
  13. """
  14. return self
  15. class SafeBytes(bytes, SafeData):
  16. """
  17. A bytes subclass that has been specifically marked as "safe" (requires no
  18. further escaping) for HTML output purposes.
  19. Kept in Django 2.0 for usage by apps supporting Python 2. Shouldn't be used
  20. in Django anymore.
  21. """
  22. def __add__(self, rhs):
  23. """
  24. Concatenating a safe byte string with another safe byte string or safe
  25. string is safe. Otherwise, the result is no longer safe.
  26. """
  27. t = super().__add__(rhs)
  28. if isinstance(rhs, SafeText):
  29. return SafeText(t)
  30. elif isinstance(rhs, SafeBytes):
  31. return SafeBytes(t)
  32. return t
  33. class SafeText(str, SafeData):
  34. """
  35. A str subclass that has been specifically marked as "safe" for HTML output
  36. purposes.
  37. """
  38. def __add__(self, rhs):
  39. """
  40. Concatenating a safe string with another safe bytestring or
  41. safe string is safe. Otherwise, the result is no longer safe.
  42. """
  43. t = super().__add__(rhs)
  44. if isinstance(rhs, SafeData):
  45. return SafeText(t)
  46. return t
  47. def __str__(self):
  48. return self
  49. SafeString = SafeText
  50. def _safety_decorator(safety_marker, func):
  51. @wraps(func)
  52. def wrapped(*args, **kwargs):
  53. return safety_marker(func(*args, **kwargs))
  54. return wrapped
  55. def mark_safe(s):
  56. """
  57. Explicitly mark a string as safe for (HTML) output purposes. The returned
  58. object can be used everywhere a string is appropriate.
  59. If used on a method as a decorator, mark the returned data as safe.
  60. Can be called multiple times on a single string.
  61. """
  62. if hasattr(s, '__html__'):
  63. return s
  64. if callable(s):
  65. return _safety_decorator(mark_safe, s)
  66. return SafeText(s)