aboutsummaryrefslogtreecommitdiff
path: root/src/func.c
diff options
context:
space:
mode:
authormistachkin <mistachkin@noemail.net>2013-09-06 20:30:53 +0000
committermistachkin <mistachkin@noemail.net>2013-09-06 20:30:53 +0000
commit9a5b271908e1f934e2cd3db2e62ad2a0eddbc624 (patch)
tree5099d5dd411dc09f941961039ab0eb10f7a88d9e /src/func.c
parentaeddf19e60ae9cbeaf272646b17e03c9344b9e68 (diff)
downloadsqlite-9a5b271908e1f934e2cd3db2e62ad2a0eddbc624.tar.gz
sqlite-9a5b271908e1f934e2cd3db2e62ad2a0eddbc624.zip
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
Diffstat (limited to 'src/func.c')
-rw-r--r--src/func.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/func.c b/src/func.c
index 31b96d4a9..7c6c6b26b 100644
--- a/src/func.c
+++ b/src/func.c
@@ -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
-** be losslessly converted into an integer, then make the conversion and
+** tointeger(X): If X is any value (integer, double, blob, or string) that
+** can be losslessly converted into an integer, then make the conversion and
** return the result. Otherwise, return NULL.
*/
static void tointegerFunc(
@@ -996,7 +996,16 @@ static void tointegerFunc(
int nBlob = sqlite3_value_bytes(argv[0]);
if( nBlob==sizeof(i64) ){
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);
}
}
@@ -1023,8 +1032,9 @@ static void tointegerFunc(
}
/*
-** toreal(X): If X can be losslessly converted into a real number, then
-** do so and return that real number. Otherwise return NULL.
+** toreal(X): If X is any value (integer, double, blob, or string) that can
+** be losslessly converted into a real number, then do so and return that
+** real number. Otherwise return NULL.
*/
#if defined(_MSC_VER)
#pragma optimize("", off)
@@ -1055,7 +1065,16 @@ static void torealFunc(
int nBlob = sqlite3_value_bytes(argv[0]);
if( nBlob==sizeof(double) ){
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);
}
}