Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

hex and octal integer parsing #73

Open
wants to merge 2 commits into from

1 participant

@philtre

Added a few lines to enable parsing of hexadecimal and octal numbers. It needs a few more corrections, specifically to enable this functionality only when a certain parse flag is present.

@philtre philtre commented on the diff
JSONKit.m
@@ -1687,7 +1692,7 @@ static int jk_parse_number(JKParseState *parseState) {
parseState->token.value.ptrRange.length = sizeof(long long);
parseState->token.value.hash = (JK_HASH_INIT + parseState->token.value.type) + (JKHash)parseState->token.value.number.longLongValue;
} else {
- parseState->token.value.number.unsignedLongLongValue = strtoull((const char *)numberTempBuf, (char **)&endOfNumber, 10);
+ parseState->token.value.number.unsignedLongLongValue = strtoull((const char *)numberTempBuf, (char **)&endOfNumber, 0);
@philtre
philtre added a note

by passing 0 as base, strtoull will decide which base to use based on the prefix (hex if prefix is 0x and octal if prefix is 0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 22, 2012
  1. @philtre
Commits on Feb 23, 2012
  1. @philtre

    fixed octal number parsing bug

    philtre authored
This page is out of date. Refresh to see the latest.
Showing with 10 additions and 5 deletions.
  1. +10 −5 JSONKit.m
View
15 JSONKit.m
@@ -1632,12 +1632,11 @@ static int jk_parse_number(JKParseState *parseState) {
const unsigned char *numberStart = JK_AT_STRING_PTR(parseState);
const unsigned char *endOfBuffer = JK_END_STRING_PTR(parseState);
const unsigned char *atNumberCharacter = NULL;
- int numberState = JSONNumberStateWholeNumberStart, isFloatingPoint = 0, isNegative = 0, backup = 0;
+ int numberState = JSONNumberStateWholeNumberStart, isFloatingPoint = 0, isNegative = 0, backup = 0, isHex = 0, isOctal = 0;
size_t startingIndex = parseState->atIndex;
for(atNumberCharacter = numberStart; (JK_EXPECT_T(atNumberCharacter < endOfBuffer)) && (JK_EXPECT_T(!(JK_EXPECT_F(numberState == JSONNumberStateFinished) || JK_EXPECT_F(numberState == JSONNumberStateError)))); atNumberCharacter++) {
unsigned long currentChar = (unsigned long)(*atNumberCharacter), lowerCaseCC = currentChar | 0x20UL;
-
switch(numberState) {
case JSONNumberStateWholeNumberStart: if (currentChar == '-') { numberState = JSONNumberStateWholeNumberMinus; isNegative = 1; break; }
case JSONNumberStateWholeNumberMinus: if (currentChar == '0') { numberState = JSONNumberStateWholeNumberZero; break; }
@@ -1648,10 +1647,16 @@ static int jk_parse_number(JKParseState *parseState) {
case JSONNumberStateExponentPlusMinus:if(!((currentChar >= '0') && (currentChar <= '9'))) { /* XXX Add error message */ numberState = JSONNumberStateError; break; }
else { if(numberState == JSONNumberStateFractionalNumberStart) { numberState = JSONNumberStateFractionalNumber; }
else { numberState = JSONNumberStateExponent; } break; }
- case JSONNumberStateWholeNumberZero:
+ case JSONNumberStateWholeNumberZero: if ((currentChar >= '0') && (currentChar <= '7')) { numberState = JSONNumberStateWholeNumber; isOctal = 1; }
+ else if (lowerCaseCC == 'x') { numberState = JSONNumberStateWholeNumber; isHex = 1; break; }
+
case JSONNumberStateWholeNumber: if (currentChar == '.') { numberState = JSONNumberStateFractionalNumberStart; isFloatingPoint = 1; break; }
case JSONNumberStateFractionalNumber: if (lowerCaseCC == 'e') { numberState = JSONNumberStateExponentStart; isFloatingPoint = 1; break; }
- case JSONNumberStateExponent: if(!((currentChar >= '0') && (currentChar <= '9')) || (numberState == JSONNumberStateWholeNumberZero)) { numberState = JSONNumberStateFinished; backup = 1; break; }
+ case JSONNumberStateExponent: if(
+ !(
+ ((currentChar >= '0') && (currentChar <= '9') && !(isOctal && (currentChar >= '8'))) || (isHex && (lowerCaseCC >= 'a' && lowerCaseCC <='f'))
+ ) || (numberState == JSONNumberStateWholeNumberZero)
+ ) { numberState = JSONNumberStateFinished; backup = 1; break; }
break;
default: /* XXX Add error message */ numberState = JSONNumberStateError; break;
}
@@ -1687,7 +1692,7 @@ static int jk_parse_number(JKParseState *parseState) {
parseState->token.value.ptrRange.length = sizeof(long long);
parseState->token.value.hash = (JK_HASH_INIT + parseState->token.value.type) + (JKHash)parseState->token.value.number.longLongValue;
} else {
- parseState->token.value.number.unsignedLongLongValue = strtoull((const char *)numberTempBuf, (char **)&endOfNumber, 10);
+ parseState->token.value.number.unsignedLongLongValue = strtoull((const char *)numberTempBuf, (char **)&endOfNumber, 0);
@philtre
philtre added a note

by passing 0 as base, strtoull will decide which base to use based on the prefix (hex if prefix is 0x and octal if prefix is 0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
parseState->token.value.type = JKValueTypeUnsignedLongLong;
parseState->token.value.ptrRange.ptr = (const unsigned char *)&parseState->token.value.number.unsignedLongLongValue;
parseState->token.value.ptrRange.length = sizeof(unsigned long long);
Something went wrong with that request. Please try again.