uint64_support_r767862_review16855.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. Index: yajl_parse.h
  2. ===================================================================
  3. --- yajl_parse.h (revision 767861)
  4. +++ yajl_parse.h (revision 767862)
  5. @@ -75,6 +75,7 @@
  6. int (* yajl_null)(void * ctx);
  7. int (* yajl_boolean)(void * ctx, int boolVal);
  8. int (* yajl_integer)(void * ctx, long long integerVal);
  9. + int (* yajl_uinteger)(void * ctx, unsigned long long uintegerVal);
  10. int (* yajl_double)(void * ctx, double doubleVal);
  11. /** A callback which passes the string representation of the number
  12. * back to the client. Will be used for all numbers when present */
  13. Index: yajl_parser.c
  14. ===================================================================
  15. --- yajl_parser.c (revision 767861)
  16. +++ yajl_parser.c (revision 767862)
  17. @@ -30,6 +30,7 @@
  18. #include <math.h>
  19. #define MAX_VALUE_TO_MULTIPLY ((LLONG_MAX / 10) + (LLONG_MAX % 10))
  20. +#define MAX_UVALUE_TO_MULTIPLY ((ULLONG_MAX / 10) + (ULLONG_MAX % 10))
  21. /* same semantics as strtol */
  22. long long
  23. @@ -57,6 +58,35 @@
  24. return sign * ret;
  25. }
  26. +unsigned long long
  27. +yajl_parse_uinteger(const unsigned char *number, unsigned int length)
  28. +{
  29. + unsigned long long ret = 0;
  30. + const unsigned char *pos = number;
  31. + if (*pos == '-') {
  32. + errno = ERANGE;
  33. + return 0;
  34. + }
  35. +
  36. + if (*pos == '+') { pos++; }
  37. +
  38. + while (pos < number + length) {
  39. + if ( ret > MAX_UVALUE_TO_MULTIPLY ) {
  40. + errno = ERANGE;
  41. + return ULLONG_MAX;
  42. + }
  43. + ret *= 10ull;
  44. + if (ULLONG_MAX - ret < (unsigned long long)(*pos - '0')) {
  45. + errno = ERANGE;
  46. + return ULLONG_MAX;
  47. + }
  48. + ret += (unsigned long long)(*pos++ - '0');
  49. + }
  50. +
  51. + return ret;
  52. +}
  53. +
  54. +
  55. unsigned char *
  56. yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
  57. size_t jsonTextLen, int verbose)
  58. @@ -283,6 +313,37 @@
  59. if ((i == LLONG_MIN || i == LLONG_MAX) &&
  60. errno == ERANGE)
  61. {
  62. + unsigned long long ui = 0;
  63. + int parsing_failed = 1;
  64. + if (hand->callbacks->yajl_uinteger) {
  65. + errno = 0;
  66. + ui = yajl_parse_uinteger(buf, bufLen);
  67. + if ((ui == 0 || ui == ULLONG_MAX) && errno == ERANGE)
  68. + parsing_failed = 1;
  69. + else
  70. + parsing_failed = 0;
  71. + }
  72. +
  73. + if (parsing_failed) {
  74. + yajl_bs_set(hand->stateStack,
  75. + yajl_state_parse_error);
  76. + hand->parseError = "integer overflow" ;
  77. + /* try to restore error offset */
  78. + if (*offset >= bufLen) *offset -= bufLen;
  79. + else *offset = 0;
  80. + goto around_again;
  81. + } else {
  82. + _CC_CHK(hand->callbacks->yajl_uinteger(hand->ctx,
  83. + ui));
  84. + }
  85. + } else {
  86. + _CC_CHK(hand->callbacks->yajl_integer(hand->ctx,
  87. + i));
  88. + }
  89. + } else if (hand->callbacks->yajl_uinteger) {
  90. + unsigned long long ui = 0;
  91. + ui = yajl_parse_uinteger(buf, bufLen);
  92. + if ((ui == 0 || ui == ULLONG_MAX) && errno == ERANGE) {
  93. yajl_bs_set(hand->stateStack,
  94. yajl_state_parse_error);
  95. hand->parseError = "integer overflow" ;
  96. @@ -291,8 +352,8 @@
  97. else *offset = 0;
  98. goto around_again;
  99. }
  100. - _CC_CHK(hand->callbacks->yajl_integer(hand->ctx,
  101. - i));
  102. + _CC_CHK(hand->callbacks->yajl_uinteger(hand->ctx,
  103. + ui));
  104. }
  105. }
  106. break;
  107. Index: yajl_tree.c
  108. ===================================================================
  109. --- yajl_tree.c (revision 767861)
  110. +++ yajl_tree.c (revision 767862)
  111. @@ -318,6 +318,14 @@
  112. endptr = NULL;
  113. errno = 0;
  114. + v->u.number.ui = yajl_parse_uinteger((const unsigned char *) v->u.number.r,
  115. + strlen(v->u.number.r));
  116. +
  117. + if ((errno == 0) && (endptr != NULL) && (*endptr == 0))
  118. + v->u.number.flags |= YAJL_NUMBER_UINT_VALID;
  119. +
  120. + endptr = NULL;
  121. + errno = 0;
  122. v->u.number.d = strtod(v->u.number.r, &endptr);
  123. if ((errno == 0) && (endptr != NULL) && (*endptr == 0))
  124. v->u.number.flags |= YAJL_NUMBER_DOUBLE_VALID;
  125. @@ -409,6 +417,7 @@
  126. /* null = */ handle_null,
  127. /* boolean = */ handle_boolean,
  128. /* integer = */ NULL,
  129. + /* unsigned integer = */ NULL,
  130. /* double = */ NULL,
  131. /* number = */ handle_number,
  132. /* string = */ handle_string,
  133. Index: yajl_parser.h
  134. ===================================================================
  135. --- yajl_parser.h (revision 767861)
  136. +++ yajl_parser.h (revision 767862)
  137. @@ -74,5 +74,8 @@
  138. long long
  139. yajl_parse_integer(const unsigned char *number, unsigned int length);
  140. +unsigned long long
  141. +yajl_parse_uinteger(const unsigned char *number, unsigned int length);
  142. +
  143. #endif
  144. Index: yajl_tree.h
  145. ===================================================================
  146. --- yajl_tree.h (revision 767861)
  147. +++ yajl_tree.h (revision 767862)
  148. @@ -50,6 +50,7 @@
  149. #define YAJL_NUMBER_INT_VALID 0x01
  150. #define YAJL_NUMBER_DOUBLE_VALID 0x02
  151. +#define YAJL_NUMBER_UINT_VALID 0x04
  152. /** A pointer to a node in the parse tree */
  153. typedef struct yajl_val_s * yajl_val;
  154. @@ -73,6 +74,7 @@
  155. char * string;
  156. struct {
  157. long long i; /*< integer value, if representable. */
  158. + unsigned long long ui; /*< unsigned integer value, if representable. */
  159. double d; /*< double value, if representable. */
  160. /** Signals whether the \em i and \em d members are
  161. * valid. See \c YAJL_NUMBER_INT_VALID and
  162. @@ -145,6 +147,7 @@
  163. #define YAJL_IS_STRING(v) (((v) != NULL) && ((v)->type == yajl_t_string))
  164. #define YAJL_IS_NUMBER(v) (((v) != NULL) && ((v)->type == yajl_t_number))
  165. #define YAJL_IS_INTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_INT_VALID))
  166. +#define YAJL_IS_UINTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_UINT_VALID))
  167. #define YAJL_IS_DOUBLE(v) (YAJL_IS_NUMBER(v) && ((v)->u.flags & YAJL_NUMBER_DOUBLE_VALID))
  168. #define YAJL_IS_OBJECT(v) (((v) != NULL) && ((v)->type == yajl_t_object))
  169. #define YAJL_IS_ARRAY(v) (((v) != NULL) && ((v)->type == yajl_t_array ))
  170. @@ -168,6 +171,10 @@
  171. * check type first, perhaps using YAJL_IS_INTEGER */
  172. #define YAJL_GET_INTEGER(v) ((v)->u.number.i)
  173. +/** Get the 64bit (unsigned long long) unsigned integer representation of a number. You should
  174. + * check type first, perhaps using YAJL_IS_UINTEGER */
  175. +#define YAJL_GET_UINTEGER(v) ((v)->u.number.ui)
  176. +
  177. /** Get a pointer to a yajl_val_object or NULL if the value is not an object. */
  178. #define YAJL_GET_OBJECT(v) (YAJL_IS_OBJECT(v) ? &(v)->u.object : NULL)
  179. Index: yajl_gen.c
  180. ===================================================================
  181. --- yajl_gen.c (revision 767861)
  182. +++ yajl_gen.c (revision 767862)
  183. @@ -208,6 +208,19 @@
  184. return yajl_gen_status_ok;
  185. }
  186. +yajl_gen_status
  187. +yajl_gen_uinteger(yajl_gen g, unsigned long long number)
  188. +{
  189. + char i[32];
  190. + ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
  191. + sprintf(i, "%llu", number);
  192. + g->print(g->ctx, i, (unsigned int)strlen(i));
  193. + APPENDED_ATOM;
  194. + FINAL_NEWLINE;
  195. + return yajl_gen_status_ok;
  196. +}
  197. +
  198. +
  199. #ifdef WIN32
  200. #include <float.h>
  201. #define isnan _isnan
  202. Index: yajl_gen.h
  203. ===================================================================
  204. --- yajl_gen.h (revision 767861)
  205. +++ yajl_gen.h (revision 767862)
  206. @@ -121,6 +121,7 @@
  207. YAJL_API void yajl_gen_free(yajl_gen handle);
  208. YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number);
  209. + YAJL_API yajl_gen_status yajl_gen_uinteger(yajl_gen hand, unsigned long long number);
  210. /** generate a floating point number. number may not be infinity or
  211. * NaN, as these have no representation in JSON. In these cases the
  212. * generator will return 'yajl_gen_invalid_number' */