fix: harden DGR-002 protocol bounds
This commit is contained in:
@@ -99,7 +99,12 @@ def compress_activation(body: bytes, policy: CompressionPolicy) -> CompressionRe
|
||||
return CompressionResult(candidate, "zstd", len(body), len(candidate), time.monotonic() - started, "compressed")
|
||||
|
||||
|
||||
def decompress_activation(body: bytes, encoding: str | None) -> CompressionResult:
|
||||
def decompress_activation(
|
||||
body: bytes,
|
||||
encoding: str | None,
|
||||
*,
|
||||
max_output_bytes: int | None = None,
|
||||
) -> CompressionResult:
|
||||
"""Decode a modern zstd body or preserve a legacy raw body with metrics."""
|
||||
started = time.monotonic()
|
||||
if not encoding:
|
||||
@@ -110,8 +115,23 @@ def decompress_activation(body: bytes, encoding: str | None) -> CompressionResul
|
||||
import zstandard as zstd
|
||||
except ImportError as exc:
|
||||
raise ValueError("zstd support is unavailable") from exc
|
||||
if max_output_bytes is not None and max_output_bytes < 0:
|
||||
raise ValueError("max_output_bytes must be non-negative")
|
||||
try:
|
||||
raw = zstd.ZstdDecompressor().decompress(body)
|
||||
if max_output_bytes is None:
|
||||
raw = zstd.ZstdDecompressor().decompress(body)
|
||||
else:
|
||||
# Cap both decoder window allocation and bytes read. zstandard's
|
||||
# max_window_size unit is KiB.
|
||||
max_window_kib = max(1024, (max_output_bytes + 1023) // 1024)
|
||||
decompressor = zstd.ZstdDecompressor(max_window_size=max_window_kib)
|
||||
# `decompress(max_output_size=...)` may trust a frame's advertised
|
||||
# content size. A bounded stream read enforces the limit regardless
|
||||
# of frame metadata and detects trailing expansion with one byte.
|
||||
with decompressor.stream_reader(body) as reader:
|
||||
raw = reader.read(max_output_bytes + 1)
|
||||
if len(raw) > max_output_bytes:
|
||||
raise ValueError("zstd activation body exceeds its output limit")
|
||||
except zstd.ZstdError as exc:
|
||||
raise ValueError("invalid zstd activation body") from exc
|
||||
return CompressionResult(raw, "zstd", len(body), len(raw), time.monotonic() - started, "decompressed")
|
||||
|
||||
Reference in New Issue
Block a user