diff options
author | drh <drh@noemail.net> | 2015-10-09 18:21:43 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-10-09 18:21:43 +0000 |
commit | 8deb4b8b172e7156d8ab9ea55135a0af204c0baf (patch) | |
tree | c071461d0489decd971be212f1b6cdb769ceda07 /ext/misc/json1.c | |
parent | 6cac258245624d7392c900dae57f9450b208b628 (diff) | |
download | sqlite-8deb4b8b172e7156d8ab9ea55135a0af204c0baf.tar.gz sqlite-8deb4b8b172e7156d8ab9ea55135a0af204c0baf.zip |
Fix the JSON1 extension so that it renders integers outside the range
of -9223372036854775808 to +9223372036854775807 as floating-point numbers.
FossilOrigin-Name: ae736e35fb59c9aed33a8c805cf2ecdee528051f
Diffstat (limited to 'ext/misc/json1.c')
-rw-r--r-- | ext/misc/json1.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c index f6fb2eafe..2962df25e 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -34,6 +34,11 @@ SQLITE_EXTENSION_INIT1 #define UNUSED_PARAM(X) (void)(X) +#ifndef LARGEST_INT64 +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) +#endif + /* ** Versions of isspace(), isalnum() and isdigit() to which it is safe ** to pass signed char values. @@ -478,18 +483,35 @@ static void jsonReturn( sqlite3_result_int(pCtx, 0); break; } - case JSON_REAL: { - double r = strtod(pNode->u.zJContent, 0); - sqlite3_result_double(pCtx, r); - break; - } case JSON_INT: { sqlite3_int64 i = 0; const char *z = pNode->u.zJContent; if( z[0]=='-' ){ z++; } - while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; } + while( z[0]>='0' && z[0]<='9' ){ + unsigned v = *(z++) - '0'; + if( i>=LARGEST_INT64/10 ){ + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; + if( v==9 ) goto int_as_real; + if( v==8 ){ + if( pNode->u.zJContent[0]=='-' ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + goto int_done; + }else{ + goto int_as_real; + } + } + } + i = i*10 + v; + } if( pNode->u.zJContent[0]=='-' ){ i = -i; } sqlite3_result_int64(pCtx, i); + int_done: + break; + int_as_real: /* fall through to real */; + } + case JSON_REAL: { + double r = strtod(pNode->u.zJContent, 0); + sqlite3_result_double(pCtx, r); break; } case JSON_STRING: { |