From 199a162f8cd23fa3b39071c22076c13498a5738e Mon Sep 17 00:00:00 2001 From: gsd Date: Sat, 14 Feb 2026 23:12:34 +0300 Subject: [PATCH] pb --- pb.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/pb.py b/pb.py index 5e83b6c..5afce44 100644 --- a/pb.py +++ b/pb.py @@ -385,6 +385,41 @@ def isInt(any): return True except: return False + +def _skip_group(buf, i, group_field, _depth=0, _max_depth=_MAX_NESTING_DEPTH): + """Пропускает все поля группы, начиная с позиции i, и возвращает новую позицию после end group.""" + if _depth > _max_depth: + raise ValueError("group nesting too deep") + b = memoryview(buf).toreadonly() if not isinstance(buf, bytearray) else buf + n = len(b) + while i < n: + key, i = _read_varint(b, i) + field = key >> 3 + wt = key & 7 + + if wt == 4: # end group + if field == group_field: + return i # группа закрыта, возвращаем позицию после ключа end group + else: + raise ValueError(f"mismatched end group: expected {group_field}, got {field}") + + # Пропускаем содержимое в зависимости от wire type + if wt == 0: # varint + _, i = _read_varint(b, i) + elif wt == 1: # 64-bit + i += 8 + elif wt == 2: # length-delimited + length, i = _read_varint(b, i) + if i + length > n: + raise ValueError("truncated length-delimited inside group") + i += length + elif wt == 3: # start group (вложенная) + i = _skip_group(b, i, field, _depth+1, _max_depth) + elif wt == 5: # 32-bit + i += 4 + else: + raise ValueError(f"unsupported wire type {wt} inside group") + raise ValueError("group not terminated") def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): if _depth > _max_depth: @@ -406,7 +441,12 @@ def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): spec = ns["fields"].get(field) if wt == 0: - v, i = _read_varint(b, i) + try: + v, i = _read_varint(b, i) + except Exception as rve: + print("key=",key, "i=",i, "field=",field, "wt=", wt,"spec=",spec, "ns-fields=", ns["fields"]) + raise rve + if spec: t = spec.get("type") if t in {"sint", "sint64"}: @@ -456,6 +496,13 @@ def decode(buf, schema=None, _depth=0, _max_depth=_MAX_NESTING_DEPTH): v = chunk else: v = chunk + elif wt == 3: + # Пропускаем всю группу, данные не сохраняем + i = _skip_group(b, i, field, _depth, _max_depth) + continue # ничего не добавляем в out + elif wt == 4: + # Если мы здесь, значит end group встречен не вовремя — ошибка + raise ValueError("unexpected end group") elif wt == 5: v, i = _read_fixed32(b, i) if spec: