about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-10-26T15·56+0200
committerGitHub <noreply@github.com>2016-10-26T15·56+0200
commite02a1352c105caf0014ca3669ed379f2e7916038 (patch)
tree6f0193766b56cd0286f38c2528db9e891f625098 /src/libexpr/primops.cc
parent5c0bd51d49a5022e83c17301bd03d4ce53cca98a (diff)
parentf0fc3dd88b05866c4f6343d3c64ae1a4de4b8c9c (diff)
Merge pull request #1108 from dezgeg/fix-sigfpe
Fix SIGFPE from integer overflow during division
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 5ba9830423b0..4398cc951da2 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1516,10 +1516,16 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value &
     NixFloat f2 = state.forceFloat(*args[1], pos);
     if (f2 == 0) throw EvalError(format("division by zero, at %1%") % pos);
 
-    if (args[0]->type == tFloat || args[1]->type == tFloat)
+    if (args[0]->type == tFloat || args[1]->type == tFloat) {
         mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos));
-    else
-        mkInt(v, state.forceInt(*args[0], pos) / state.forceInt(*args[1], pos));
+    } else {
+        NixInt i1 = state.forceInt(*args[0], pos);
+        NixInt i2 = state.forceInt(*args[1], pos);
+        /* Avoid division overflow as it might raise SIGFPE. */
+        if (i1 == std::numeric_limits<NixInt>::min() && i2 == -1)
+            throw EvalError(format("overflow in integer division, at %1%") % pos);
+        mkInt(v, i1 / i2);
+    }
 }