@@ -820,23 +820,19 @@ static double sqlite3Fp10Convert2(u64 d, int p){
820820**
821821** Return positive if the result is a valid real number (or integer) and
822822** zero or negative if the string is empty or contains extraneous text.
823- ** More specifically:
823+ ** Lower bits of the return value contain addition information about the
824+ ** parse:
824825**
825- ** 2 => The input has a decimal point and/or eNNN clause
826- ** 1 => The input string is a pure integer
827- ** 0 => The input string is not well-formed
828- ** -1 => The input is not well-formed, but it does begin
829- ** with a well-formed integer prefix
830- ** -2 => The input is not well-formed, but it does begin
831- ** with a well-formed floating-point prefix with a
832- ** decimal point and/or eNNN clause
826+ ** bit 0 => Set for any valid input
827+ ** bit 1 => Input contains a decimal point or eNNN clause
828+ ** This bit is zero if the input is an integer
829+ ** bit 2 => The input is exactly 0.0, not an underflow from
830+ ** some value near zero
833831**
834- ** Return codes are organized as follows:
835- **
836- ** 1 or more => Input string is well-formed
837- ** 0 => No prefix of the input looks like a number
838- ** -1 or less => Some prefix of the input looks like a number
839- ** but the prefix is followed by extraneous text
832+ ** If the input contains a syntax error but begins with text that might
833+ ** be a valid number of some kind, then the result is negative. The
834+ ** result is only zero if no prefix of the input could be interpreted as
835+ ** a number.
840836**
841837** Leading and trailing whitespace is ignored. Valid numbers are in
842838** one of the formats below:
@@ -865,14 +861,13 @@ int sqlite3AtoF(const char *zIn, double *pResult){
865861 int neg = 0 ; /* True for a negative value */
866862 u64 s = 0 ; /* mantissa */
867863 int d = 0 ; /* Value is s * pow(10,d) */
868- int seenDigit = 0 ; /* true if any digits seen */
869- int seenFP = 0 ; /* True if we've seen a "." or a "e" */
864+ int mState = 0 ; /* 1: digit seen 2: fp 4: hard-zero */
870865 unsigned v ; /* Value of a single digit */
871866
872867 start_of_text :
873868 if ( (v = (unsigned )z [0 ] - '0' )< 10 ){
874869 parse_integer_part :
875- seenDigit = 1 ;
870+ mState = 1 ;
876871 s = v ;
877872 z ++ ;
878873 while ( (v = (unsigned )z [0 ] - '0' )< 10 ){
@@ -900,20 +895,21 @@ int sqlite3AtoF(const char *zIn, double *pResult){
900895 /* if decimal point is present */
901896 if ( * z == '.' ){
902897 z ++ ;
903- seenFP = 1 ;
904898 if ( sqlite3Isdigit (z [0 ]) ){
905- seenDigit = 1 ;
899+ mState | = 1 ;
906900 do {
907901 if ( s < ((LARGEST_INT64 - 9 )/10 ) ){
908902 s = s * 10 + z [0 ] - '0' ;
909903 d -- ;
910904 }
911905 z ++ ;
912906 }while ( sqlite3Isdigit (z [0 ]) );
907+ }else if ( mState == 0 ){
908+ * pResult = 0.0 ;
909+ return 0 ;
913910 }
914- }
915-
916- if ( !seenDigit ){
911+ mState |= 2 ;
912+ }else if ( mState == 0 ){
917913 * pResult = 0.0 ;
918914 return 0 ;
919915 }
@@ -937,7 +933,7 @@ int sqlite3AtoF(const char *zIn, double *pResult){
937933 if ( (v = (unsigned )z [0 ] - '0' )< 10 ){
938934 int exp = v ;
939935 z ++ ;
940- seenFP = 1 ;
936+ mState |= 2 ;
941937 while ( (v = (unsigned )z [0 ] - '0' )< 10 ){
942938 exp = exp < 10000 ? (exp * 10 + v ) : 10000 ;
943939 z ++ ;
@@ -950,21 +946,26 @@ int sqlite3AtoF(const char *zIn, double *pResult){
950946 }
951947
952948 /* Convert s*pow(10,d) into real */
953- * pResult = s ? sqlite3Fp10Convert2 (s ,d ) : 0.0 ;
949+ if ( s == 0 ){
950+ * pResult = 0.0 ;
951+ mState |= 4 ;
952+ }else {
953+ * pResult = sqlite3Fp10Convert2 (s ,d );
954+ }
954955 if ( neg ) * pResult = - * pResult ;
955956 assert ( !sqlite3IsNaN (* pResult ) );
956957
957958 /* return true if number and no extra non-whitespace characters after */
958959 if ( z [0 ]== 0 ){
959- return seenFP + 1 ;
960+ return mState ;
960961 }
961962 if ( sqlite3Isspace (z [0 ]) ){
962963 do { z ++ ; }while ( sqlite3Isspace (* z ) );
963964 if ( z [0 ]== 0 ){
964- return seenFP + 1 ;
965+ return mState ;
965966 }
966967 }
967- return -1 - seenFP ;
968+ return 0xfffffff0 | mState ;
968969#else
969970 return sqlite3Atoi64 (z , pResult , strlen (z ), SQLITE_UTF8 )== 0 ;
970971#endif /* SQLITE_OMIT_FLOATING_POINT */
0 commit comments