Skip to content

Commit ab0f561

Browse files
committed
fix: reject non-finite HydroDyn ballast scalars explicitly
1 parent a7b4ed5 commit ab0f561

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

‎src/pybmodes/io/_hydrodyn_ballast.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,19 @@ def _table(
141141

142142

143143
def _float(tok: str, what: str, path: pathlib.Path) -> float:
144+
"""Parse one deck scalar, rejecting anything non-finite.
145+
146+
A NaN would slip past every later range check (comparisons with NaN
147+
are false) and reach the platform mass matrix, so finiteness is
148+
checked here rather than left to the shared parser.
149+
"""
144150
try:
145-
return _parse_fortran_float(tok)
151+
value = _parse_fortran_float(tok)
146152
except ValueError as err:
147153
raise ValueError(f"Malformed {what} in {path}: {tok!r}") from err
154+
if not np.isfinite(value):
155+
raise ValueError(f"Non-finite {what} in {path}: {tok!r}")
156+
return value
148157

149158

150159
def _int(tok: str, what: str, path: pathlib.Path) -> int:

‎tests/test_hydrodyn_ballast.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,27 @@ def test_non_physical_section_is_rejected(self, tmp_path):
280280
with pytest.raises(ValueError, match="non-physical"):
281281
read_filled_ballast(path)
282282

283+
@pytest.mark.parametrize("token", ["nan", "NaN", "inf", "-Infinity"])
284+
@pytest.mark.parametrize("where", ["FillDens", "FillFSLoc", "joint", "PropD"])
285+
def test_non_finite_deck_scalars_are_rejected(self, tmp_path, token, where):
286+
joints = [(1, 0, 0, -10), (2, 0, 0, 0)]
287+
props = [(1, 2.0, 0.0)]
288+
fs, dens = "0.0", f"{RHO}"
289+
if where == "FillDens":
290+
dens = token
291+
elif where == "FillFSLoc":
292+
fs = token
293+
elif where == "joint":
294+
joints = [(1, 0, token, -10), (2, 0, 0, 0)]
295+
else:
296+
props = [(1, token, 0.0)]
297+
path = _deck(
298+
tmp_path, joints=joints, props=props,
299+
members=[(1, 1, 2, 1, 1)], fills=[f"1 1 {fs} {dens}"],
300+
)
301+
with pytest.raises(ValueError, match="(?i)non-finite|malformed"):
302+
read_filled_ballast(path)
303+
283304
@pytest.mark.parametrize("bad", [0.0, -1.0, float("nan"), float("inf")])
284305
def test_bad_water_density_is_rejected(self, tmp_path, bad):
285306
path = _vertical_column(tmp_path, fs=-8.0)

0 commit comments

Comments
 (0)