fix: harden graph JSON loading against corruption (#1536)

Wrap unguarded json.loads() in build_merge(), load_graph(), and
_read_json_file() so corrupted graph.json files produce an actionable
RuntimeError instead of an unhelpful JSONDecodeError traceback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
guy oron
2026-06-29 12:35:49 +03:00
committed by safishamsi
parent 93e8e445dd
commit 4a8d6bad97
3 changed files with 21 additions and 3 deletions
+7 -1
View File
@@ -210,7 +210,13 @@ def load_graph(path: Path) -> nx.Graph:
import json
from networkx.readwrite import json_graph
raw = json.loads(path.read_text(encoding="utf-8"))
try:
raw = json.loads(path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError) as exc:
raise RuntimeError(
f"Cannot read graph file {path}: {exc}. "
"Re-run 'graphify extract' to regenerate it."
) from exc
# Force directed so stored caller→callee direction survives the round-trip;
# mirrors serve.py and __main__.py (#1174).
raw = {**raw, "directed": True}
+7 -1
View File
@@ -746,7 +746,13 @@ def build_merge(
# NetworkX round-trip loses direction permanently (#760).
from graphify.security import check_graph_file_size_cap
check_graph_file_size_cap(graph_path)
data = json.loads(graph_path.read_text(encoding="utf-8"))
try:
data = json.loads(graph_path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError) as exc:
raise RuntimeError(
f"Cannot read {graph_path} for incremental merge: {exc}. "
"Delete the file and run a full rebuild."
) from exc
links_key = "links" if "links" in data else "edges"
existing_nodes = list(data.get("nodes", []))
existing_edges = list(data.get(links_key, []))
+7 -1
View File
@@ -274,7 +274,13 @@ def _read_json_file(path: str | Path) -> dict[str, Any]:
json_path = Path(path)
check_graph_file_size_cap(json_path)
data = json.loads(json_path.read_text(encoding="utf-8"))
try:
data = json.loads(json_path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError) as exc:
raise RuntimeError(
f"Cannot parse {json_path}: {exc}. "
"The file may be corrupted — re-run 'graphify extract'."
) from exc
if not isinstance(data, dict):
raise ValueError("diagnostic input must be a JSON object")
return data