From: dxbjavid Date: Mon, 22 Jun 2026 15:30:40 +0000 (-0400) Subject: fix catastrophic backtracking in mysql index comment reflection regex X-Git-Tag: rel_2_1_0b3~7^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ba06dcce50d7f9f30f953a2961db020f1e42afb;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git fix catastrophic backtracking in mysql index comment reflection regex 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 --- diff --git a/doc/build/changelog/unreleased_21/13393.rst b/doc/build/changelog/unreleased_21/13393.rst new file mode 100644 index 0000000000..8083b0b07d --- /dev/null +++ b/doc/build/changelog/unreleased_21/13393.rst @@ -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. diff --git a/lib/sqlalchemy/dialects/mysql/reflection.py b/lib/sqlalchemy/dialects/mysql/reflection.py index d5ac03a513..ac9b323d92 100644 --- a/lib/sqlalchemy/dialects/mysql/reflection.py +++ b/lib/sqlalchemy/dialects/mysql/reflection.py @@ -518,7 +518,7 @@ class MySQLTableDefinitionParser: r"(?: +USING +(?P\S+))?" r"(?: +KEY_BLOCK_SIZE *[ =]? *(?P\S+))?" r"(?: +WITH PARSER +(?P\S+))?" - r"(?: +COMMENT +(?P(\x27\x27|\x27([^\x27])*?\x27)+))?" + r"(?: +COMMENT +(?P\x27(?:\x27\x27|[^\x27])*\x27))?" r"(?: +/\*(?P.+)\*/ *)?" r",?$" % quotes ) diff --git a/test/dialect/mysql/test_reflection.py b/test/dialect/mysql/test_reflection.py index e42ad32ff9..c9302513b2 100644 --- a/test/dialect/mysql/test_reflection.py +++ b/test/dialect/mysql/test_reflection.py @@ -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