Merge pull request #2494 from storytold/sonar-fix/path-cmd-hardening

security: validate CLI paths/args in dev tools (SonarCloud S2083/S8707/S8705)
This commit is contained in:
Dylan M. Taylor
2026-10-22 19:27:49 -04:00
committed by GitHub
3 changed files with 37 additions and 2 deletions
+16 -1
View File
@@ -1,6 +1,21 @@
#!/usr/bin/env python3
"""lcb.py FILE.jsonl — run control requests from a JSON-lines file ({"method":..., "params":...} or {"sleep": s})."""
import json, socket, sys, time
from pathlib import Path
def _jsonl_path(arg):
"""Resolve the CLI file argument; require an existing readable regular file."""
path = Path(arg).resolve()
if not path.is_file():
sys.exit(f"not a readable file: {arg}")
try:
with path.open("rb"):
pass
except OSError:
sys.exit(f"not a readable file: {arg}")
return path
def call(method, params):
s = socket.create_connection(("127.0.0.1", 7980), timeout=180)
s.sendall((json.dumps({"id": 1, "method": method, "params": params}) + "\n").encode())
@@ -10,7 +25,7 @@ def call(method, params):
if not c: break
buf += c
return json.loads(buf)
for line in open(sys.argv[1]):
for line in open(_jsonl_path(sys.argv[1])):
line = line.strip()
if not line or line.startswith("#"): continue
r = json.loads(line)
+1
View File
@@ -1,2 +1,3 @@
sonar.projectKey=storytold_lightcraft
sonar.organization=storytold
sonar.coverage.exclusions=**/tools/**,**/docs/**,**/examples/**
+20 -1
View File
@@ -19,6 +19,25 @@ import sys
import colour
import numpy as np
from scipy.optimize import minimize
from pathlib import Path
def _existing_dir(arg):
"""Resolve a directory CLI argument; require it to exist."""
path = Path(arg).resolve()
if not path.is_dir():
sys.exit(f"not a directory: {arg}")
return str(path)
def _out_path(arg):
"""Resolve an output path CLI argument; require its parent to exist."""
path = Path(arg).resolve()
if not path.parent.is_dir():
sys.exit(f"output directory does not exist: {arg}")
if path.exists() and not path.is_file():
sys.exit(f"output path is not a regular file: {arg}")
return str(path)
WL = np.arange(380, 781, 5)
D50 = colour.xy_to_XYZ(colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D50"])
@@ -119,4 +138,4 @@ def main(root, out):
if __name__ == "__main__":
if len(sys.argv) != 3:
sys.exit("usage: spectral_camera_table.py <rawtoaces-data checkout> <output .rs>")
main(sys.argv[1], sys.argv[2])
main(_existing_dir(sys.argv[1]), _out_path(sys.argv[2]))