aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/json1.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-10-09 18:21:43 +0000
committerdrh <drh@noemail.net>2015-10-09 18:21:43 +0000
commit8deb4b8b172e7156d8ab9ea55135a0af204c0baf (patch)
treec071461d0489decd971be212f1b6cdb769ceda07 /ext/misc/json1.c
parent6cac258245624d7392c900dae57f9450b208b628 (diff)
downloadsqlite-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.c34
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: {