Compare commits

...
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 23e181283c Release 0.13.0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 20:06:09 -04:00
Dylan M. Taylor beb044bf35 Merge pull request #2494 from storytold/sonar-fix/path-cmd-hardening
security: validate CLI paths/args in dev tools (SonarCloud S2083/S8707/S8705)
2026-10-22 19:27:49 -04:00
Dylan M. Taylor ac2d7623e3 security: tighten readable/regular file checks in CLI tools 2026-10-22 19:18:41 -04:00
Dylan M. Taylor 3a9b35c687 ci: exclude dev tool scripts from SonarCloud coverage gate
tools/ and docs/ scripts aren't unit-tested; exclude them from coverage so the
new-code coverage gate doesn't block hardening-only changes.
2026-10-21 17:31:18 -04:00
Dylan M. Taylor 68d5118a9d security: validate CLI paths/args in dev tools (SonarCloud S2083/S8707/S8705/S7044)
Resolve and validate command-line path arguments before use, enforce HTTPS at
download sinks, and confirm path containment. Hardens local codegen/fetch tools
against path-traversal and command-argument-injection findings.
2026-10-21 17:13:05 -04:00
5 changed files with 71 additions and 36 deletions

No files matched your search

Generated
+33 -33
View File
@@ -3087,7 +3087,7 @@ dependencies = [
[[package]]
name = "lightcraft"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"chrono",
"eframe",
@@ -3113,7 +3113,7 @@ dependencies = [
[[package]]
name = "lightcraft-catalog"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"chrono",
"crc32fast",
@@ -3131,7 +3131,7 @@ dependencies = [
[[package]]
name = "lightcraft-cli"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"dhat",
"lightcraft-codecs",
@@ -3147,7 +3147,7 @@ dependencies = [
[[package]]
name = "lightcraft-codecs"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"avif-serialize",
"bytemuck",
@@ -3178,7 +3178,7 @@ dependencies = [
[[package]]
name = "lightcraft-color"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-geom",
"proptest",
@@ -3187,7 +3187,7 @@ dependencies = [
[[package]]
name = "lightcraft-denoise"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"faer-core",
"lightcraft-denoise-core",
@@ -3204,7 +3204,7 @@ dependencies = [
[[package]]
name = "lightcraft-denoise-core"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-raster",
"miniz_oxide 0.8.9",
@@ -3219,7 +3219,7 @@ dependencies = [
[[package]]
name = "lightcraft-develop"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-color",
"lightcraft-geom",
@@ -3231,7 +3231,7 @@ dependencies = [
[[package]]
name = "lightcraft-engine"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"ab_glyph",
"chrono",
@@ -3275,7 +3275,7 @@ dependencies = [
[[package]]
name = "lightcraft-faces"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-testkit",
"matrixmultiply",
@@ -3290,7 +3290,7 @@ dependencies = [
[[package]]
name = "lightcraft-fetch"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"log",
"rustls",
@@ -3301,7 +3301,7 @@ dependencies = [
[[package]]
name = "lightcraft-geocode"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"miniz_oxide 0.8.9",
"serde",
@@ -3309,7 +3309,7 @@ dependencies = [
[[package]]
name = "lightcraft-geom"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"proptest",
"serde",
@@ -3317,7 +3317,7 @@ dependencies = [
[[package]]
name = "lightcraft-gpu"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"bytemuck",
"lightcraft-color",
@@ -3337,7 +3337,7 @@ dependencies = [
[[package]]
name = "lightcraft-heif"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"heic-rs",
"rayon",
@@ -3345,14 +3345,14 @@ dependencies = [
[[package]]
name = "lightcraft-inpaint"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"rayon",
]
[[package]]
name = "lightcraft-lensdb"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-develop",
"lightcraft-geom",
@@ -3361,7 +3361,7 @@ dependencies = [
[[package]]
name = "lightcraft-mcp"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-codecs",
"lightcraft-engine",
@@ -3372,7 +3372,7 @@ dependencies = [
[[package]]
name = "lightcraft-merge"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-codecs",
"lightcraft-color",
@@ -3388,7 +3388,7 @@ dependencies = [
[[package]]
name = "lightcraft-meta"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"chrono",
"lightcraft-geom",
@@ -3401,7 +3401,7 @@ dependencies = [
[[package]]
name = "lightcraft-pipeline"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"image",
"lightcraft-color",
@@ -3419,7 +3419,7 @@ dependencies = [
[[package]]
name = "lightcraft-preview"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"jpeg-encoder",
"lightcraft-raster",
@@ -3431,7 +3431,7 @@ dependencies = [
[[package]]
name = "lightcraft-raster"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"libc",
"lightcraft-color",
@@ -3443,7 +3443,7 @@ dependencies = [
[[package]]
name = "lightcraft-raw"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"dhat",
"jpeg-encoder",
@@ -3467,7 +3467,7 @@ dependencies = [
[[package]]
name = "lightcraft-scenes"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"image",
"lightcraft-color",
@@ -3478,7 +3478,7 @@ dependencies = [
[[package]]
name = "lightcraft-segment"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"candle-core",
"candle-nn",
@@ -3492,7 +3492,7 @@ dependencies = [
[[package]]
name = "lightcraft-slideshow"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"lightcraft-raster",
"serde",
@@ -3501,15 +3501,15 @@ dependencies = [
[[package]]
name = "lightcraft-sysmem"
version = "0.12.0"
version = "0.13.0"
[[package]]
name = "lightcraft-testkit"
version = "0.12.0"
version = "0.13.0"
[[package]]
name = "lightcraft-tiff"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"proptest",
"serde",
@@ -3518,7 +3518,7 @@ dependencies = [
[[package]]
name = "lightcraft-ui-egui"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"craft-ui",
"egui",
@@ -3547,7 +3547,7 @@ dependencies = [
[[package]]
name = "lightcraft-web"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"crc32fast",
"eframe",
@@ -7017,7 +7017,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
[[package]]
name = "xtask"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"brotli",
"flate2",
+1 -1
View File
@@ -3,7 +3,7 @@ resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
[workspace.package]
version = "0.12.0"
version = "0.13.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.90"
+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]))