Allow parsing of the hexadecimal number standard format (e.g. `0x<number>`). Signed-off-by: Nitzan Carmi <nitzanc@mellanox.com>pull/551/head
@@ -242,6 +242,30 @@ struct json_object* json_tokener_parse_verbose(const char *str, | |||||
/* End optimization macro defs */ | /* End optimization macro defs */ | ||||
int json_tokener_number_has_hex_prefix(const char *number) | |||||
{ | |||||
char *ptr_x; | |||||
/* Find 'x' location on string, if exist */ | |||||
ptr_x = strchr(number, 'x'); | |||||
if (!ptr_x) | |||||
return 0; | |||||
/* Check if 'x' located in a valid place */ | |||||
switch (ptr_x - number) { | |||||
case 1: | |||||
/* Positive Hex number, must start with '0x' */ | |||||
return (number[0] == '0'); | |||||
case 2: | |||||
/* Negative Hex number, must start with '-0x' */ | |||||
return (number[0] == '-') && (number[1] == '0'); | |||||
default: | |||||
return 0; | |||||
} | |||||
return 0; | |||||
} | |||||
struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | ||||
const char *str, int len) | const char *str, int len) | ||||
{ | { | ||||
@@ -736,7 +760,21 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
int case_len=0; | int case_len=0; | ||||
int is_exponent=0; | int is_exponent=0; | ||||
int negativesign_next_possible_location=1; | int negativesign_next_possible_location=1; | ||||
while(c && strchr(json_number_chars, c)) { | |||||
const char *json_valid_chars = json_number_chars; | |||||
if (json_tokener_number_has_hex_prefix(str)) { | |||||
json_valid_chars = json_hex_chars; | |||||
/* Advance pointers after the `0x` prefix */ | |||||
while (c != 'x') { | |||||
case_len++; | |||||
if (!PEEK_CHAR(c, tok) || !ADVANCE_CHAR(str, tok)) { | |||||
tok->err = json_tokener_error_parse_number; | |||||
goto out; | |||||
} | |||||
} | |||||
if (!PEEK_CHAR(c, tok)) | |||||
goto out; | |||||
} | |||||
while(c && strchr(json_valid_chars, c)) { | |||||
++case_len; | ++case_len; | ||||
/* non-digit characters checks */ | /* non-digit characters checks */ | ||||
@@ -148,6 +148,8 @@ typedef struct json_tokener json_tokener; | |||||
*/ | */ | ||||
#define JSON_TOKENER_VALIDATE_UTF8 0x10 | #define JSON_TOKENER_VALIDATE_UTF8 0x10 | ||||
int json_tokener_number_has_hex_prefix(const char *number); | |||||
/** | /** | ||||
* Given an error previously returned by json_tokener_get_error(), | * Given an error previously returned by json_tokener_get_error(), | ||||
* return a human readable description of the error. | * return a human readable description of the error. | ||||
@@ -10,6 +10,7 @@ | |||||
*/ | */ | ||||
#include "config.h" | #include "config.h" | ||||
#include "json_tokener.h" | |||||
#undef realloc | #undef realloc | ||||
#include "strerror_override.h" | #include "strerror_override.h" | ||||
@@ -223,9 +224,12 @@ int json_parse_int64(const char *buf, int64_t *retval) | |||||
{ | { | ||||
char *end = NULL; | char *end = NULL; | ||||
int64_t val; | int64_t val; | ||||
int base; | |||||
errno = 0; | errno = 0; | ||||
val = strtoll(buf, &end, 10); | |||||
base = json_tokener_number_has_hex_prefix(buf) ? 16 : 10; | |||||
val = strtoll(buf, &end, base); | |||||
if (end != buf) | if (end != buf) | ||||
*retval = val; | *retval = val; | ||||
return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0; | return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0; | ||||
@@ -235,14 +239,17 @@ int json_parse_uint64(const char *buf, uint64_t *retval) | |||||
{ | { | ||||
char *end = NULL; | char *end = NULL; | ||||
uint64_t val; | uint64_t val; | ||||
int base; | |||||
errno = 1; | errno = 1; | ||||
base = json_tokener_number_has_hex_prefix(buf) ? 16 : 10; | |||||
while (*buf == ' ') { | while (*buf == ' ') { | ||||
buf++; | buf++; | ||||
} | } | ||||
if (*buf == '-') errno = 0; | if (*buf == '-') errno = 0; | ||||
val = strtoull(buf, &end, 10); | |||||
val = strtoull(buf, &end, base); | |||||
if (end != buf) | if (end != buf) | ||||
*retval = val; | *retval = val; | ||||
return ((errno == 0) || (end == buf)) ? 1 : 0; | return ((errno == 0) || (end == buf)) ? 1 : 0; | ||||