ipld / ipld/py-ipld-dag

DAG-JSON `decode()` doesn't validate `{" /": ...}` namespace strictly

Open Beginner friendly
#35 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.