mirror of https://github.com/Textualize/rich.git
Strip problematic private escape sequences:
["Private escape sequences"](https://en.wikipedia.org/wiki/ANSI_escape_code#Fp_Escape_sequences)
are escape sequences that are reserved for private use, though `\x1b7` and
`\x1b8` are commonly used for storing and restoring the current cursor
position. When those escape codes are not stripped the cursor jumps around and
causes Rich to write garbage output. An example of a program that uses this
cursor store/restore functionality is the APK package manager in Alpine Linux:
48d91f482e/src/print.c (L232-240)
This commit updates the ANSI parser to ignore the `\x1b0`-`\x1b?` escape
sequences, thus preventing them from being printed and causing havoc.
This commit is contained in:
parent
26152e9cc9
commit
f021979c79
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Fixed
|
||||
|
||||
- Strip problematic private escape sequences (like `\x1b7`)
|
||||
|
||||
## [13.7.0] - 2023-11-15
|
||||
|
||||
### Added
|
||||
|
|
|
@ -25,6 +25,7 @@ The following people have contributed to the development of Rich:
|
|||
- [Kenneth Hoste](https://github.com/boegel)
|
||||
- [Lanqing Huang](https://github.com/lqhuang)
|
||||
- [Finn Hughes](https://github.com/finnhughes)
|
||||
- [Logan Hunt](https://github.com/dosisod)
|
||||
- [Ionite](https://github.com/ionite34)
|
||||
- [Josh Karpel](https://github.com/JoshKarpel)
|
||||
- [Jan Katins](https://github.com/jankatins)
|
||||
|
|
|
@ -9,6 +9,7 @@ from .text import Text
|
|||
|
||||
re_ansi = re.compile(
|
||||
r"""
|
||||
(?:\x1b[0-?])|
|
||||
(?:\x1b\](.*?)\x1b\\)|
|
||||
(?:\x1b([(@-Z\\-_]|\[[0-?]*[ -/]*[@-~]))
|
||||
""",
|
||||
|
|
|
@ -68,3 +68,17 @@ def test_decode_issue_2688(ansi_bytes, expected_text):
|
|||
text = Text.from_ansi(ansi_bytes.decode())
|
||||
|
||||
assert str(text) == expected_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code", [*"0123456789:;<=>?"])
|
||||
def test_strip_private_escape_sequences(code):
|
||||
text = Text.from_ansi(f"\x1b{code}x")
|
||||
|
||||
console = Console(force_terminal=True)
|
||||
|
||||
with console.capture() as capture:
|
||||
console.print(text)
|
||||
|
||||
expected = "x\n"
|
||||
|
||||
assert capture.get() == expected
|
||||
|
|
Loading…
Reference in New Issue