diff --git a/CHANGES.rst b/CHANGES.rst index 7a94e8f8..f8a182f7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Unreleased - Drop support for Python 3.9. - Remove previously deprecated code. +- Fix performance issue with ``striptags``. :issue:`521` Version 3.0.3 diff --git a/src/markupsafe/__init__.py b/src/markupsafe/__init__.py index f8a0d58b..3b79610a 100644 --- a/src/markupsafe/__init__.py +++ b/src/markupsafe/__init__.py @@ -204,24 +204,29 @@ def striptags(self, /) -> str: 'Main ยป About' """ value = str(self) - - # Look for comments then tags separately. Otherwise, a comment that - # contains a tag would end early, leaving some of the comment behind. - - # keep finding comment start marks - while (start := value.find("", start)) == -1: - break - - value = f"{value[:start]}{value[end + 3 :]}" - - # remove tags using the same method - while (start := value.find("<")) != -1: - if (end := value.find(">", start)) == -1: + parts = [] + prev = 0 + while True: + start = value.find("<", prev) + if start == -1: break - - value = f"{value[:start]}{value[end + 1 :]}" + if value[start : start + 4] == "", start) + if end == -1: + break + parts.append(value[prev:start]) + prev = end + 3 + else: + # tag + end = value.find(">", start) + if end == -1: + break + parts.append(value[prev:start]) + prev = end + 1 + if prev > 0: + parts.append(value[prev:]) + value = "".join(parts) # collapse spaces value = " ".join(value.split())