fix parsing of SGR RGB codes using colons

This commit is contained in:
Alex Carney 2025-06-21 14:36:51 +01:00
parent 9c9b011187
commit 7b1567cc18
4 changed files with 21 additions and 2 deletions

View File

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed extraction of recursive exceptions https://github.com/Textualize/rich/pull/3772
- Fixed padding applied to Syntax https://github.com/Textualize/rich/pull/3782
- Fixed `Panel` title missing the panel background style https://github.com/Textualize/rich/issues/3569
- Fixed parsing of SGR color codes using colons https://github.com/Textualize/rich/pull/3789
### Added

View File

@ -11,6 +11,7 @@ The following people have contributed to the development of Rich:
- [Robin Bowes](https://github.com/yo61)
- [Dennis Brakhane](https://github.com/brakhane)
- [Darren Burns](https://github.com/darrenburns)
- [Alex Carney](https://github.com/alcarney)
- [Ceyda Cinarel](https://github.com/cceyda)
- [Jim Crist-Harif](https://github.com/jcrist)
- [Ed Davis](https://github.com/davised)

View File

@ -144,6 +144,7 @@ class AnsiDecoder:
Returns:
Text: A Text instance marked up according to ansi codes.
"""
from_ansi = Color.from_ansi
from_rgb = Color.from_rgb
_Style = Style
@ -163,7 +164,7 @@ class AnsiDecoder:
# Ignore invalid codes, because we want to be lenient
codes = [
min(255, int(_code) if _code else 0)
for _code in sgr.split(";")
for _code in sgr.replace("::", ";").replace(":", ";").split(";")
if _code.isdigit() or _code == ""
]
iter_codes = iter(codes)

View File

@ -1,5 +1,4 @@
import pytest
from rich.ansi import AnsiDecoder
from rich.console import Console
from rich.style import Style
@ -70,6 +69,23 @@ def test_decode_issue_2688(ansi_bytes, expected_text):
assert str(text) == expected_text
@pytest.mark.parametrize(
"text,expected",
[
(
"\x1b[38;2;255;0;0mred\x1b[0m text",
Text("red text", spans=[Span(0, 3, Style.parse("#ff0000"))]),
),
(
"\x1b[38:2::255:0:0mred\x1b[0m text",
Text("red text", spans=[Span(0, 3, Style.parse("#ff0000"))]),
),
],
)
def test_decode_sgr_rgb(text, expected):
assert Text.from_ansi(text) == expected
@pytest.mark.parametrize("code", [*"0123456789:;<=>?"])
def test_strip_private_escape_sequences(code):
text = Text.from_ansi(f"\x1b{code}x")