From 42d4ef2acc3e15e5bfa7e80c2ae99c11593ee000 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Tue, 26 Jun 2007 11:13:25 +0000 Subject: [PATCH] Fix for #2444: Avoid SIGFPE on 64-bit platforms when evaluating expressions like ((1<<63)/-1). (CVS 4130) FossilOrigin-Name: c6dfd9e43449b0b3528281d9e2e4971c6ba86ab5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 12 +++++++++++- test/expr.test | 5 ++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3d35f81589..86b808f71c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sunused\sEXTSRC\svariable\sfrom\sthe\snon-configure\smakefile.\s(CVS\s4129) -D 2007-06-26T10:56:40 +C Fix\sfor\s#2444:\sAvoid\sSIGFPE\son\s64-bit\splatforms\swhen\sevaluating\sexpressions\slike\s((1<<63)/-1).\s(CVS\s4130) +D 2007-06-26T11:13:26 F Makefile.in 7f7485a4cc039476a42e534b3f26ec90e2f9753e F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -138,7 +138,7 @@ F src/update.c 6b10becb6235ea314ed245fbfbf8b38755e3166e F src/utf.c 01b2aba02b10d12903e9e1ff897215c9faf6b662 F src/util.c 9e81d417fc60bd2fe156f8f2317aa4845bc6cc90 F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef -F src/vdbe.c 99f53a0aa8db4fe7fa867a24446bdd7deed191c4 +F src/vdbe.c b01ec63187c6ccc53f4d4520f58bb3e2b4c40409 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h 7d2bf163d6d4e815724a457f2216dd8e38c3955c F src/vdbeapi.c 7930b9a188ab385287ca3eb3840af7225cb43549 @@ -226,7 +226,7 @@ F test/enc3.test 9331988b9d72decec96995c90637e87b00d747a5 F test/exclusive.test 5bc520ba366ae3d242420af025ab64d465b04706 F test/exclusive2.test 3496656375dc88e97d704c2d5d2c93d626cb7104 F test/exclusive3.test 0e49c35b7e7cb8e7280b4ce3f0359d30b207d2ff -F test/expr.test a4dc0855b86ba0daeef47f3dd4cf394eda2bd0ac +F test/expr.test b8d63779b043dff06580fe4f3d85e5bebd067957 F test/filefmt.test 053b622009fbbb74dd37921ffad374d852c13cd8 F test/fkey1.test dcb4f28eb22d5141f15161d6bdca9a4f58c95729 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -516,7 +516,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P c349cf942534357955f80fc2aa8c96206af97b78 -R e274bb8f2d1469809dfb33a3f5436cb7 +P bbdcf372c6f2144a62fba742b3f4bd6b2fe58593 +R 485893afc93c6a008cca6e703f7615a7 U danielk1977 -Z df0dd041a3eb4ee7dd57d773a2b1890f +Z a1b4c3aea76673647cfd46dd712e2aca diff --git a/manifest.uuid b/manifest.uuid index ef1fbfa7fa..f912d8bb84 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbdcf372c6f2144a62fba742b3f4bd6b2fe58593 \ No newline at end of file +c6dfd9e43449b0b3528281d9e2e4971c6ba86ab5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c2c93c5269..ec8148ce7e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.632 2007/06/26 00:37:28 drh Exp $ +** $Id: vdbe.c,v 1.633 2007/06/26 11:13:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1153,11 +1153,20 @@ case OP_Remainder: { /* same as TK_REM, no-push */ case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0 ) goto divide_by_zero; + /* Dividing the largest possible negative 64-bit integer (1<<63) by + ** -1 returns an integer to large to store in a 64-bit data-type. On + ** some architectures, the value overflows to (1<<63). On others, + ** a SIGFPE is issued. The following statement normalizes this + ** behaviour so that all architectures behave as if integer + ** overflow occured. + */ + if( a==-1 && b==(1<<63) ) a = 1; b /= a; break; } default: { if( a==0 ) goto divide_by_zero; + if( a==-1 ) a = 1; b %= a; break; } @@ -1184,6 +1193,7 @@ case OP_Remainder: { /* same as TK_REM, no-push */ i64 ia = (i64)a; i64 ib = (i64)b; if( ia==0 ) goto divide_by_zero; + if( ia==-1 ) ia = 1; b = ib % ia; break; } diff --git a/test/expr.test b/test/expr.test index e6a057b90f..b619f337f8 100644 --- a/test/expr.test +++ b/test/expr.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # -# $Id: expr.test,v 1.56 2007/06/25 17:28:02 drh Exp $ +# $Id: expr.test,v 1.57 2007/06/26 11:13:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -139,6 +139,9 @@ test_expr expr-1.103 {i1=0} {(-2147483648.0 % -1)} 0.0 test_expr expr-1.104 {i1=0} {(-9223372036854775808.0 % -1)} 0.0 test_expr expr-1.105 {i1=0} {(-9223372036854775808.0 / -1)>1} 1 +test_expr expr-1.106 {i1=0} {(1<<63)/-1} -9223372036854775808 +test_expr expr-1.107 {i1=0} {(1<<63)%-1} 0 + test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782