DAG-JSON `decode()` doesn't validate `{" /": ...}` namespace strictly
- Dominant language
- Python
- Stars
- 13
- Forks
- 9
- PR merge metrics
- No merged PRs in 30d
Description
The DAG-JSON spec says any `{" /": ...}` that isn't a CID link or bytes is an error in strict mode. `_restore_from_json()` silently passes through unrecognized patterns.
### Problem
In `dag/codecs/dag_json.py`:
```python
def _restore_from_json(node: Any) -> Any:
if isinstance(node, dict):
if len(node) == 1 and _LINK_KEY in node:
link_value = node[_LINK_KEY]
if isinstance(link_value, str):
return _parse_cid_string(link_value)
if isinstance(link_value, dict) and len(link_value) == 1 and "bytes" in link_value:
return _base64_decode_no_pad(link_value["bytes"])
# ← Unrecognized {"/": ...} patterns are silently ignored!
return {k: _restore_from_json(v) for k, v in node.items()}
# ...
```
This means:
```python
# These should raise errors in strict mode, but don't:
decode(b'{" /": 123}') # Integer value
decode(b'{" /": [1, 2, 3]}') # Array value
decode(b'{" /": {"unknown": "value"}}') # Unrecognized dict
```
### Proposed Solution
Add strict validation:
```python
def _restore_from_json(node: Any, strict: bool = True) -> Any:
if isinstance(node, dict):
if len(node) == 1 and _LINK_KEY in node:
link_value = node[_LINK_KEY]
if isinstance(link_value, str):
return _parse_cid_string(link_value)
if isinstance(link_value, dict) and len(link_value) == 1 and "bytes" in link_value:
return _base64_decode_no_pad(link_value["bytes"])
if strict:
raise ValueError(
f'Invalid DAG-JSON: {{"/": ...}} must be a CID string or '
f'{{"bytes": "..."}}, got {type(link_value).__name__}'
)
return {k: _restore_from_json(v, strict) for k, v in node.items()}
# ...
```
Add a `strict` parameter to `DagJsonCodec.decode()`:
```python
def decode(self, data: bytes, strict: bool = True) -> IPLDNode:
raw = json.loads(data)
return _restore_from_json(raw, strict=strict)
```
### Related
- DAG-JSON spec: https://ipld.io/specs/codecs/dag-json/spec/
- File: `dag/codecs/dag_json.py`
Contributor guide
Research direction
Start in dag/codecs/dag_json.py by reading DagJsonCodec.decode() and _restore_from_json(), then compare their behavior with the DAG-JSON specification linked in the issue. Done means valid CID and bytes links still decode, while unrecognized {"/": ...} values raise in strict mode and recursive values honor the selected mode.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100