mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 22:23:27 +00:00
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: Adam Bailey <aebailey@gmail.com>
This commit is contained in:
parent
c170fc78ba
commit
3a2e7c30d3
@ -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;
|
||||
+}
|
||||
+
|
||||
|
Loading…
Reference in New Issue
Block a user