Skip to content

Commit 269f9af

Browse files
sbryngelsonclaude
andcommitted
Harden readers and CLI error handling
- Validate Fortran record length is non-negative - Clip searchsorted indices to prevent out-of-bounds in assembly - Check silo_hdf5 directory exists before listing - Catch discover_format FileNotFoundError for clean CLI output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1153d88 commit 269f9af

3 files changed

Lines changed: 12 additions & 4 deletions

File tree

toolchain/mfc/viz/reader.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ def _read_record_endian(f, endian: str) -> bytes:
7373
if len(raw) < 4:
7474
raise EOFError("Unexpected end of file reading record marker")
7575
rec_len = struct.unpack(f'{endian}i', raw)[0]
76+
if rec_len < 0:
77+
raise ValueError(f"Invalid Fortran record length: {rec_len}")
7678
payload = f.read(rec_len)
7779
if len(payload) < rec_len:
7880
raise EOFError("Unexpected end of file reading record payload")
@@ -316,9 +318,9 @@ def assemble_from_proc_data( # pylint: disable=too-many-locals
316318

317319
# Place each processor's data using per-cell coordinate lookup
318320
for _rank, pd, x_cc, y_cc, z_cc in proc_centers:
319-
xi = np.searchsorted(global_x, np.round(x_cc, 12))
320-
yi = np.searchsorted(global_y, np.round(y_cc, 12)) if ndim >= 2 else np.array([0])
321-
zi = np.searchsorted(global_z, np.round(z_cc, 12)) if ndim >= 3 else np.array([0])
321+
xi = np.clip(np.searchsorted(global_x, np.round(x_cc, 12)), 0, nx - 1)
322+
yi = np.clip(np.searchsorted(global_y, np.round(y_cc, 12)), 0, ny - 1) if ndim >= 2 else np.array([0])
323+
zi = np.clip(np.searchsorted(global_z, np.round(z_cc, 12)), 0, nz - 1) if ndim >= 3 else np.array([0])
322324

323325
for vn, data in pd.variables.items():
324326
if vn not in global_vars:

toolchain/mfc/viz/silo_reader.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ def assemble_silo(
145145
_check_h5py()
146146

147147
base = os.path.join(case_dir, "silo_hdf5")
148+
if not os.path.isdir(base):
149+
raise FileNotFoundError(f"Silo-HDF5 directory not found: {base}")
148150
ranks: List[int] = []
149151
for entry in os.listdir(base):
150152
if entry.startswith("p") and entry[1:].isdigit():

toolchain/mfc/viz/viz.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ def viz(): # pylint: disable=too-many-locals,too-many-statements,too-many-branc
6363
if fmt_arg:
6464
fmt = fmt_arg
6565
else:
66-
fmt = discover_format(case_dir)
66+
try:
67+
fmt = discover_format(case_dir)
68+
except FileNotFoundError as exc:
69+
cons.print(f"[bold red]Error:[/bold red] {exc}")
70+
sys.exit(1)
6771

6872
cons.print(f"[bold]Format:[/bold] {fmt}")
6973

0 commit comments

Comments
 (0)