fix: reject NaN results from arithmetic operations#915
Open
He-Pin wants to merge 1 commit into
Open
Conversation
Motivation: sjsonnet silently produced NaN for modulo-by-zero (e.g. `42 % 0`) instead of throwing "division by zero" like go-jsonnet. The modulo operator lacked zero-divisor guards in 4 out of 6 evaluation paths, and the static optimizer constant-folded `x % 0` into Val.Num(NaN). Modification: - Evaluator: add rd==0 checks to evalBinaryOpNumNum, visitBinaryOpAsDouble, visitBinaryOp, and tryInlineArith for OP_% - Evaluator: add isNaN defense check to OP_/ in visitBinaryOp (catches NaN from stdlib math functions like std.sqrt(-1)) - StaticOptimizer: add r==0 guard to tryFoldAsDouble and main transform constant-folding for OP_% (consistent with OP_/) - Fix percent_mod_int5.jsonnet.golden to expect "division by zero" (verified against go-jsonnet binary) - Add regression tests for modulo-by-zero error cases Result: All modulo evaluation paths now reject division by zero, matching go-jsonnet behavior. NaN can no longer silently leak through.
be1f38a to
1c47422
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix: guard modulo-by-zero across all evaluation paths
Motivation:
sjsonnet silently produced NaN for modulo-by-zero (
42 % 0) instead of throwing "division by zero" like go-jsonnet. The modulo operator lacked zero-divisor guards in 4 out of 6 evaluation paths, and the static optimizer constant-foldedx % 0intoVal.Num(NaN).Modification:
rd == 0checks toevalBinaryOpNumNum,visitBinaryOpAsDouble,visitBinaryOp, andtryInlineArithforOP_%isNaNdefense check toOP_/invisitBinaryOp(catches NaN from unguarded stdlib math functions likestd.sqrt(-1))r == 0guard totryFoldAsDoubleand main-transform constant-folding forOP_%(consistent withOP_/)percent_mod_int5.jsonnet.goldento expect "division by zero" (verified against go-jsonnet binary)error.modulo_by_zeroanderror.modulo_by_zero_floatregression testsResult:
All modulo evaluation paths now reject division by zero, matching go-jsonnet behavior. NaN can no longer silently leak through any path.
References:
builtins.go:108-135:builtinDiv/builtinModulochecky.value == 0→ "Division by zero."builtins.go:1108-1116:makeDoubleCheckguards NaN/Infinity on all arithmetic results