123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- Index: yajl_parse.h
- ===================================================================
- --- yajl_parse.h (revision 767861)
- +++ yajl_parse.h (revision 767862)
- @@ -75,6 +75,7 @@
- int (* yajl_null)(void * ctx);
- int (* yajl_boolean)(void * ctx, int boolVal);
- int (* yajl_integer)(void * ctx, long long integerVal);
- + int (* yajl_uinteger)(void * ctx, unsigned long long uintegerVal);
- int (* yajl_double)(void * ctx, double doubleVal);
- /** A callback which passes the string representation of the number
- * back to the client. Will be used for all numbers when present */
- Index: yajl_parser.c
- ===================================================================
- --- yajl_parser.c (revision 767861)
- +++ yajl_parser.c (revision 767862)
- @@ -30,6 +30,7 @@
- #include <math.h>
-
- #define MAX_VALUE_TO_MULTIPLY ((LLONG_MAX / 10) + (LLONG_MAX % 10))
- +#define MAX_UVALUE_TO_MULTIPLY ((ULLONG_MAX / 10) + (ULLONG_MAX % 10))
-
- /* same semantics as strtol */
- long long
- @@ -57,6 +58,35 @@
- return sign * ret;
- }
-
- +unsigned long long
- +yajl_parse_uinteger(const unsigned char *number, unsigned int length)
- +{
- + unsigned long long ret = 0;
- + const unsigned char *pos = number;
- + if (*pos == '-') {
- + errno = ERANGE;
- + return 0;
- + }
- +
- + if (*pos == '+') { pos++; }
- +
- + while (pos < number + length) {
- + if ( ret > MAX_UVALUE_TO_MULTIPLY ) {
- + errno = ERANGE;
- + return ULLONG_MAX;
- + }
- + ret *= 10ull;
- + if (ULLONG_MAX - ret < (unsigned long long)(*pos - '0')) {
- + errno = ERANGE;
- + return ULLONG_MAX;
- + }
- + ret += (unsigned long long)(*pos++ - '0');
- + }
- +
- + return ret;
- +}
- +
- +
- unsigned char *
- yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
- size_t jsonTextLen, int verbose)
- @@ -283,6 +313,37 @@
- if ((i == LLONG_MIN || i == LLONG_MAX) &&
- errno == ERANGE)
- {
- + unsigned long long ui = 0;
- + int parsing_failed = 1;
- + if (hand->callbacks->yajl_uinteger) {
- + errno = 0;
- + ui = yajl_parse_uinteger(buf, bufLen);
- + if ((ui == 0 || ui == ULLONG_MAX) && errno == ERANGE)
- + parsing_failed = 1;
- + else
- + parsing_failed = 0;
- + }
- +
- + if (parsing_failed) {
- + yajl_bs_set(hand->stateStack,
- + yajl_state_parse_error);
- + hand->parseError = "integer overflow" ;
- + /* try to restore error offset */
- + if (*offset >= bufLen) *offset -= bufLen;
- + else *offset = 0;
- + goto around_again;
- + } else {
- + _CC_CHK(hand->callbacks->yajl_uinteger(hand->ctx,
- + ui));
- + }
- + } else {
- + _CC_CHK(hand->callbacks->yajl_integer(hand->ctx,
- + i));
- + }
- + } else if (hand->callbacks->yajl_uinteger) {
- + unsigned long long ui = 0;
- + ui = yajl_parse_uinteger(buf, bufLen);
- + if ((ui == 0 || ui == ULLONG_MAX) && errno == ERANGE) {
- yajl_bs_set(hand->stateStack,
- yajl_state_parse_error);
- hand->parseError = "integer overflow" ;
- @@ -291,8 +352,8 @@
- else *offset = 0;
- goto around_again;
- }
- - _CC_CHK(hand->callbacks->yajl_integer(hand->ctx,
- - i));
- + _CC_CHK(hand->callbacks->yajl_uinteger(hand->ctx,
- + ui));
- }
- }
- break;
- Index: yajl_tree.c
- ===================================================================
- --- yajl_tree.c (revision 767861)
- +++ yajl_tree.c (revision 767862)
- @@ -318,6 +318,14 @@
-
- endptr = NULL;
- errno = 0;
- + v->u.number.ui = yajl_parse_uinteger((const unsigned char *) v->u.number.r,
- + strlen(v->u.number.r));
- +
- + if ((errno == 0) && (endptr != NULL) && (*endptr == 0))
- + v->u.number.flags |= YAJL_NUMBER_UINT_VALID;
- +
- + endptr = NULL;
- + errno = 0;
- v->u.number.d = strtod(v->u.number.r, &endptr);
- if ((errno == 0) && (endptr != NULL) && (*endptr == 0))
- v->u.number.flags |= YAJL_NUMBER_DOUBLE_VALID;
- @@ -409,6 +417,7 @@
- /* null = */ handle_null,
- /* boolean = */ handle_boolean,
- /* integer = */ NULL,
- + /* unsigned integer = */ NULL,
- /* double = */ NULL,
- /* number = */ handle_number,
- /* string = */ handle_string,
- Index: yajl_parser.h
- ===================================================================
- --- yajl_parser.h (revision 767861)
- +++ yajl_parser.h (revision 767862)
- @@ -74,5 +74,8 @@
- long long
- yajl_parse_integer(const unsigned char *number, unsigned int length);
-
- +unsigned long long
- +yajl_parse_uinteger(const unsigned char *number, unsigned int length);
-
- +
- #endif
- Index: yajl_tree.h
- ===================================================================
- --- yajl_tree.h (revision 767861)
- +++ yajl_tree.h (revision 767862)
- @@ -50,6 +50,7 @@
-
- #define YAJL_NUMBER_INT_VALID 0x01
- #define YAJL_NUMBER_DOUBLE_VALID 0x02
- +#define YAJL_NUMBER_UINT_VALID 0x04
-
- /** A pointer to a node in the parse tree */
- typedef struct yajl_val_s * yajl_val;
- @@ -73,6 +74,7 @@
- char * string;
- struct {
- long long i; /*< integer value, if representable. */
- + unsigned long long ui; /*< unsigned integer value, if representable. */
- double d; /*< double value, if representable. */
- /** Signals whether the \em i and \em d members are
- * valid. See \c YAJL_NUMBER_INT_VALID and
- @@ -145,6 +147,7 @@
- #define YAJL_IS_STRING(v) (((v) != NULL) && ((v)->type == yajl_t_string))
- #define YAJL_IS_NUMBER(v) (((v) != NULL) && ((v)->type == yajl_t_number))
- #define YAJL_IS_INTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_INT_VALID))
- +#define YAJL_IS_UINTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_UINT_VALID))
- #define YAJL_IS_DOUBLE(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_DOUBLE_VALID))
- #define YAJL_IS_OBJECT(v) (((v) != NULL) && ((v)->type == yajl_t_object))
- #define YAJL_IS_ARRAY(v) (((v) != NULL) && ((v)->type == yajl_t_array ))
- @@ -168,6 +171,10 @@
- * check type first, perhaps using YAJL_IS_INTEGER */
- #define YAJL_GET_INTEGER(v) ((v)->u.number.i)
-
- +/** Get the 64bit (unsigned long long) unsigned integer representation of a number. You should
- + * check type first, perhaps using YAJL_IS_UINTEGER */
- +#define YAJL_GET_UINTEGER(v) ((v)->u.number.ui)
- +
- /** Get a pointer to a yajl_val_object or NULL if the value is not an object. */
- #define YAJL_GET_OBJECT(v) (YAJL_IS_OBJECT(v) ? &(v)->u.object : NULL)
-
- Index: yajl_gen.c
- ===================================================================
- --- yajl_gen.c (revision 767861)
- +++ yajl_gen.c (revision 767862)
- @@ -208,6 +208,19 @@
- return yajl_gen_status_ok;
- }
-
- +yajl_gen_status
- +yajl_gen_uinteger(yajl_gen g, unsigned long long number)
- +{
- + char i[32];
- + ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
- + sprintf(i, "%llu", number);
- + g->print(g->ctx, i, (unsigned int)strlen(i));
- + APPENDED_ATOM;
- + FINAL_NEWLINE;
- + return yajl_gen_status_ok;
- +}
- +
- +
- #ifdef WIN32
- #include <float.h>
- #define isnan _isnan
- Index: yajl_gen.h
- ===================================================================
- --- yajl_gen.h (revision 767861)
- +++ yajl_gen.h (revision 767862)
- @@ -121,6 +121,7 @@
- YAJL_API void yajl_gen_free(yajl_gen handle);
-
- YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number);
- + YAJL_API yajl_gen_status yajl_gen_uinteger(yajl_gen hand, unsigned long long number);
- /** generate a floating point number. number may not be infinity or
- * NaN, as these have no representation in JSON. In these cases the
- * generator will return 'yajl_gen_invalid_number' */
|