From bf592926cd4942e6b3561c8faa94baef2f1134a6 Mon Sep 17 00:00:00 2001 From: Ankur Tyagi Date: Mon, 14 Sep 2026 15:12:54 +1200 Subject: [PATCH] python3-sqlparse: patch CVE-2026-54284 Detais: https://nvd.nist.gov/vuln/detail/cve-2026-54284 Signed-off-by: Ankur Tyagi Signed-off-by: Anuj Mittal --- .../python3-sqlparse/CVE-2026-54284-1.patch | 37 +++++ .../python3-sqlparse/CVE-2026-54284-2.patch | 144 ++++++++++++++++++ .../python/python3-sqlparse_0.5.5.bb | 4 + 3 files changed, 185 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-1.patch create mode 100644 meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-2.patch diff --git a/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-1.patch b/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-1.patch new file mode 100644 index 0000000000..90769436aa --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-1.patch @@ -0,0 +1,37 @@ +From 1a0f6530c8f506f953d1b4ffdfa84ae7ad72f7df Mon Sep 17 00:00:00 2001 +From: alhudz +Date: Mon, 1 Jun 2026 19:05:57 +0530 +Subject: [PATCH] set group value from child tokens to avoid quadratic grouping + +(cherry picked from commit 939b129e24c0ad5d51368b1aa72fffcaca76f06f) + +CVE: CVE-2026-54284 +Upstream-Status: Backport [https://github.com/andialbrecht/sqlparse/commit/939b129e24c0ad5d51368b1aa72fffcaca76f06f] + +Signed-off-by: Ankur Tyagi +--- + sqlparse/sql.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sqlparse/sql.py b/sqlparse/sql.py +index 831dfb9..0163ff1 100644 +--- a/sqlparse/sql.py ++++ b/sqlparse/sql.py +@@ -159,7 +159,7 @@ class TokenList(Token): + def __init__(self, tokens=None): + self.tokens = tokens or [] + [setattr(token, 'parent', self) for token in self.tokens] +- super().__init__(None, str(self)) ++ super().__init__(None, ''.join(token.value for token in self.tokens)) + self.is_group = True + + def __str__(self): +@@ -322,7 +322,7 @@ class TokenList(Token): + grp = start + grp.tokens.extend(subtokens) + del self.tokens[start_idx + 1:end_idx] +- grp.value = str(start) ++ grp.value += ''.join(token.value for token in subtokens) + else: + subtokens = self.tokens[start_idx:end_idx] + grp = grp_cls(subtokens) diff --git a/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-2.patch b/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-2.patch new file mode 100644 index 0000000000..c2d355f78a --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-sqlparse/CVE-2026-54284-2.patch @@ -0,0 +1,144 @@ +From 6416e171b41da8939f391c0492b355d3b6cb8c11 Mon Sep 17 00:00:00 2001 +From: Andi Albrecht +Date: Sat, 6 Jun 2026 07:12:43 +0200 +Subject: [PATCH] Add tests from PR, update CHANGELOG and AUTHORS. + +(cherry picked from commit f80af6a4007f11ada847218df8c29dc859238290) + +CVE: CVE-2026-54284 +Upstream-Status: Backport [https://github.com/andialbrecht/sqlparse/commit/f80af6a4007f11ada847218df8c29dc859238290] + +Dropped changes to the CHANGELOG file. + +Signed-off-by: Ankur Tyagi +--- + AUTHORS | 2 ++ + benchmarks/bench_grouping.py | 59 ++++++++++++++++++++++++++++++++++++ + tests/test_dos_prevention.py | 28 +++++++++++++++++ + 3 files changed, 89 insertions(+) + create mode 100644 benchmarks/bench_grouping.py + +diff --git a/AUTHORS b/AUTHORS +index 24ca667..872c700 100644 +--- a/AUTHORS ++++ b/AUTHORS +@@ -12,6 +12,7 @@ Alphabetical list of contributors: + * Aki Ariga + * Alexander Beedie + * Alexey Malyshev ++* alhudz + * ali-tny + * andrew deryabin + * Andrew Tipton +@@ -77,6 +78,7 @@ Alphabetical list of contributors: + * Tao Wang + * Tenghuan + * Tim Graham ++* tonghuaroot + * Victor Hahn + * Victor Uriarte + * Ville Skyttä +diff --git a/benchmarks/bench_grouping.py b/benchmarks/bench_grouping.py +new file mode 100644 +index 0000000..245ea0e +--- /dev/null ++++ b/benchmarks/bench_grouping.py +@@ -0,0 +1,59 @@ ++"""Grouping performance benchmarks. ++ ++Measures parse time for SQL patterns that stress the grouping engine: ++- Deeply nested parentheses ++- Deeply nested CASE WHEN expressions ++- Wide column lists (tests O(N) identifier grouping, fixed in PR848) ++ ++Run with: python benchmarks/bench_grouping.py ++""" ++ ++import signal ++import time ++ ++import sqlparse ++ ++ ++def _alarm_handler(signum, frame): ++ raise TimeoutError() ++ ++ ++signal.signal(signal.SIGALRM, _alarm_handler) ++ ++ ++def measure(label, sql, fn): ++ signal.alarm(30) ++ t0 = time.perf_counter() ++ status = 'OK' ++ try: ++ fn(sql) ++ except sqlparse.exceptions.SQLParseError: ++ status = 'CAP' ++ except TimeoutError: ++ status = 'TIMEOUT' ++ finally: ++ signal.alarm(0) ++ dt = (time.perf_counter() - t0) * 1000 ++ print(f' {status:8} {dt:8.1f} ms {label} ({len(sql)} B)') ++ ++ ++# Vector 1: deeply nested parentheses ++print('Nested parentheses:') ++for n in (200, 500, 1000, 2000): ++ sql = 'SELECT ' + '(' * n + '1' + ')' * n ++ measure(f'nested-paren n={n}', sql, sqlparse.parse) ++ ++# Vector 2: deeply nested CASE WHEN ++print('Nested CASE WHEN:') ++for n in (100, 200, 400): ++ case = '1' ++ for i in range(n): ++ case = f'CASE WHEN x={i} THEN {case} ELSE NULL END' ++ measure(f'CASE-nested n={n}', f'SELECT {case} FROM t', sqlparse.parse) ++ ++# Vector 3: wide column lists (O(N) grouping, regression fixed in PR848) ++print('Wide column lists:') ++for n in (500, 1000, 2000, 4000): ++ cols = ', '.join(f'col_{i}' for i in range(n)) ++ sql = f'SELECT {cols} FROM t' ++ measure(f'wide-select n={n}', sql, sqlparse.parse) +diff --git a/tests/test_dos_prevention.py b/tests/test_dos_prevention.py +index 4e826c5..1753c05 100644 +--- a/tests/test_dos_prevention.py ++++ b/tests/test_dos_prevention.py +@@ -50,6 +50,34 @@ class TestDoSPrevention: + with pytest.raises(SQLParseError, match="Maximum number of tokens exceeded"): + sqlparse.format(sql, reindent=True) + ++ def test_nested_paren_within_cap_under_1s(self): ++ """Reaching MAX_GROUPING_DEPTH must not require multi-second CPU. ++ ++ Before the TokenList.__init__ fix, a 1 KB payload of 500 nested ++ parens took ~1.3 s and a 2 KB payload of 1000 nested parens took ++ ~11 s before the depth cap raised SQLParseError, because each ++ TokenList materialised its ``value`` via ``str(self)`` which ++ recursed over the full subtree (O(n * depth)). ++ """ ++ sql = 'SELECT ' + '(' * 1000 + '1' + ')' * 1000 ++ t0 = time.perf_counter() ++ with pytest.raises(SQLParseError, match='Maximum grouping depth'): ++ sqlparse.parse(sql) ++ dt = time.perf_counter() - t0 ++ assert dt < 1.0, f'parse took {dt:.2f}s, expected sub-second' ++ ++ def test_nested_case_within_cap_under_1s(self): ++ """Same invariant as nested parentheses, exercised via CASE WHEN.""" ++ case = '1' ++ for i in range(400): ++ case = f'CASE WHEN x={i} THEN {case} ELSE NULL END' ++ sql = f'SELECT {case} FROM t' ++ t0 = time.perf_counter() ++ with pytest.raises(SQLParseError, match='Maximum grouping depth'): ++ sqlparse.parse(sql) ++ dt = time.perf_counter() - t0 ++ assert dt < 1.0, f'parse took {dt:.2f}s, expected sub-second' ++ + def test_normal_sql_still_works(self): + """Test that normal SQL still works correctly after DoS protections.""" + sql = """ diff --git a/meta-python/recipes-devtools/python/python3-sqlparse_0.5.5.bb b/meta-python/recipes-devtools/python/python3-sqlparse_0.5.5.bb index 03c032c49e..021ccfa349 100644 --- a/meta-python/recipes-devtools/python/python3-sqlparse_0.5.5.bb +++ b/meta-python/recipes-devtools/python/python3-sqlparse_0.5.5.bb @@ -6,6 +6,10 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=2b136f573f5386001ea3b7b9016222fc" SRC_URI[sha256sum] = "e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e" +SRC_URI += "file://CVE-2026-54284-1.patch \ + file://CVE-2026-54284-2.patch \ +" + CVE_PRODUCT = "sqlparse" export BUILD_SYS