]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-135661: Fix parsing attributes with whitespaces around the "=" separator...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 22 Jul 2025 09:56:10 +0000 (11:56 +0200)
committerGitHub <noreply@github.com>
Tue, 22 Jul 2025 09:56:10 +0000 (11:56 +0200)
This fixes a regression introduced in GH-135930.
(cherry picked from commit dee650189497735edbc08a54edabb5b06ef1bd09)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/html/parser.py
Lib/test/test_htmlparser.py
Misc/NEWS.d/next/Security/2025-06-25-14-13-39.gh-issue-135661.idjQ0B.rst

index 9b4f09599134bd611f3555083fffcd12baddfe7a..7eea885cfe63c56e70670534ae8983e3562bd957 100644 (file)
@@ -45,7 +45,7 @@ attrfind_tolerant = re.compile(r"""
   (
     (?<=['"\t\n\r\f /])[^\t\n\r\f />][^\t\n\r\f /=>]*  # attribute name
    )
-  (=                                # value indicator
+  ([\t\n\r\f ]*=[\t\n\r\f ]*        # value indicator
     ('[^']*'                        # LITA-enclosed value
     |"[^"]*"                        # LIT-enclosed value
     |(?!['"])[^>\t\n\r\f ]*         # bare value
@@ -57,7 +57,7 @@ locatetagend = re.compile(r"""
   [a-zA-Z][^\t\n\r\f />]*           # tag name
   [\t\n\r\f /]*                     # optional whitespace before attribute name
   (?:(?<=['"\t\n\r\f /])[^\t\n\r\f />][^\t\n\r\f /=>]*  # attribute name
-    (?:=                            # value indicator
+    (?:[\t\n\r\f ]*=[\t\n\r\f ]*    # value indicator
       (?:'[^']*'                    # LITA-enclosed value
         |"[^"]*"                    # LIT-enclosed value
         |(?!['"])[^>\t\n\r\f ]*     # bare value
index 15cad061889a79bc5c8dcbade9a3b40feed4b7d2..47c0752fb517b96b334e01db4e2df170d2535976 100644 (file)
@@ -623,7 +623,7 @@ text
 
         html = '<div style="", foo = "bar" ><b>The <a href="some_url">rain</a>'
         expected = [
-            ('starttag', 'div', [('style', ''), (',', None), ('foo', None), ('=', None), ('"bar"', None)]),
+            ('starttag', 'div', [('style', ''), (',', None), ('foo', 'bar')]),
             ('starttag', 'b', []),
             ('data', 'The '),
             ('starttag', 'a', [('href', 'some_url')]),
@@ -813,12 +813,12 @@ class AttributesTestCase(TestCaseBase):
         ]
         self._run_check("""<a b='v' c="v" d=v e>""", output)
         self._run_check("<a foo==bar>", [('starttag', 'a', [('foo', '=bar')])])
-        self._run_check("<a foo =bar>", [('starttag', 'a', [('foo', None), ('=bar', None)])])
-        self._run_check("<a foo\t=bar>", [('starttag', 'a', [('foo', None), ('=bar', None)])])
+        self._run_check("<a foo =bar>", [('starttag', 'a', [('foo', 'bar')])])
+        self._run_check("<a foo\t=bar>", [('starttag', 'a', [('foo', 'bar')])])
         self._run_check("<a foo\v=bar>", [('starttag', 'a', [('foo\v', 'bar')])])
         self._run_check("<a foo\xa0=bar>", [('starttag', 'a', [('foo\xa0', 'bar')])])
-        self._run_check("<a foo= bar>", [('starttag', 'a', [('foo', ''), ('bar', None)])])
-        self._run_check("<a foo=\tbar>", [('starttag', 'a', [('foo', ''), ('bar', None)])])
+        self._run_check("<a foo= bar>", [('starttag', 'a', [('foo', 'bar')])])
+        self._run_check("<a foo=\tbar>", [('starttag', 'a', [('foo', 'bar')])])
         self._run_check("<a foo=\vbar>", [('starttag', 'a', [('foo', '\vbar')])])
         self._run_check("<a foo=\xa0bar>", [('starttag', 'a', [('foo', '\xa0bar')])])
 
@@ -829,8 +829,8 @@ class AttributesTestCase(TestCaseBase):
                                             ("d", "\txyz\n")])])
         self._run_check("""<a b='' c="">""",
                         [("starttag", "a", [("b", ""), ("c", "")])])
-        self._run_check("<a b=\t c=\n>",
-                        [("starttag", "a", [("b", ""), ("c", "")])])
+        self._run_check("<a b=\tx c=\ny>",
+                        [('starttag', 'a', [('b', 'x'), ('c', 'y')])])
         self._run_check("<a b=\v c=\xa0>",
                         [("starttag", "a", [("b", "\v"), ("c", "\xa0")])])
         # Regression test for SF patch #669683.
@@ -899,13 +899,17 @@ class AttributesTestCase(TestCaseBase):
         )
         expected = [
             ('starttag', 'a', [('href', "test'style='color:red;bad1'")]),
-            ('data', 'test - bad1'), ('endtag', 'a'),
+            ('data', 'test - bad1'),
+            ('endtag', 'a'),
             ('starttag', 'a', [('href', "test'+style='color:red;ba2'")]),
-            ('data', 'test - bad2'), ('endtag', 'a'),
+            ('data', 'test - bad2'),
+            ('endtag', 'a'),
             ('starttag', 'a', [('href', "test'\xa0style='color:red;bad3'")]),
-            ('data', 'test - bad3'), ('endtag', 'a'),
-            ('starttag', 'a', [('href', None), ('=', None), ("test'&nbsp;style", 'color:red;bad4')]),
-            ('data', 'test - bad4'), ('endtag', 'a')
+            ('data', 'test - bad3'),
+            ('endtag', 'a'),
+            ('starttag', 'a', [('href', "test'\xa0style='color:red;bad4'")]),
+            ('data', 'test - bad4'),
+            ('endtag', 'a'),
         ]
         self._run_check(html, expected)
 
index b6f9e104e4404725e51fe8f08f266da83b91f563..27e886abdb58e56cf87ffdadbef181e398b1eb7e 100644 (file)
@@ -18,8 +18,3 @@ according to the HTML5 standard.
 
 * Multiple ``=`` between attribute name and value are no longer collapsed.
   E.g. ``<a foo==bar>`` produces attribute "foo" with value "=bar".
-
-* Whitespaces between the ``=`` separator and attribute name or value are no
-  longer ignored. E.g. ``<a foo =bar>`` produces two attributes "foo" and
-  "=bar", both with value None; ``<a foo= bar>`` produces two attributes:
-  "foo" with value "" and "bar" with value None.