fix: check the meta key budget before scanning every key
The key-count cap exists to catch a whole request body dumped into meta. That is exactly the shape where the per-key regex runs tens of thousands of times before the real reason surfaces, so the cheap check goes first. Also correct two stale docstrings: postgres.py still claimed 22 columns (it is 24), and _canonical_meta_json promised to raise on non-finite floats. It is evaluated inside _record's degradation try, so the real outcome is a warning plus a dropped row -- never an error the caller sees. What the gate actually buys us is the SQLite side, whose meta is a TEXT column that would happily store a literal NaN.
This commit is contained in:
@@ -42,8 +42,13 @@ def _canonical_meta_json(meta: Mapping[str, Any]) -> str:
|
||||
|
||||
`allow_nan=False` 是**第二道闸**(主防线是 `types.validate_caller_dimensions`
|
||||
在公共入口的校验): `json.dumps` 默认把 `nan` 写成裸 `NaN` 字面量,那不是合法
|
||||
JSON,PG 的 JSONB 会拒收;而写入失败会被 `_record` 的降级 try 吞成 warning,
|
||||
等于把调用方的输入错误转化成静默丢遥测。宁可在这里显式抛。
|
||||
JSON。这道闸真正的价值在 **SQLite 侧**——PG 的 JSONB 本来就会拒收 `NaN`,而
|
||||
SQLite 的 `meta` 是 TEXT 列**不做任何 JSON 校验**,没有这道闸就会把 `NaN`
|
||||
这种非法 JSON 静默存进去,污染后续一切按 JSON 解析 meta 的分析。
|
||||
|
||||
注意它抛出的 `ValueError` **不会外泄给调用方**: 本函数在 `_record` 的降级
|
||||
`try` 内被求值,异常会被那里的 `except Exception` 接住 → 落 warning、整行
|
||||
遥测丢弃。即入口失守时的真实结果是"警告 + 丢一行",不是"报错给调用方"。
|
||||
"""
|
||||
if not meta:
|
||||
return "{}"
|
||||
|
||||
Reference in New Issue
Block a user