diff options
author | Alexey Stepanov <penguinolog@users.noreply.github.com> | 2023-04-05 14:37:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-05 14:37:28 +0200 |
commit | 02d0fd689731d957f360858d3e3244a4c36166fb (patch) | |
tree | e83795aff0072955c45d4e56ae5d583901769e0b | |
parent | 9976f338c122a208b8a9108590ea525086cdd5a1 (diff) | |
download | urwid-02d0fd689731d957f360858d3e3244a4c36166fb.tar.gz |
Fix old_str_util.decode_one : support bytes and str as arguments (#531)
fix #525
Co-authored-by: Aleksei Stepanov <alekseis@nvidia.com>
-rwxr-xr-x | urwid/old_str_util.py | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/urwid/old_str_util.py b/urwid/old_str_util.py index 8861b53..cd0d31c 100755 --- a/urwid/old_str_util.py +++ b/urwid/old_str_util.py @@ -92,53 +92,70 @@ def get_width(o) -> Literal[0, 1, 2]: return 1 -def decode_one(text: bytes, pos: int) -> tuple[int, int]: +def decode_one(text: bytes| str, pos: int) -> tuple[int, int]: """ Return (ordinal at pos, next position) for UTF-8 encoded text. """ - assert isinstance(text, bytes), text - b1 = text[pos] + lt = len(text) - pos + + b2 = 0 # Fallback, not changing anything + b3 = 0 # Fallback, not changing anything + b4 = 0 # Fallback, not changing anything + + try: + if isinstance(text, str): + b1 = ord(text[pos]) + if lt > 1: + b2 = ord(text[pos + 1]) + if lt > 2: + b3 = ord(text[pos + 2]) + if lt > 3: + b4 = ord(text[pos + 3]) + else: + b1 = text[pos] + if lt > 1: + b2 = text[pos + 1] + if lt > 2: + b3 = text[pos + 2] + if lt > 3: + b4 = text[pos + 3] + except Exception as e: + raise ValueError(f"{e}: {text=!r}, {pos=!r}, {lt=}").with_traceback(e.__traceback__) from e + if not b1 & 0x80: return b1, pos+1 error = ord("?"), pos+1 - lt = len(text) - lt = lt-pos + if lt < 2: return error if b1 & 0xe0 == 0xc0: - b2 = text[pos+1] if b2 & 0xc0 != 0x80: return error - o = ((b1&0x1f)<<6)|(b2&0x3f) + o = ((b1 & 0x1f) << 6) | (b2 & 0x3f) if o < 0x80: return error return o, pos+2 if lt < 3: return error if b1 & 0xf0 == 0xe0: - b2 = text[pos+1] if b2 & 0xc0 != 0x80: return error - b3 = text[pos+2] if b3 & 0xc0 != 0x80: return error - o = ((b1&0x0f)<<12)|((b2&0x3f)<<6)|(b3&0x3f) + o = ((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f) if o < 0x800: return error return o, pos+3 if lt < 4: return error if b1 & 0xf8 == 0xf0: - b2 = text[pos+1] if b2 & 0xc0 != 0x80: return error - b3 = text[pos+2] if b3 & 0xc0 != 0x80: return error - b4 = text[pos+2] if b4 & 0xc0 != 0x80: return error - o = ((b1&0x07)<<18)|((b2&0x3f)<<12)|((b3&0x3f)<<6)|(b4&0x3f) + o = ((b1 & 0x07) << 18) | ((b2 & 0x3f) << 12)|((b3 & 0x3f) << 6) | (b4 & 0x3f) if o < 0x10000: return error return o, pos+4 |