]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fix catastrophic backtracking in mysql index comment reflection regex
authordxbjavid <dxbjavid@gmail.com>
Mon, 22 Jun 2026 15:30:40 +0000 (11:30 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 23 Jun 2026 19:28:57 +0000 (15:28 -0400)
Improved the regular expression used to parse index COMMENT clauses
in MySQL SHOW CREATE TABLE reflection to use an unambiguous
single-quoted-string pattern; the previous pattern was theoretically
subject to backtracking on malformed input, though such input is not
producible by MySQL itself.  Fix courtesy of Javid Khan.

Fixes: #13393
Closes: #13394
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13394
Pull-request-sha: 52239d122e937fd6b266ac49fb024063c82c9372

Change-Id: I9174705dd8e1539d8ed7c384b13280bf543d7341

doc/build/changelog/unreleased_21/13393.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mysql/reflection.py
test/dialect/mysql/test_reflection.py

diff --git a/doc/build/changelog/unreleased_21/13393.rst b/doc/build/changelog/unreleased_21/13393.rst
new file mode 100644 (file)
index 0000000..8083b0b
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, mysql
+    :tickets: 13393
+
+    Improved the regular expression used to parse index ``COMMENT`` clauses
+    in MySQL ``SHOW CREATE TABLE`` reflection to use an unambiguous
+    single-quoted-string pattern; the previous pattern was theoretically
+    subject to backtracking on malformed input, though such input is not
+    producible by MySQL itself.  Fix courtesy of Javid Khan.
index d5ac03a51320f8943c35d3bc9cb270376bf4ab68..ac9b323d92f5fae38567003fad41c4f296efaa40 100644 (file)
@@ -518,7 +518,7 @@ class MySQLTableDefinitionParser:
             r"(?: +USING +(?P<using_post>\S+))?"
             r"(?: +KEY_BLOCK_SIZE *[ =]? *(?P<keyblock>\S+))?"
             r"(?: +WITH PARSER +(?P<parser>\S+))?"
-            r"(?: +COMMENT +(?P<comment>(\x27\x27|\x27([^\x27])*?\x27)+))?"
+            r"(?: +COMMENT +(?P<comment>\x27(?:\x27\x27|[^\x27])*\x27))?"
             r"(?: +/\*(?P<version_sql>.+)\*/ *)?"
             r",?$" % quotes
         )
index e42ad32ff97a4d7bd3e4367295f6d5f0d47e9222..c9302513b2a7aa4d8692a9af6013b508ee328411 100644 (file)
@@ -1502,6 +1502,22 @@ class RawReflectionTest(fixtures.TestBase):
         eq_(m.group("type"), "PRIMARY")
         eq_(m.group("columns"), "`id`")
 
+    @testing.combinations(
+        # 60 single quotes is a valid SQL string (29 '' pairs inside outer
+        # quotes); the previous ambiguous pattern backtracked on this input
+        ("  KEY (`id`) COMMENT " + ("'" * 60), "'" * 60),
+        # odd quotes followed by a non-quote: uncloseable, should not match
+        ("  KEY (`id`) COMMENT " + ("'" * 59) + "x", None),
+        argnames="line,expected_comment",
+    )
+    def test_key_reflection_comment_many_quotes(self, line, expected_comment):
+        regex = self.parser._re_key
+        m = regex.match(line)
+        eq_(
+            m.group("comment") if m is not None else None,
+            expected_comment,
+        )
+
     def test_key_reflection_columns(self):
         regex = self.parser._re_key
         exprs = self.parser._re_keyexprs