When converting from a BLOB value in the tointeger() and toreal() SQL functions, make sure that endianness of the machine does not matter.

FossilOrigin-Name: 94c4cdc50d2753c859e494d53cebd09edd2e5663
This commit is contained in:
mistachkin
2013-09-06 20:30:53 +00:00
parent aeddf19e60
commit 9a5b271908
4 changed files with 114 additions and 121 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
C Additional\stest\scases\sfor\sthe\stointeger()\sand\storeal()\sSQL\sfunctions\swhen\sconverting\sfrom\sa\sBLOB. C When\sconverting\sfrom\sa\sBLOB\svalue\sin\sthe\stointeger()\sand\storeal()\sSQL\sfunctions,\smake\ssure\sthat\sendianness\sof\sthe\smachine\sdoes\snot\smatter.
D 2013-09-04T00:58:00.238 D 2013-09-06T20:30:53.365
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -175,7 +175,7 @@ F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94
F src/expr.c 4d89bd03a04fcdb5ff71d86b4e0cc7d3230797b8 F src/expr.c 4d89bd03a04fcdb5ff71d86b4e0cc7d3230797b8
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
F src/func.c ed294cd9437881cb7e2fbece2ea3389fc80c9fc7 F src/func.c 1f24db7b0f19e28170ffa5d5887b842e4d9a48d9
F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
@@ -562,7 +562,7 @@ F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test cd25cf605c5a345d038dc7b84232204c6a901c84 F test/func.test cd25cf605c5a345d038dc7b84232204c6a901c84
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
F test/func4.test 488c8deabf6a282e47aa5fcde782c6657e7625bc F test/func4.test 142490571f2e7ee6c3c5a65f24cad3f8342c02a2
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6
F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
@@ -1110,7 +1110,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 2982725e12715fba425a46ae024f317f031b6a54 P e1814452faa698946ef77f06a42665277ee59cc1
R c95b9007057313a186c90146fdfe015a R 134c8f8ed3149356b5cf5475063a56e8
U mistachkin U mistachkin
Z e95b03ef226de372c05086e066827ed5 Z b7db7274557533e42de3d2876d1a3f58
+1 -1
View File
@@ -1 +1 @@
e1814452faa698946ef77f06a42665277ee59cc1 94c4cdc50d2753c859e494d53cebd09edd2e5663
+25 -6
View File
@@ -966,8 +966,8 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
} }
/* /*
** tointeger(X): If X is any value (integer, double, or string) that can ** tointeger(X): If X is any value (integer, double, blob, or string) that
** be losslessly converted into an integer, then make the conversion and ** can be losslessly converted into an integer, then make the conversion and
** return the result. Otherwise, return NULL. ** return the result. Otherwise, return NULL.
*/ */
static void tointegerFunc( static void tointegerFunc(
@@ -996,7 +996,16 @@ static void tointegerFunc(
int nBlob = sqlite3_value_bytes(argv[0]); int nBlob = sqlite3_value_bytes(argv[0]);
if( nBlob==sizeof(i64) ){ if( nBlob==sizeof(i64) ){
i64 iVal; i64 iVal;
memcpy(&iVal, zBlob, sizeof(i64)); if( SQLITE_BIGENDIAN ){
int i;
unsigned char *zBlobRev = contextMalloc(context, nBlob);
if( !zBlobRev ) break;
for(i=0; i<nBlob; i++) zBlobRev[i] = zBlob[nBlob-1-i];
memcpy(&iVal, zBlobRev, sizeof(i64));
sqlite3_free(zBlobRev);
}else{
memcpy(&iVal, zBlob, sizeof(i64));
}
sqlite3_result_int64(context, iVal); sqlite3_result_int64(context, iVal);
} }
} }
@@ -1023,8 +1032,9 @@ static void tointegerFunc(
} }
/* /*
** toreal(X): If X can be losslessly converted into a real number, then ** toreal(X): If X is any value (integer, double, blob, or string) that can
** do so and return that real number. Otherwise return NULL. ** be losslessly converted into a real number, then do so and return that
** real number. Otherwise return NULL.
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma optimize("", off) #pragma optimize("", off)
@@ -1055,7 +1065,16 @@ static void torealFunc(
int nBlob = sqlite3_value_bytes(argv[0]); int nBlob = sqlite3_value_bytes(argv[0]);
if( nBlob==sizeof(double) ){ if( nBlob==sizeof(double) ){
double rVal; double rVal;
memcpy(&rVal, zBlob, sizeof(double)); if( SQLITE_LITTLEENDIAN ){
int i;
unsigned char *zBlobRev = contextMalloc(context, nBlob);
if( !zBlobRev ) break;
for(i=0; i<nBlob; i++) zBlobRev[i] = zBlob[nBlob-1-i];
memcpy(&rVal, zBlobRev, sizeof(double));
sqlite3_free(zBlobRev);
}else{
memcpy(&rVal, zBlob, sizeof(double));
}
sqlite3_result_double(context, rVal); sqlite3_result_double(context, rVal);
} }
} }
+81 -107
View File
@@ -667,115 +667,89 @@ for {set i 0} {$i < 10} {incr i} {
} }
} }
proc swapHexBytes { value } { do_execsql_test func4-6.2.1 {
if {[string length $value] % 2 != 0} { SELECT tointeger(x'0102030405060708');
error "value \"$value\" must have an even number of characters" } {578437695752307201}
} do_execsql_test func4-6.2.2 {
if {![string is xdigit -strict $value]} then { SELECT tointeger(x'0807060504030201');
error "value \"$value\" must contain only hexadecimal digits" } {72623859790382856}
}
join [lreverse [regexp -all -inline {.{2}} $value]] ""
}
proc swapIntegerHexBytes { value } {
if {![info exists ::tcl_platform(byteOrder)] || \
$::tcl_platform(byteOrder) eq "littleEndian"} {
return $value
}
return [swapHexBytes $value]
}
proc swapDoubleHexBytes { value } {
if {![info exists ::tcl_platform(byteOrder)] || \
$::tcl_platform(byteOrder) ne "littleEndian"} {
return $value
}
return [swapHexBytes $value]
}
do_execsql_test func4-6.2.1 [subst {
SELECT tointeger(x'[swapIntegerHexBytes 0102030405060708]');
}] {578437695752307201}
do_execsql_test func4-6.2.2 [subst {
SELECT tointeger(x'[swapIntegerHexBytes 0807060504030201]');
}] {72623859790382856}
ifcapable floatingpoint { ifcapable floatingpoint {
do_execsql_test func4-6.3.1 [subst { do_execsql_test func4-6.3.1 {
SELECT toreal(x'[swapDoubleHexBytes ffefffffffffffff]'); SELECT toreal(x'ffefffffffffffff');
}] {-1.7976931348623157e+308} } {-1.7976931348623157e+308}
do_execsql_test func4-6.3.2 [subst { do_execsql_test func4-6.3.2 {
SELECT toreal(x'[swapDoubleHexBytes 8010000000000000]'); SELECT toreal(x'8010000000000000');
}] {-2.2250738585072014e-308} } {-2.2250738585072014e-308}
do_execsql_test func4-6.3.3 [subst { do_execsql_test func4-6.3.3 {
SELECT toreal(x'[swapDoubleHexBytes c000000000000000]'); SELECT toreal(x'c000000000000000');
}] {-2.0} } {-2.0}
do_execsql_test func4-6.3.4 [subst { do_execsql_test func4-6.3.4 {
SELECT toreal(x'[swapDoubleHexBytes bff0000000000000]'); SELECT toreal(x'bff0000000000000');
}] {-1.0} } {-1.0}
do_execsql_test func4-6.3.5 [subst { do_execsql_test func4-6.3.5 {
SELECT toreal(x'[swapDoubleHexBytes 8000000000000000]'); SELECT toreal(x'8000000000000000');
}] {-0.0} } {-0.0}
do_execsql_test func4-6.3.6 [subst { do_execsql_test func4-6.3.6 {
SELECT toreal(x'[swapDoubleHexBytes 0000000000000000]'); SELECT toreal(x'0000000000000000');
}] {0.0} } {0.0}
do_execsql_test func4-6.3.7 [subst { do_execsql_test func4-6.3.7 {
SELECT toreal(x'[swapDoubleHexBytes 3ff0000000000000]'); SELECT toreal(x'3ff0000000000000');
}] {1.0} } {1.0}
do_execsql_test func4-6.3.8 [subst { do_execsql_test func4-6.3.8 {
SELECT toreal(x'[swapDoubleHexBytes 4000000000000000]'); SELECT toreal(x'4000000000000000');
}] {2.0} } {2.0}
do_execsql_test func4-6.3.9 [subst { do_execsql_test func4-6.3.9 {
SELECT toreal(x'[swapDoubleHexBytes 0010000000000000]'); SELECT toreal(x'0010000000000000');
}] {2.2250738585072014e-308} } {2.2250738585072014e-308}
do_execsql_test func4-6.3.10 [subst { do_execsql_test func4-6.3.10 {
SELECT toreal(x'[swapDoubleHexBytes 7fefffffffffffff]'); SELECT toreal(x'7fefffffffffffff');
}] {1.7976931348623157e+308} } {1.7976931348623157e+308}
do_execsql_test func4-6.3.11 [subst { do_execsql_test func4-6.3.11 {
SELECT toreal(x'[swapDoubleHexBytes 8000000000000001]'); SELECT toreal(x'8000000000000001');
}] {-5e-324} } {-5e-324}
do_execsql_test func4-6.3.12 [subst { do_execsql_test func4-6.3.12 {
SELECT toreal(x'[swapDoubleHexBytes 800fffffffffffff]'); SELECT toreal(x'800fffffffffffff');
}] {-2.225073858507201e-308} } {-2.225073858507201e-308}
do_execsql_test func4-6.3.13 [subst { do_execsql_test func4-6.3.13 {
SELECT toreal(x'[swapDoubleHexBytes 0000000000000001]'); SELECT toreal(x'0000000000000001');
}] {5e-324} } {5e-324}
do_execsql_test func4-6.3.14 [subst { do_execsql_test func4-6.3.14 {
SELECT toreal(x'[swapDoubleHexBytes 000fffffffffffff]'); SELECT toreal(x'000fffffffffffff');
}] {2.225073858507201e-308} } {2.225073858507201e-308}
do_execsql_test func4-6.3.15 [subst { do_execsql_test func4-6.3.15 {
SELECT toreal(x'[swapDoubleHexBytes fff0000000000000]'); SELECT toreal(x'fff0000000000000');
}] {-Inf} } {-Inf}
do_execsql_test func4-6.3.16 [subst { do_execsql_test func4-6.3.16 {
SELECT toreal(x'[swapDoubleHexBytes 7ff0000000000000]'); SELECT toreal(x'7ff0000000000000');
}] {Inf} } {Inf}
do_execsql_test func4-6.3.17 [subst { do_execsql_test func4-6.3.17 {
SELECT toreal(x'[swapDoubleHexBytes fff8000000000000]'); SELECT toreal(x'fff8000000000000');
}] {{}} } {{}}
do_execsql_test func4-6.3.18 [subst { do_execsql_test func4-6.3.18 {
SELECT toreal(x'[swapDoubleHexBytes fff0000000000001]'); SELECT toreal(x'fff0000000000001');
}] {{}} } {{}}
do_execsql_test func4-6.3.19 [subst { do_execsql_test func4-6.3.19 {
SELECT toreal(x'[swapDoubleHexBytes fff7ffffffffffff]'); SELECT toreal(x'fff7ffffffffffff');
}] {{}} } {{}}
do_execsql_test func4-6.3.20 [subst { do_execsql_test func4-6.3.20 {
SELECT toreal(x'[swapDoubleHexBytes 7ff0000000000001]'); SELECT toreal(x'7ff0000000000001');
}] {{}} } {{}}
do_execsql_test func4-6.3.21 [subst { do_execsql_test func4-6.3.21 {
SELECT toreal(x'[swapDoubleHexBytes 7ff7ffffffffffff]'); SELECT toreal(x'7ff7ffffffffffff');
}] {{}} } {{}}
do_execsql_test func4-6.3.22 [subst { do_execsql_test func4-6.3.22 {
SELECT toreal(x'[swapDoubleHexBytes fff8000000000001]'); SELECT toreal(x'fff8000000000001');
}] {{}} } {{}}
do_execsql_test func4-6.3.23 [subst { do_execsql_test func4-6.3.23 {
SELECT toreal(x'[swapDoubleHexBytes ffffffffffffffff]'); SELECT toreal(x'ffffffffffffffff');
}] {{}} } {{}}
do_execsql_test func4-6.3.24 [subst { do_execsql_test func4-6.3.24 {
SELECT toreal(x'[swapDoubleHexBytes 7ff8000000000000]'); SELECT toreal(x'7ff8000000000000');
}] {{}} } {{}}
do_execsql_test func4-6.3.25 [subst { do_execsql_test func4-6.3.25 {
SELECT toreal(x'[swapDoubleHexBytes 7fffffffffffffff]'); SELECT toreal(x'7fffffffffffffff');
}] {{}} } {{}}
} }
set tcl_precision $saved_tcl_precision set tcl_precision $saved_tcl_precision