add the disabling formatting coments and adjust the partial code manuly

This commit is contained in:
dota17
2020-03-27 13:04:50 +08:00
parent a8cec740f0
commit c117d8a8a8
13 changed files with 345 additions and 301 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
} }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)
{ {

View File

@@ -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; }

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 },

View File

@@ -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) */