diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/test1.c | 2 | ||||
-rw-r--r-- | src/util.c | 11 |
2 files changed, 8 insertions, 5 deletions
diff --git a/src/test1.c b/src/test1.c index 5478a7254..98afb03e1 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1271,7 +1271,7 @@ static int sqlite3_mprintf_int64( return TCL_ERROR; } for(i=2; i<5; i++){ - if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ + if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } diff --git a/src/util.c b/src/util.c index 1f59a9f73..e883b1b9e 100644 --- a/src/util.c +++ b/src/util.c @@ -574,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int neg = 0; /* assume positive */ int i; int c = 0; - int nonNum = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ const char *zStart; const char *zEnd = zNum + length; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); @@ -585,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i<length && zNum[i]==0; i+=2){} nonNum = i<length; - zEnd = zNum+i+enc-3; + zEnd = &zNum[i^1]; zNum += (enc&1); } while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr; @@ -612,8 +612,11 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); - if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) - || i>19*incr || nonNum ){ + if( &zNum[i]<zEnd /* Extra bytes at the end */ + || (i==0 && zStart==zNum) /* No digits */ + || i>19*incr /* Too many digits */ + || nonNum /* UTF16 with high-order bytes non-zero */ + ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; |