mirror of
https://github.com/json-c/json-c.git
synced 2026-04-06 05:49:07 +08:00
add the disabling formatting coments and adjust the partial code manuly
This commit is contained in:
@@ -663,9 +663,9 @@ int32_t json_object_get_int(const struct json_object *jso)
|
|||||||
if (o_type == json_type_string)
|
if (o_type == json_type_string)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Parse strings into 64-bit numbers, then use the
|
* Parse strings into 64-bit numbers, then use the
|
||||||
* 64-to-32-bit number handling below.
|
* 64-to-32-bit number handling below.
|
||||||
*/
|
*/
|
||||||
if (json_parse_int64(get_string_component(jso), &cint64) != 0)
|
if (json_parse_int64(get_string_component(jso), &cint64) != 0)
|
||||||
return 0; /* whoops, it didn't work. */
|
return 0; /* whoops, it didn't work. */
|
||||||
o_type = json_type_int;
|
o_type = json_type_int;
|
||||||
@@ -896,9 +896,10 @@ static int json_object_double_to_json_string_format(struct json_object* jso,
|
|||||||
char buf[128], *p, *q;
|
char buf[128], *p, *q;
|
||||||
int size;
|
int size;
|
||||||
/* Although JSON RFC does not support
|
/* Although JSON RFC does not support
|
||||||
NaN or Infinity as numeric values
|
* NaN or Infinity as numeric values
|
||||||
ECMA 262 section 9.8.1 defines
|
* ECMA 262 section 9.8.1 defines
|
||||||
how to handle these cases as strings */
|
* how to handle these cases as strings
|
||||||
|
*/
|
||||||
if (isnan(jso->o.c_double))
|
if (isnan(jso->o.c_double))
|
||||||
{
|
{
|
||||||
size = snprintf(buf, sizeof(buf), "NaN");
|
size = snprintf(buf, sizeof(buf), "NaN");
|
||||||
@@ -1084,10 +1085,10 @@ double json_object_get_double(const struct json_object *jso)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the conversion terminated on something sensible
|
* Check that the conversion terminated on something sensible
|
||||||
*
|
*
|
||||||
* For example, { "pay" : 123AB } would parse as 123.
|
* For example, { "pay" : 123AB } would parse as 123.
|
||||||
*/
|
*/
|
||||||
if (*errPtr != '\0')
|
if (*errPtr != '\0')
|
||||||
{
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@@ -1095,16 +1096,16 @@ double json_object_get_double(const struct json_object *jso)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If strtod encounters a string which would exceed the
|
* If strtod encounters a string which would exceed the
|
||||||
* capacity of a double, it returns +/- HUGE_VAL and sets
|
* capacity of a double, it returns +/- HUGE_VAL and sets
|
||||||
* errno to ERANGE. But +/- HUGE_VAL is also a valid result
|
* errno to ERANGE. But +/- HUGE_VAL is also a valid result
|
||||||
* from a conversion, so we need to check errno.
|
* from a conversion, so we need to check errno.
|
||||||
*
|
*
|
||||||
* Underflow also sets errno to ERANGE, but it returns 0 in
|
* Underflow also sets errno to ERANGE, but it returns 0 in
|
||||||
* that case, which is what we will return anyway.
|
* that case, which is what we will return anyway.
|
||||||
*
|
*
|
||||||
* See CERT guideline ERR30-C
|
* See CERT guideline ERR30-C
|
||||||
*/
|
*/
|
||||||
if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
|
if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
|
||||||
(ERANGE == errno))
|
(ERANGE == errno))
|
||||||
cdouble = 0.0;
|
cdouble = 0.0;
|
||||||
|
|||||||
@@ -153,10 +153,10 @@ json_object_iter_init_default(void)
|
|||||||
struct json_object_iterator iter;
|
struct json_object_iterator iter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note Make this a negative, invalid value, such that
|
* @note Make this a negative, invalid value, such that
|
||||||
* accidental access to it would likely be trapped by the
|
* accidental access to it would likely be trapped by the
|
||||||
* hardware as an invalid address.
|
* hardware as an invalid address.
|
||||||
*/
|
*/
|
||||||
iter.opaque_ = NULL;
|
iter.opaque_ = NULL;
|
||||||
|
|
||||||
return iter;
|
return iter;
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in json_object for strings? */
|
/**< how many bytes are directly stored in json_object for strings? */
|
||||||
|
#define LEN_DIRECT_STRING_DATA 32
|
||||||
|
|
||||||
typedef void (json_object_private_delete_fn)(struct json_object *o);
|
typedef void (json_object_private_delete_fn)(struct json_object *o);
|
||||||
|
|
||||||
@@ -52,8 +53,8 @@ struct json_object
|
|||||||
struct {
|
struct {
|
||||||
union {
|
union {
|
||||||
/* optimize: if we have small strings, we can store them
|
/* optimize: if we have small strings, we can store them
|
||||||
* directly. This saves considerable CPU cycles AND memory.
|
* directly. This saves considerable CPU cycles AND memory.
|
||||||
*/
|
*/
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char data[LEN_DIRECT_STRING_DATA];
|
char data[LEN_DIRECT_STRING_DATA];
|
||||||
} str;
|
} str;
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur,
|
|||||||
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx)
|
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx)
|
||||||
{
|
{
|
||||||
int i, len = strlen(path);
|
int i, len = strlen(path);
|
||||||
/* this code-path optimizes a bit, for when we reference the 0-9 index range in a JSON array
|
/* this code-path optimizes a bit, for when we reference the 0-9 index range
|
||||||
and because leading zeros not allowed */
|
* in a JSON array and because leading zeros not allowed
|
||||||
|
*/
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
if (isdigit((unsigned char)path[0])) {
|
if (isdigit((unsigned char)path[0])) {
|
||||||
*idx = (path[0] - '0');
|
*idx = (path[0] - '0');
|
||||||
@@ -124,12 +125,14 @@ static int json_pointer_set_single_path(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* path replacements should have been done in json_pointer_get_single_path(),
|
/* path replacements should have been done in json_pointer_get_single_path(),
|
||||||
and we should still be good here */
|
* and we should still be good here
|
||||||
|
*/
|
||||||
if (json_object_is_type(parent, json_type_object))
|
if (json_object_is_type(parent, json_type_object))
|
||||||
return json_object_object_add(parent, path, value);
|
return json_object_object_add(parent, path, value);
|
||||||
|
|
||||||
/* Getting here means that we tried to "dereference" a primitive JSON type (like string, int, bool).
|
/* Getting here means that we tried to "dereference" a primitive JSON type
|
||||||
i.e. add a sub-object to it */
|
* (like string, int, bool).i.e. add a sub-object to it
|
||||||
|
*/
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -158,7 +161,8 @@ static int json_pointer_get_recursive(
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (endp) {
|
if (endp) {
|
||||||
*endp = '/'; /* Put the slash back, so that the sanity check passes on next recursion level */
|
/* Put the slash back, so that the sanity check passes on next recursion level */
|
||||||
|
*endp = '/';
|
||||||
return json_pointer_get_recursive(obj, endp, value);
|
return json_pointer_get_recursive(obj, endp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
json_tokener.c
119
json_tokener.c
@@ -68,24 +68,26 @@ static const int json_true_str_len = sizeof(json_true_str) - 1;
|
|||||||
static const char json_false_str[] = "false";
|
static const char json_false_str[] = "false";
|
||||||
static const int json_false_str_len = sizeof(json_false_str) - 1;
|
static const int json_false_str_len = sizeof(json_false_str) - 1;
|
||||||
|
|
||||||
static const char* json_tokener_errors[] = {
|
/* clang-format off */
|
||||||
"success",
|
static const char *json_tokener_errors[] = {
|
||||||
"continue",
|
"success",
|
||||||
"nesting too deep",
|
"continue",
|
||||||
"unexpected end of data",
|
"nesting too deep",
|
||||||
"unexpected character",
|
"unexpected end of data",
|
||||||
"null expected",
|
"unexpected character",
|
||||||
"boolean expected",
|
"null expected",
|
||||||
"number expected",
|
"boolean expected",
|
||||||
"array value separator ',' expected",
|
"number expected",
|
||||||
"quoted object property name expected",
|
"array value separator ',' expected",
|
||||||
"object property name separator ':' expected",
|
"quoted object property name expected",
|
||||||
"object value separator ',' expected",
|
"object property name separator ':' expected",
|
||||||
"invalid string sequence",
|
"object value separator ',' expected",
|
||||||
"expected comment",
|
"invalid string sequence",
|
||||||
"invalid utf-8 string",
|
"expected comment",
|
||||||
"buffer size overflow"
|
"invalid utf-8 string",
|
||||||
|
"buffer size overflow"
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
const char *json_tokener_error_desc(enum json_tokener_error jerr)
|
const char *json_tokener_error_desc(enum json_tokener_error jerr)
|
||||||
{
|
{
|
||||||
@@ -261,10 +263,11 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
tok->err = json_tokener_success;
|
tok->err = json_tokener_success;
|
||||||
|
|
||||||
/* this interface is presently not 64-bit clean due to the int len argument
|
/* this interface is presently not 64-bit clean due to the int len argument
|
||||||
and the internal printbuf interface that takes 32-bit int len arguments
|
* and the internal printbuf interface that takes 32-bit int len arguments
|
||||||
so the function limits the maximum string size to INT32_MAX (2GB).
|
* so the function limits the maximum string size to INT32_MAX (2GB).
|
||||||
If the function is called with len == -1 then strlen is called to check
|
* If the function is called with len == -1 then strlen is called to check
|
||||||
the string length is less than INT32_MAX (2GB) */
|
* the string length is less than INT32_MAX (2GB)
|
||||||
|
*/
|
||||||
if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
|
if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
|
||||||
tok->err = json_tokener_error_size;
|
tok->err = json_tokener_error_size;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -390,12 +393,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
|
case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
|
||||||
{
|
{
|
||||||
/* If we were guaranteed to have len set, then we could (usually) handle
|
/* If we were guaranteed to have len set, then we could (usually) handle
|
||||||
* the entire "Infinity" check in a single strncmp (strncasecmp), but
|
* the entire "Infinity" check in a single strncmp (strncasecmp), but
|
||||||
* since len might be -1 (i.e. "read until \0"), we need to check it
|
* since len might be -1 (i.e. "read until \0"), we need to check it
|
||||||
* a character at a time.
|
* a character at a time.
|
||||||
* Trying to handle it both ways would make this code considerably more
|
* Trying to handle it both ways would make this code considerably more
|
||||||
* complicated with likely little performance benefit.
|
* complicated with likely little performance benefit.
|
||||||
*/
|
*/
|
||||||
int is_negative = 0;
|
int is_negative = 0;
|
||||||
const char *_json_inf_str = json_inf_str;
|
const char *_json_inf_str = json_inf_str;
|
||||||
if (!(tok->flags & JSON_TOKENER_STRICT))
|
if (!(tok->flags & JSON_TOKENER_STRICT))
|
||||||
@@ -421,9 +424,9 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We checked the full length of "Infinity", so create the object.
|
/* We checked the full length of "Infinity", so create the object.
|
||||||
* When handling -Infinity, the number parsing code will have dropped
|
* When handling -Infinity, the number parsing code will have dropped
|
||||||
* the "-" into tok->pb for us, so check it now.
|
* the "-" into tok->pb for us, so check it now.
|
||||||
*/
|
*/
|
||||||
if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
|
if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
|
||||||
{
|
{
|
||||||
is_negative = 1;
|
is_negative = 1;
|
||||||
@@ -620,10 +623,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
|
unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
|
||||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
|
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
|
||||||
} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
|
} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
|
||||||
/* Got a high surrogate. Remember it and look for the
|
/* Got a high surrogate. Remember it and look for
|
||||||
* the beginning of another sequence, which should be the
|
* the beginning of another sequence, which
|
||||||
* low surrogate.
|
* should be the low surrogate.
|
||||||
*/
|
*/
|
||||||
got_hi_surrogate = tok->ucs_char;
|
got_hi_surrogate = tok->ucs_char;
|
||||||
/* Not at end, and the next two chars should be "\u" */
|
/* Not at end, and the next two chars should be "\u" */
|
||||||
if ((len == -1 || len > (tok->char_offset + 2)) &&
|
if ((len == -1 || len > (tok->char_offset + 2)) &&
|
||||||
@@ -631,17 +634,17 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
(str[1] == '\\') &&
|
(str[1] == '\\') &&
|
||||||
(str[2] == 'u'))
|
(str[2] == 'u'))
|
||||||
{
|
{
|
||||||
/* Advance through the 16 bit surrogate, and move on to the
|
/* Advance through the 16 bit surrogate, and move
|
||||||
* next sequence. The next step is to process the following
|
* on to the next sequence. The next step is to
|
||||||
* characters.
|
* process the following characters.
|
||||||
*/
|
*/
|
||||||
if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
|
if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
|
||||||
printbuf_memappend_fast(tok->pb,
|
printbuf_memappend_fast(tok->pb,
|
||||||
(char*) utf8_replacement_char, 3);
|
(char*) utf8_replacement_char, 3);
|
||||||
}
|
}
|
||||||
/* Advance to the first char of the next sequence and
|
/* Advance to the first char of the next sequence and
|
||||||
* continue processing with the next sequence.
|
* continue processing with the next sequence.
|
||||||
*/
|
*/
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||||
printbuf_memappend_fast(tok->pb,
|
printbuf_memappend_fast(tok->pb,
|
||||||
(char*) utf8_replacement_char, 3);
|
(char*) utf8_replacement_char, 3);
|
||||||
@@ -649,12 +652,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
tok->ucs_char = 0;
|
tok->ucs_char = 0;
|
||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
continue; /* other json_tokener_state_escape_unicode */
|
/* other json_tokener_state_escape_unicode */
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* Got a high surrogate without another sequence following
|
/* Got a high surrogate without another sequence following
|
||||||
* it. Put a replacement char in for the hi surrogate
|
* it. Put a replacement char in for the hi surrogate
|
||||||
* and pretend we finished.
|
* and pretend we finished.
|
||||||
*/
|
*/
|
||||||
printbuf_memappend_fast(tok->pb,
|
printbuf_memappend_fast(tok->pb,
|
||||||
(char*) utf8_replacement_char, 3);
|
(char*) utf8_replacement_char, 3);
|
||||||
}
|
}
|
||||||
@@ -684,7 +688,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||||
if (got_hi_surrogate) /* Clean up any pending chars */
|
/* Clean up any pending chars */
|
||||||
|
if (got_hi_surrogate)
|
||||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -741,14 +746,16 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
|
|
||||||
/* non-digit characters checks */
|
/* non-digit characters checks */
|
||||||
/* note: since the main loop condition to get here was
|
/* note: since the main loop condition to get here was
|
||||||
an input starting with 0-9 or '-', we are
|
* an input starting with 0-9 or '-', we are
|
||||||
protected from input starting with '.' or
|
* protected from input starting with '.' or
|
||||||
e/E. */
|
* e/E.
|
||||||
|
*/
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
if (tok->is_double != 0) {
|
if (tok->is_double != 0) {
|
||||||
/* '.' can only be found once, and out of the exponent part.
|
/* '.' can only be found once, and out of the exponent part.
|
||||||
Thus, if the input is already flagged as double, it
|
* Thus, if the input is already flagged as double, it
|
||||||
is invalid. */
|
* is invalid.
|
||||||
|
*/
|
||||||
tok->err = json_tokener_error_parse_number;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -767,8 +774,9 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
if (c == '-' && case_len != negativesign_next_possible_location) {
|
if (c == '-' && case_len != negativesign_next_possible_location) {
|
||||||
/* If the negative sign is not where expected (ie
|
/* If the negative sign is not where expected (ie
|
||||||
start of input or start of exponent part), the
|
* start of input or start of exponent part), the
|
||||||
input is invalid. */
|
* input is invalid.
|
||||||
|
*/
|
||||||
tok->err = json_tokener_error_parse_number;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -979,7 +987,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
/* unexpected char after JSON data */
|
/* unexpected char after JSON data */
|
||||||
tok->err = json_tokener_error_parse_unexpected;
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
}
|
}
|
||||||
if (!c) { /* We hit an eof char (0) */
|
if (!c) {
|
||||||
|
/* We hit an eof char (0) */
|
||||||
if(state != json_tokener_state_finish &&
|
if(state != json_tokener_state_finish &&
|
||||||
saved_state != json_tokener_state_finish)
|
saved_state != json_tokener_state_finish)
|
||||||
tok->err = json_tokener_error_parse_eof;
|
tok->err = json_tokener_error_parse_eof;
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ struct json_tokener
|
|||||||
struct printbuf *pb;
|
struct printbuf *pb;
|
||||||
int max_depth, depth, is_double, st_pos;
|
int max_depth, depth, is_double, st_pos;
|
||||||
/**
|
/**
|
||||||
* See json_tokener_get_parse_end()
|
* See json_tokener_get_parse_end()
|
||||||
*/
|
*/
|
||||||
int char_offset;
|
int char_offset;
|
||||||
enum json_tokener_error err;
|
enum json_tokener_error err;
|
||||||
unsigned int ucs_char;
|
unsigned int ucs_char;
|
||||||
|
|||||||
23
json_util.c
23
json_util.c
@@ -189,7 +189,8 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
|
/* CAW: probably unnecessary, but the most 64bit safe */
|
||||||
|
wsize = (unsigned int)(strlen(json_str) & UINT_MAX);
|
||||||
wpos = 0;
|
wpos = 0;
|
||||||
while(wpos < wsize) {
|
while(wpos < wsize) {
|
||||||
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
|
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
|
||||||
@@ -260,16 +261,18 @@ void* rpl_realloc(void* p, size_t n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NELEM(a) (sizeof(a) / sizeof(a[0]))
|
#define NELEM(a) (sizeof(a) / sizeof(a[0]))
|
||||||
static const char* json_type_name[] = {
|
/* clang-format off */
|
||||||
/* If you change this, be sure to update the enum json_type definition too */
|
static const char *json_type_name[] = {
|
||||||
"null",
|
/* If you change this, be sure to update the enum json_type definition too */
|
||||||
"boolean",
|
"null",
|
||||||
"double",
|
"boolean",
|
||||||
"int",
|
"double",
|
||||||
"object",
|
"int",
|
||||||
"array",
|
"object",
|
||||||
"string",
|
"array",
|
||||||
|
"string",
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
const char *json_type_to_name(enum json_type o_type)
|
const char *json_type_to_name(enum json_type o_type)
|
||||||
{
|
{
|
||||||
|
|||||||
354
linkhash.c
354
linkhash.c
@@ -178,15 +178,17 @@ on, and rotates are much kinder to the top and bottom bits, so I used
|
|||||||
rotates.
|
rotates.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
/* clang-format off */
|
||||||
#define mix(a,b,c) \
|
#define mix(a,b,c) \
|
||||||
{ \
|
{ \
|
||||||
a -= c; a ^= rot(c, 4); c += b; \
|
a -= c; a ^= rot(c, 4); c += b; \
|
||||||
b -= a; b ^= rot(a, 6); a += c; \
|
b -= a; b ^= rot(a, 6); a += c; \
|
||||||
c -= b; c ^= rot(b, 8); b += a; \
|
c -= b; c ^= rot(b, 8); b += a; \
|
||||||
a -= c; a ^= rot(c,16); c += b; \
|
a -= c; a ^= rot(c,16); c += b; \
|
||||||
b -= a; b ^= rot(a,19); a += c; \
|
b -= a; b ^= rot(a,19); a += c; \
|
||||||
c -= b; c ^= rot(b, 4); b += a; \
|
c -= b; c ^= rot(b, 4); b += a; \
|
||||||
}
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -213,16 +215,18 @@ and these came close:
|
|||||||
11 8 15 26 3 22 24
|
11 8 15 26 3 22 24
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
/* clang-format off */
|
||||||
#define final(a,b,c) \
|
#define final(a,b,c) \
|
||||||
{ \
|
{ \
|
||||||
c ^= b; c -= rot(b,14); \
|
c ^= b; c -= rot(b,14); \
|
||||||
a ^= c; a -= rot(c,11); \
|
a ^= c; a -= rot(c,11); \
|
||||||
b ^= a; b -= rot(a,25); \
|
b ^= a; b -= rot(a,25); \
|
||||||
c ^= b; c -= rot(b,16); \
|
c ^= b; c -= rot(b,16); \
|
||||||
a ^= c; a -= rot(c,4); \
|
a ^= c; a -= rot(c,4); \
|
||||||
b ^= a; b -= rot(a,14); \
|
b ^= a; b -= rot(a,14); \
|
||||||
c ^= b; c -= rot(b,24); \
|
c ^= b; c -= rot(b,24); \
|
||||||
}
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -252,184 +256,195 @@ acceptable. Do NOT use for cryptographic purposes.
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
/* clang-format off */
|
||||||
|
static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
|
||||||
{
|
{
|
||||||
uint32_t a,b,c; /* internal state */
|
uint32_t a,b,c; /* internal state */
|
||||||
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
|
union
|
||||||
|
{
|
||||||
|
const void *ptr;
|
||||||
|
size_t i;
|
||||||
|
} u; /* needed for Mac Powerbook G4 */
|
||||||
|
|
||||||
/* Set up the internal state */
|
/* Set up the internal state */
|
||||||
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
||||||
|
|
||||||
u.ptr = key;
|
u.ptr = key;
|
||||||
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
||||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
||||||
|
|
||||||
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
||||||
while (length > 12)
|
while (length > 12)
|
||||||
{
|
{
|
||||||
a += k[0];
|
a += k[0];
|
||||||
b += k[1];
|
b += k[1];
|
||||||
c += k[2];
|
c += k[2];
|
||||||
mix(a,b,c);
|
mix(a,b,c);
|
||||||
length -= 12;
|
length -= 12;
|
||||||
k += 3;
|
k += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------- handle the last (probably partial) block */
|
/*----------------------------- handle the last (probably partial) block */
|
||||||
/*
|
/*
|
||||||
* "k[2]&0xffffff" actually reads beyond the end of the string, but
|
* "k[2]&0xffffff" actually reads beyond the end of the string, but
|
||||||
* then masks off the part it's not allowed to read. Because the
|
* then masks off the part it's not allowed to read. Because the
|
||||||
* string is aligned, the masked-off tail is in the same word as the
|
* string is aligned, the masked-off tail is in the same word as the
|
||||||
* rest of the string. Every machine with memory protection I've seen
|
* rest of the string. Every machine with memory protection I've seen
|
||||||
* does it on word boundaries, so is OK with this. But VALGRIND will
|
* does it on word boundaries, so is OK with this. But VALGRIND will
|
||||||
* still catch it and complain. The masking trick does make the hash
|
* still catch it and complain. The masking trick does make the hash
|
||||||
* noticably faster for short strings (like English words).
|
* noticably faster for short strings (like English words).
|
||||||
* AddressSanitizer is similarly picky about overrunning
|
* AddressSanitizer is similarly picky about overrunning
|
||||||
* the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html
|
* the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html
|
||||||
*/
|
*/
|
||||||
#ifdef VALGRIND
|
#ifdef VALGRIND
|
||||||
# define PRECISE_MEMORY_ACCESS 1
|
#define PRECISE_MEMORY_ACCESS 1
|
||||||
#elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */
|
#elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */
|
||||||
# define PRECISE_MEMORY_ACCESS 1
|
#define PRECISE_MEMORY_ACCESS 1
|
||||||
#elif defined(__has_feature)
|
#elif defined(__has_feature)
|
||||||
# if __has_feature(address_sanitizer) /* Clang's ASAN */
|
#if __has_feature(address_sanitizer) /* Clang's ASAN */
|
||||||
# define PRECISE_MEMORY_ACCESS 1
|
#define PRECISE_MEMORY_ACCESS 1
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef PRECISE_MEMORY_ACCESS
|
#ifndef PRECISE_MEMORY_ACCESS
|
||||||
|
|
||||||
switch(length)
|
switch(length)
|
||||||
{
|
{
|
||||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
|
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
|
||||||
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
|
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
|
||||||
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
|
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
|
||||||
case 8 : b+=k[1]; a+=k[0]; break;
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
|
case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
|
||||||
case 6 : b+=k[1]&0xffff; a+=k[0]; break;
|
case 6 : b+=k[1]&0xffff; a+=k[0]; break;
|
||||||
case 5 : b+=k[1]&0xff; a+=k[0]; break;
|
case 5 : b+=k[1]&0xff; a+=k[0]; break;
|
||||||
case 4 : a+=k[0]; break;
|
case 4 : a+=k[0]; break;
|
||||||
case 3 : a+=k[0]&0xffffff; break;
|
case 3 : a+=k[0]&0xffffff; break;
|
||||||
case 2 : a+=k[0]&0xffff; break;
|
case 2 : a+=k[0]&0xffff; break;
|
||||||
case 1 : a+=k[0]&0xff; break;
|
case 1 : a+=k[0]&0xff; break;
|
||||||
case 0 : return c; /* zero length strings require no mixing */
|
case 0 : return c; /* zero length strings require no mixing */
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* make valgrind happy */
|
#else /* make valgrind happy */
|
||||||
|
|
||||||
const uint8_t *k8 = (const uint8_t *)k;
|
const uint8_t *k8 = (const uint8_t *)k;
|
||||||
switch(length)
|
switch(length)
|
||||||
{
|
{
|
||||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
case 9 : c+=k8[8]; /* fall through */
|
||||||
case 8 : b+=k[1]; a+=k[0]; break;
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
case 5 : b+=k8[4]; /* fall through */
|
||||||
case 4 : a+=k[0]; break;
|
case 4 : a+=k[0]; break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||||
case 1 : a+=k8[0]; break;
|
case 1 : a+=k8[0]; break;
|
||||||
case 0 : return c;
|
case 0 : return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !valgrind */
|
#endif /* !valgrind */
|
||||||
|
|
||||||
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
}
|
||||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0))
|
||||||
const uint8_t *k8;
|
{
|
||||||
|
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
||||||
|
const uint8_t *k8;
|
||||||
|
|
||||||
/*--------------- all but last block: aligned reads and different mixing */
|
/*--------------- all but last block: aligned reads and different mixing */
|
||||||
while (length > 12)
|
while (length > 12)
|
||||||
{
|
{
|
||||||
a += k[0] + (((uint32_t)k[1])<<16);
|
a += k[0] + (((uint32_t)k[1])<<16);
|
||||||
b += k[2] + (((uint32_t)k[3])<<16);
|
b += k[2] + (((uint32_t)k[3])<<16);
|
||||||
c += k[4] + (((uint32_t)k[5])<<16);
|
c += k[4] + (((uint32_t)k[5])<<16);
|
||||||
mix(a,b,c);
|
mix(a,b,c);
|
||||||
length -= 12;
|
length -= 12;
|
||||||
k += 6;
|
k += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------- handle the last (probably partial) block */
|
/*----------------------------- handle the last (probably partial) block */
|
||||||
k8 = (const uint8_t *)k;
|
k8 = (const uint8_t *)k;
|
||||||
switch(length)
|
switch(length)
|
||||||
{
|
{
|
||||||
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||||
case 10: c+=k[4];
|
case 10: c+=k[4];
|
||||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 9 : c+=k8[8]; /* fall through */
|
case 9 : c+=k8[8]; /* fall through */
|
||||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||||
case 6 : b+=k[2];
|
case 6 : b+=k[2];
|
||||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 5 : b+=k8[4]; /* fall through */
|
case 5 : b+=k8[4]; /* fall through */
|
||||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
break;
|
break;
|
||||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||||
case 2 : a+=k[0];
|
case 2 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
case 1 : a+=k8[0];
|
case 1 : a+=k8[0];
|
||||||
break;
|
break;
|
||||||
case 0 : return c; /* zero length requires no mixing */
|
case 0 : return c; /* zero length requires no mixing */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { /* need to read the key one byte at a time */
|
}
|
||||||
const uint8_t *k = (const uint8_t *)key;
|
else
|
||||||
|
{
|
||||||
|
/* need to read the key one byte at a time */
|
||||||
|
const uint8_t *k = (const uint8_t *)key;
|
||||||
|
|
||||||
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
||||||
while (length > 12)
|
while (length > 12)
|
||||||
{
|
{
|
||||||
a += k[0];
|
a += k[0];
|
||||||
a += ((uint32_t)k[1])<<8;
|
a += ((uint32_t)k[1])<<8;
|
||||||
a += ((uint32_t)k[2])<<16;
|
a += ((uint32_t)k[2])<<16;
|
||||||
a += ((uint32_t)k[3])<<24;
|
a += ((uint32_t)k[3])<<24;
|
||||||
b += k[4];
|
b += k[4];
|
||||||
b += ((uint32_t)k[5])<<8;
|
b += ((uint32_t)k[5])<<8;
|
||||||
b += ((uint32_t)k[6])<<16;
|
b += ((uint32_t)k[6])<<16;
|
||||||
b += ((uint32_t)k[7])<<24;
|
b += ((uint32_t)k[7])<<24;
|
||||||
c += k[8];
|
c += k[8];
|
||||||
c += ((uint32_t)k[9])<<8;
|
c += ((uint32_t)k[9])<<8;
|
||||||
c += ((uint32_t)k[10])<<16;
|
c += ((uint32_t)k[10])<<16;
|
||||||
c += ((uint32_t)k[11])<<24;
|
c += ((uint32_t)k[11])<<24;
|
||||||
mix(a,b,c);
|
mix(a,b,c);
|
||||||
length -= 12;
|
length -= 12;
|
||||||
k += 12;
|
k += 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------- last block: affect all 32 bits of (c) */
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
||||||
switch(length) /* all the case statements fall through */
|
switch(length) /* all the case statements fall through */
|
||||||
{
|
{
|
||||||
case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */
|
case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */
|
||||||
case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */
|
case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */
|
||||||
case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */
|
case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */
|
||||||
case 9 : c+=k[8]; /* FALLTHRU */
|
case 9 : c+=k[8]; /* FALLTHRU */
|
||||||
case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */
|
case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */
|
||||||
case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */
|
case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */
|
||||||
case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */
|
case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */
|
||||||
case 5 : b+=k[4]; /* FALLTHRU */
|
case 5 : b+=k[4]; /* FALLTHRU */
|
||||||
case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */
|
case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */
|
||||||
case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */
|
case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */
|
||||||
case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */
|
case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */
|
||||||
case 1 : a+=k[0];
|
case 1 : a+=k[0];
|
||||||
break;
|
break;
|
||||||
case 0 : return c;
|
case 0 : return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final(a,b,c);
|
final(a,b,c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
/* a simple hash function similiar to what perl does for strings.
|
/* a simple hash function similiar to what perl does for strings.
|
||||||
* for good results, the string should not be excessivly large.
|
* for good results, the string should not be excessivly large.
|
||||||
@@ -457,7 +472,7 @@ static unsigned long lh_char_hash(const void *k)
|
|||||||
if (random_seed == -1) {
|
if (random_seed == -1) {
|
||||||
RANDOM_SEED_TYPE seed;
|
RANDOM_SEED_TYPE seed;
|
||||||
/* we can't use -1 as it is the unitialized sentinel */
|
/* we can't use -1 as it is the unitialized sentinel */
|
||||||
while ((seed = json_c_get_random_seed()) == -1);
|
while ((seed = json_c_get_random_seed()) == -1) {}
|
||||||
#if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
|
#if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
|
||||||
#define USE_SYNC_COMPARE_AND_SWAP 1
|
#define USE_SYNC_COMPARE_AND_SWAP 1
|
||||||
#endif
|
#endif
|
||||||
@@ -638,7 +653,8 @@ json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
|
|||||||
|
|
||||||
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
||||||
{
|
{
|
||||||
ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
|
/* CAW: fixed to be 64bit nice, still need the crazy negative case... */
|
||||||
|
ptrdiff_t n = (ptrdiff_t)(e - t->table);
|
||||||
|
|
||||||
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
|
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
|
||||||
if(n < 0) { return -2; }
|
if(n < 0) { return -2; }
|
||||||
|
|||||||
@@ -124,9 +124,10 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
|
|||||||
size = vsnprintf(buf, 128, msg, ap);
|
size = vsnprintf(buf, 128, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* if string is greater than stack buffer, then use dynamic string
|
/* if string is greater than stack buffer, then use dynamic string
|
||||||
with vasprintf. Note: some implementation of vsnprintf return -1
|
* with vasprintf. Note: some implementation of vsnprintf return -1
|
||||||
if output is truncated whereas some return the number of bytes that
|
* if output is truncated whereas some return the number of bytes that
|
||||||
would have been written - this code handles both cases. */
|
* would have been written - this code handles both cases.
|
||||||
|
*/
|
||||||
if(size == -1 || size > 127) {
|
if(size == -1 || size > 127) {
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
|
if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ static struct {
|
|||||||
int errno_value;
|
int errno_value;
|
||||||
const char *errno_str;
|
const char *errno_str;
|
||||||
} errno_list[] = {
|
} errno_list[] = {
|
||||||
|
/* clang-format off */
|
||||||
#define STRINGIFY(x) #x
|
#define STRINGIFY(x) #x
|
||||||
#define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]}
|
#define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]}
|
||||||
ENTRY(EPERM),
|
ENTRY(EPERM),
|
||||||
@@ -52,6 +53,7 @@ static struct {
|
|||||||
ENTRY(EAGAIN),
|
ENTRY(EAGAIN),
|
||||||
{ 0, (char *)0 }
|
{ 0, (char *)0 }
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
// Enabled during tests
|
// Enabled during tests
|
||||||
int _json_c_strerror_enable = 0;
|
int _json_c_strerror_enable = 0;
|
||||||
|
|||||||
@@ -32,30 +32,32 @@ static const char *input_json_str = "{ "
|
|||||||
"'m~n': 8 "
|
"'m~n': 8 "
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
static const char *rec_input_json_str = "{"
|
static const char *rec_input_json_str =
|
||||||
"'arr' : ["
|
"{"
|
||||||
"{"
|
"'arr' : ["
|
||||||
"'obj': ["
|
"{"
|
||||||
"{},{},"
|
"'obj': ["
|
||||||
"{"
|
"{},{},"
|
||||||
"'obj1': 0,"
|
"{"
|
||||||
"'obj2': \"1\""
|
"'obj1': 0,"
|
||||||
"}"
|
"'obj2': \"1\""
|
||||||
"]"
|
"}"
|
||||||
"}"
|
"]"
|
||||||
"],"
|
"}"
|
||||||
"'obj' : {"
|
"],"
|
||||||
"'obj': {"
|
"'obj' : {"
|
||||||
"'obj': ["
|
"'obj': {"
|
||||||
"{"
|
"'obj': ["
|
||||||
"'obj1': 0,"
|
"{"
|
||||||
"'obj2': \"1\""
|
"'obj1': 0,"
|
||||||
"}"
|
"'obj2': \"1\""
|
||||||
"]"
|
"}"
|
||||||
"}"
|
"]"
|
||||||
"}"
|
"}"
|
||||||
"}";
|
"}"
|
||||||
|
"}";
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
/* Example from RFC */
|
/* Example from RFC */
|
||||||
static void test_example_get()
|
static void test_example_get()
|
||||||
@@ -67,6 +69,7 @@ static void test_example_get()
|
|||||||
int i;
|
int i;
|
||||||
};
|
};
|
||||||
/* Create a map to iterate over for the ints */
|
/* Create a map to iterate over for the ints */
|
||||||
|
/* clang-format off */
|
||||||
struct json_pointer_map_s_i json_pointers[] = {
|
struct json_pointer_map_s_i json_pointers[] = {
|
||||||
{ "/", 0 },
|
{ "/", 0 },
|
||||||
{ "/a~1b", 1 },
|
{ "/a~1b", 1 },
|
||||||
@@ -79,6 +82,7 @@ static void test_example_get()
|
|||||||
{ "/m~0n", 8 },
|
{ "/m~0n", 8 },
|
||||||
{ NULL, 0}
|
{ NULL, 0}
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
jo1 = json_tokener_parse(input_json_str);
|
jo1 = json_tokener_parse(input_json_str);
|
||||||
assert(NULL != jo1);
|
assert(NULL != jo1);
|
||||||
|
|||||||
@@ -310,8 +310,9 @@ struct incremental_step {
|
|||||||
{ "fail", 5, 2, json_tokener_error_parse_boolean, 1 },
|
{ "fail", 5, 2, json_tokener_error_parse_boolean, 1 },
|
||||||
|
|
||||||
/* Although they may initially look like they should fail,
|
/* Although they may initially look like they should fail,
|
||||||
the next few tests check that parsing multiple sequential
|
* the next few tests check that parsing multiple sequential
|
||||||
json objects in the input works as expected */
|
* json objects in the input works as expected
|
||||||
|
*/
|
||||||
{ "null123", 9, 4, json_tokener_success, 0 },
|
{ "null123", 9, 4, json_tokener_success, 0 },
|
||||||
{ &"null123"[4], 4, 3, json_tokener_success, 1 },
|
{ &"null123"[4], 4, 3, json_tokener_success, 1 },
|
||||||
{ "nullx", 5, 4, json_tokener_success, 0 },
|
{ "nullx", 5, 4, json_tokener_success, 0 },
|
||||||
@@ -357,8 +358,9 @@ struct incremental_step {
|
|||||||
{ "[,1]", -1, 1, json_tokener_error_parse_unexpected, 1 },
|
{ "[,1]", -1, 1, json_tokener_error_parse_unexpected, 1 },
|
||||||
|
|
||||||
/* This behaviour doesn't entirely follow the json spec, but until we have
|
/* This behaviour doesn't entirely follow the json spec, but until we have
|
||||||
a way to specify how strict to be we follow Postel's Law and be liberal
|
* a way to specify how strict to be we follow Postel's Law and be liberal
|
||||||
in what we accept (up to a point). */
|
* in what we accept (up to a point).
|
||||||
|
*/
|
||||||
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 },
|
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 },
|
||||||
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
|
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ static int vasprintf(char **buf, const char *fmt, va_list ap)
|
|||||||
chars = _vscprintf(fmt, ap)+1;
|
chars = _vscprintf(fmt, ap)+1;
|
||||||
#else /* !defined(WIN32) */
|
#else /* !defined(WIN32) */
|
||||||
/* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
|
/* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
|
||||||
our buffer like on some 64bit sun systems.... but hey, its time to move on */
|
* our buffer like on some 64bit sun systems.... but hey, its time to move on
|
||||||
|
*/
|
||||||
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
|
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
|
||||||
if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
|
if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
|
||||||
#endif /* defined(WIN32) */
|
#endif /* defined(WIN32) */
|
||||||
|
|||||||
Reference in New Issue
Block a user