Skip to content

Preserve SGR parameter order when mixing colon colors and resets - #321

Closed
anticipate218 wants to merge 1 commit into
jquast:masterfrom
anticipate218:fix/c-sgr-parameter-order
Closed

anticipate218 wants to merge 1 commit into
jquast:masterfrom
anticipate218:fix/c-sgr-parameter-order

Conversation

@anticipate218

Copy link
Copy Markdown

The C SGR parser applies colon-separated colors immediately, then applies all ordinary parameters afterward. A reset followed by a color, such as \x1b[0;38:2::255:0:0m, therefore loses its color when propagate_sgr() restores it on the next line or clip() restores it at the clipping boundary. The Python implementation already preserves this order.

This extracts the existing integer-parameter application loop and flushes each integer run before applying the next colon color. The integer-only path and color serialization are unchanged. Tests cover resets, default/basic colors, and replacement between the two color syntaxes through both public functions and the C library.

The scope is valid SGR parameter sequences. Incomplete color parameters interrupted by a colon tuple can also behave differently; this does not try to define or normalize malformed input.

Validation on Windows x64, CPython 3.13, MSVC:

  • The new public-API tests fail on the original C extension: 10 failed, 4 passed. The new C-library test also fails on the original implementation.
  • Full suite with the fixed C extension: 1,934 passed, 11 skipped.
  • Full suite in Python mode: 1,897 passed, 48 skipped.
  • All 13 CTest programs pass, including allocation-failure coverage.
  • Changed files pass clang-format, flake8, isort, docformatter, pylint, and git diff --check.
  • The changed files pass codespell. The sdist and Windows C-extension wheel build successfully and pass twine check --strict; the sdist contains the exact tested C source.
  • An independent local comparison of 2,190 valid parameter combinations, including integer runs across the stack-allocation boundary, agrees with the Python implementation. Allocation-failure probes found no retained allocations.

This was found while reading the SGR parser, rather than from a reported production incident. No real terminal rendering or performance claim is made. AI assistance: OpenAI Codex generated the patch and ran the checks above.

Apply accumulated integer SGR parameters before each following colon color. Preserve valid reset/color ordering through the C-backed propagation and clipping APIs, with native and Python regression coverage.

Assisted-by: OpenAI Codex
@jquast

jquast commented Nov 13, 2026

Copy link
Copy Markdown
Owner

Superseded by #327

@jquast jquast closed this Nov 13, 2026
jquast added a commit that referenced this pull request Nov 13, 2026
This supersedes #321. I studied kitty and xterm parsing about this small possible deviation from ECMA-48/ITU T.416/etc. standards, and those changes have been simplified (WCWIDTH_SGR_MAX_PARAMS was removed, malloc/realloc/free removed), while also supporting "hybrid" sequences found to be supported in at least xterm and kitty, and it brings coverage of the changed code up to 100%

Note that #321 was likely created by AI Analysis, that these are probably [Unlikely sequences](https://github.com/jquast/wcwidth#unlikely-sequences), but, because I discovered code in xterm and kitty that attempts to support them, it is presumed that *some* misbehaving TUI program or library *somewhere* must have drove them into the more complex accommodation.
@anticipate218

Copy link
Copy Markdown
Author

Thanks for reviewing this and consolidating it in #327. I appreciate the xterm/kitty investigation and the simpler allocation-free implementation. Thanks for taking this forward and merging the consolidated fix.

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.

2 participants