Skip to content

Don't raise IndexError on short parenthesis groups in StripWhitespaceFilter - #941

Open
adarshsm wants to merge 1 commit into
andialbrecht:masterfrom
adarshsm:fix/885-stripws-malformed-parenthesis
Open

adarshsm wants to merge 1 commit into
andialbrecht:masterfrom
adarshsm:fix/885-stripws-malformed-parenthesis

Conversation

@adarshsm

Copy link
Copy Markdown

Fixes #885.

_stripws_parenthesis assumed every Parenthesis group is laid out as ( content ), so it indexed tokens[1] and tokens[-2] unconditionally. For "( AS )" the grouping step produces a Parenthesis that holds a single nested Identifier token, so tokens[1] does not exist:

>>> sqlparse.format("( AS )", strip_whitespace=True)
IndexError: list index out of range
>>> stmt = sqlparse.parse("( AS )")[0]
>>> paren = next(t for t in stmt.token_next(0) if isinstance(t, Parenthesis))
>>> len(paren.tokens)
1

Change

sqlparse/filters/others.py:

  • When the group is too short to have a bracket on both sides, fall back to _stripws_default instead of indexing past the end.
  • Guard the inner trailing-whitespace loop so an inner group whose tokens are all whitespace can't empty itself and then be indexed.

The output for the reported input is now the input unchanged ("( AS )"). I deliberately did not collapse it to "(AS)": the inner content is a single nested group that already went through _stripws_default, and tightening it would need bracket-aware handling that is out of scope for the crash.

Behaviour for well-formed groups is unchanged — SELECT ( a ) FROM t still formats to SELECT (a) FROM t, and the full suite passes.

Tests

Two regression tests in tests/test_regressions.py (near the other issue-numbered tests):

  • test_issue885_stripws_malformed_parenthesis — the reported reproducer.
  • test_issue885_stripws_short_parenthesis_groups — (), ( ), (a) must not raise.
uv run --group dev --python 3.11 pytest tests/
508 passed, 2 xfailed, 1 xpassed

uv run --group dev ruff check sqlparse/
All checks passed!

A CHANGELOG entry is added under Development Version.

…Filter

_stripws_parenthesis assumed a group laid out as "(" content ")", so
tokens[1] and tokens[-2] existed. A group holding fewer tokens raised
IndexError from inside the formatter:

    >>> sqlparse.format("( AS )", strip_whitespace=True)
    IndexError: list index out of range

"( AS )" groups the whole thing into a Parenthesis with a single nested
Identifier token, so the assumption did not hold.

Fall back to the default whitespace handling when the group is too short
to have a bracket on either side, and guard the inner trailing-whitespace
loop against a group whose tokens are all whitespace.

Closes andialbrecht#885
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

strip_whitespace=True raises IndexError on "( AS )"

1 participant