提交 c29390b0 编写于 作者: A Adam Bailey 提交者: Hauke Mehrtens

lua: fix integer overflow in LNUM patch

Safely detect integer overflow in try_addint() and try_subint().
Old code relied on undefined behavior, and recent versions of GCC on x86
optimized away the if-statements.
This caused integer overflow in Lua code instead of falling back to
floating-point numbers.
Signed-off-by: NAdam Bailey <aebailey@gmail.com>
(cherry picked from commit 3a2e7c30)
上级 503aa7f9
......@@ -1600,18 +1600,18 @@
+ * (and doing them).
+ */
+int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
+ lua_Integer v= ib+ic; /* may overflow */
+ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ }
+ else if (ib<0 && ic<0) { if (v >= 0) return 0; }
+ *r= v;
+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
+ if (ic>0) { if (ib > LUA_INTEGER_MAX - ic) return 0; /*overflow, use floats*/ }
+ else { if (ib < LUA_INTEGER_MIN - ic) return 0; }
+ *r = ib + ic;
+ return 1;
+}
+
+int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
+ lua_Integer v= ib-ic; /* may overflow */
+ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ }
+ else if (ib<0 && ic>0) { if (v >= 0) return 0; }
+ *r= v;
+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
+ if (ic>0) { if (ib < LUA_INTEGER_MIN + ic) return 0; /*overflow, use floats*/ }
+ else { if (ib > LUA_INTEGER_MAX + ic) return 0; }
+ *r = ib - ic;
+ return 1;
+}
+
......
......@@ -1589,18 +1589,18 @@
+ * (and doing them).
+ */
+int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
+ lua_Integer v= ib+ic; /* may overflow */
+ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ }
+ else if (ib<0 && ic<0) { if (v >= 0) return 0; }
+ *r= v;
+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
+ if (ic>0) { if (ib > LUA_INTEGER_MAX - ic) return 0; /*overflow, use floats*/ }
+ else { if (ib < LUA_INTEGER_MIN - ic) return 0; }
+ *r = ib + ic;
+ return 1;
+}
+
+int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
+ lua_Integer v= ib-ic; /* may overflow */
+ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ }
+ else if (ib<0 && ic>0) { if (v >= 0) return 0; }
+ *r= v;
+ /* Signed int overflow is undefined behavior, so catch it without causing it. */
+ if (ic>0) { if (ib < LUA_INTEGER_MIN + ic) return 0; /*overflow, use floats*/ }
+ else { if (ib > LUA_INTEGER_MAX + ic) return 0; }
+ *r = ib - ic;
+ return 1;
+}
+
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册