diff --git a/src/encrypt.c b/src/encrypt.c index a5c7dde5..e31c3102 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -109,11 +109,13 @@ static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] = }; #ifdef USE_CRYPTO_POLARSSL -static const int supported_ciphers_iv_size[CIPHER_NUM] = { +static const int supported_ciphers_iv_size[CIPHER_NUM] = +{ 0, 0, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16 }; -static const int supported_ciphers_key_size[CIPHER_NUM] = { +static const int supported_ciphers_key_size[CIPHER_NUM] = +{ 0, 16, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16 }; #endif @@ -211,7 +213,8 @@ unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md) return MD5(d, n, md); #elif defined(USE_CRYPTO_POLARSSL) static unsigned char m[16]; - if (md == NULL) { + if (md == NULL) + { md = m; } md5(d, n, md); @@ -257,7 +260,8 @@ int cipher_iv_size(const cipher_kt_t *cipher) #if defined(USE_CRYPTO_OPENSSL) return EVP_CIPHER_iv_length (cipher); #elif defined(USE_CRYPTO_POLARSSL) - if (cipher == NULL) { + if (cipher == NULL) + { return 0; } return cipher->iv_size; @@ -269,11 +273,13 @@ int cipher_key_size (const cipher_kt_t *cipher) #if defined(USE_CRYPTO_OPENSSL) return EVP_CIPHER_key_length(cipher); #elif defined(USE_CRYPTO_POLARSSL) - if (cipher == NULL) { + if (cipher == NULL) + { return 0; } /* Override PolarSSL 32 bit default key size with sane 128 bit default */ - if (cipher->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == cipher->base->cipher) { + if (cipher->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == cipher->base->cipher) + { return 128 / 8; } return cipher->key_length / 8; @@ -299,28 +305,37 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8 nkey = cipher_key_size(cipher); niv = cipher_iv_size(cipher); rv = nkey; - if (pass == NULL) { + if (pass == NULL) + { return nkey; } memset(&c, 0, sizeof(md_context_t)); - if (md_init_ctx(&c, md)) { + if (md_init_ctx(&c, md)) + { return 0; } addmd = 0; mds = md_get_size(md); - for (;;) { + for (;;) + { int error; - do { + do + { error = 1; - if (md_starts(&c)) { + if (md_starts(&c)) + { break; } - if (addmd) { - if (md_update(&c, &(md_buf[0]), mds)) { + if (addmd) + { + if (md_update(&c, &(md_buf[0]), mds)) + { break; - } - } else { + } + } + else + { addmd = 1; } if (md_update(&c, pass, datal)) @@ -328,16 +343,20 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8 if (md_finish(&c, &(md_buf[0]))) break; error = 0; - } while (0); - if (error) { + } + while (0); + if (error) + { md_free_ctx(&c); memset(md_buf, 0, MAX_MD_SIZE); return 0; } i=0; - if (nkey) { - for (;;) { + if (nkey) + { + for (;;) + { if (nkey == 0) break; if (i == mds) break; if (key != NULL) @@ -346,8 +365,10 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8 i++; } } - if (niv && (i != mds)) { - for (;;) { + if (niv && (i != mds)) + { + for (;;) + { if (niv == 0) break; if (i == mds) break; if (iv != NULL) @@ -374,39 +395,49 @@ int rand_bytes(uint8_t *output, int len) static unsigned char rand_initialised = 0; const size_t blen = min(len, CTR_DRBG_MAX_REQUEST); - if (!rand_initialised) { + if (!rand_initialised) + { #ifdef _WIN32 HCRYPTPROV hProvider; - union { + union + { unsigned __int64 seed; BYTE buffer[8]; } rand_buffer; hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { CryptGenRandom(hProvider, 8, rand_buffer.buffer); CryptReleaseContext(hProvider, 0); - } else { + } + else + { rand_buffer.seed = (unsigned __int64) clock(); } #else FILE *urand; - union { + union + { uint64_t seed; uint8_t buffer[8]; } rand_buffer; urand = fopen("/dev/urandom", "r"); - if (urand) { + if (urand) + { fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand); fclose(urand); - } else { + } + else + { rand_buffer.seed = (uint64_t) clock(); } #endif entropy_init(&ec); - if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *) rand_buffer.buffer, 8) != 0) { + if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *) rand_buffer.buffer, 8) != 0) + { #if POLARSSL_VERSION_NUMBER >= 0x01030000 entropy_free(&ec); #endif @@ -414,8 +445,10 @@ int rand_bytes(uint8_t *output, int len) } rand_initialised = 1; } - while (len > 0) { - if (ctr_drbg_random(&cd_ctx, output, blen) != 0) { + while (len > 0) + { + if (ctr_drbg_random(&cd_ctx, output, blen) != 0) + { return 0; } output += blen; @@ -427,7 +460,8 @@ int rand_bytes(uint8_t *output, int len) const cipher_kt_t *get_cipher_type(int method) { - if (method <= TABLE || method >= CIPHER_NUM) { + if (method <= TABLE || method >= CIPHER_NUM) + { LOGE("get_cipher_type(): Illegal method"); return NULL; } @@ -437,7 +471,8 @@ const cipher_kt_t *get_cipher_type(int method) return EVP_get_cipherbyname(ciphername); #elif defined(USE_CRYPTO_POLARSSL) const char *polarname = supported_ciphers_polarssl[method]; - if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0) { + if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0) + { LOGE("Cipher %s currently is not supported by PolarSSL library", ciphername); return NULL; } @@ -447,7 +482,8 @@ const cipher_kt_t *get_cipher_type(int method) const digest_type_t *get_digest_type(const char *digest) { - if (digest == NULL) { + if (digest == NULL) + { LOGE("get_digest_type(): Digest name is null"); return NULL; } @@ -461,7 +497,8 @@ const digest_type_t *get_digest_type(const char *digest) void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) { - if (method <= TABLE || method >= CIPHER_NUM) { + if (method <= TABLE || method >= CIPHER_NUM) + { LOGE("cipher_context_init(): Illegal method"); return; } @@ -471,14 +508,20 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) cipher_cc_t *cc = &ctx->cc; cc->cryptor = NULL; cc->cipher = supported_ciphers_applecc[method]; - if (cc->cipher == kCCAlgorithmInvalid) { + if (cc->cipher == kCCAlgorithmInvalid) + { cc->valid = kCCContextInvalid; - } else { + } + else + { cc->valid = kCCContextValid; - if (cc->cipher == kCCAlgorithmRC4) { + if (cc->cipher == kCCAlgorithmRC4) + { cc->mode = kCCModeRC4; cc->padding = ccNoPadding; - } else { + } + else + { cc->mode = kCCModeCFB; cc->padding = ccPKCS7Padding; } @@ -489,29 +532,35 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) cipher_evp_t *evp = &ctx->evp; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) - if (cipher == NULL) { + if (cipher == NULL) + { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); - if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { + if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) + { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } - if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { + if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) + { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } - if (method > RC4) { + if (method > RC4) + { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) - if (cipher == NULL) { + if (cipher == NULL) + { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } - if (cipher_init_ctx(evp, cipher) != 0) { + if (cipher_init_ctx(evp, cipher) != 0) + { FATAL("Cannot initialize PolarSSL cipher context"); } #endif @@ -519,38 +568,44 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int enc) { - if (iv == NULL) { + if (iv == NULL) + { LOGE("cipher_context_set_iv(): IV is null"); return; } - if (enc) { + if (enc) + { rand_bytes(iv, iv_len); } #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; - if (cc->valid == kCCContextValid) { + if (cc->valid == kCCContextValid) + { memcpy(cc->iv, iv, iv_len); memcpy(cc->key, enc_key, enc_key_len); cc->iv_len = iv_len; cc->key_len = enc_key_len; cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; - if (cc->cryptor != NULL) { + if (cc->cryptor != NULL) + { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } CCCryptorStatus ret; ret = CCCryptorCreateWithMode( - cc->encrypt, - cc->mode, - cc->cipher, - cc->padding, - cc->iv, cc->key, cc->key_len, - NULL, 0, 0, 0, - &cc->cryptor); - if (ret != kCCSuccess) { - if (cc->cryptor != NULL) { + cc->encrypt, + cc->mode, + cc->cipher, + cc->padding, + cc->iv, cc->key, cc->key_len, + NULL, 0, 0, 0, + &cc->cryptor); + if (ret != kCCSuccess) + { + if (cc->cryptor != NULL) + { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } @@ -561,31 +616,37 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int en #endif cipher_evp_t *evp = &ctx->evp; - if (evp == NULL) { + if (evp == NULL) + { LOGE("cipher_context_set_iv(): Cipher context is null"); return; } #if defined(USE_CRYPTO_OPENSSL) - if (!EVP_CipherInit_ex(evp, NULL, NULL, enc_key, iv, enc)) { + if (!EVP_CipherInit_ex(evp, NULL, NULL, enc_key, iv, enc)) + { EVP_CIPHER_CTX_cleanup(evp); FATAL("Cannot set key and IV"); } #elif defined(USE_CRYPTO_POLARSSL) - if (cipher_setkey(evp, enc_key, enc_key_len * 8, enc) != 0) { + if (cipher_setkey(evp, enc_key, enc_key_len * 8, enc) != 0) + { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher key"); } #if POLARSSL_VERSION_NUMBER >= 0x01030000 - if (cipher_set_iv(evp, iv, iv_len) != 0) { + if (cipher_set_iv(evp, iv, iv_len) != 0) + { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } - if(cipher_reset(evp) != 0) { + if(cipher_reset(evp) != 0) + { cipher_free_ctx(evp); FATAL("Cannot finalize PolarSSL cipher context"); } #else - if(cipher_reset(evp, iv) != 0) { + if(cipher_reset(evp, iv) != 0) + { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } @@ -597,14 +658,17 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int en #endif } -void cipher_context_release(cipher_ctx_t *ctx) { +void cipher_context_release(cipher_ctx_t *ctx) +{ #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; - if (cc->cryptor != NULL) { + if (cc->cryptor != NULL) + { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } - if (cc->valid == kCCContextValid) { + if (cc->valid == kCCContextValid) + { return; } #endif @@ -618,10 +682,12 @@ void cipher_context_release(cipher_ctx_t *ctx) { } static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen, - const uint8_t *input, int ilen) { + const uint8_t *input, int ilen) +{ #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; - if (cc->valid == kCCContextValid) { + if (cc->valid == kCCContextValid) + { CCCryptorStatus ret; ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ilen + BLOCK_SIZE, (size_t *) olen); return (ret == kCCSuccess) ? 1 : 0; @@ -841,7 +907,8 @@ void enc_ctx_init(int method, struct enc_ctx *ctx, int enc) void enc_key_init(int method, const char *pass) { - if (method <= TABLE || method >= CIPHER_NUM) { + if (method <= TABLE || method >= CIPHER_NUM) + { LOGE("enc_key_init(): Illegal method"); return; } @@ -856,10 +923,13 @@ void enc_key_init(int method, const char *pass) uint8_t iv[MAX_IV_LENGTH]; const cipher_kt_t *cipher = get_cipher_type(method); - if (cipher == NULL) { - do { + if (cipher == NULL) + { + do + { #if defined(USE_CRYPTO_POLARSSL) && defined(USE_CRYPTO_APPLECC) - if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { + if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) + { cipher_info.base = NULL; cipher_info.key_length = supported_ciphers_key_size[method] * 8; cipher_info.iv_size = supported_ciphers_iv_size[method]; @@ -869,15 +939,18 @@ void enc_key_init(int method, const char *pass) #endif LOGE("Cipher %s not found in crypto library", supported_ciphers[method]); FATAL("Cannot initialize cipher"); - } while (0); + } + while (0); } const digest_type_t *md = get_digest_type("MD5"); - if (md == NULL) { + if (md == NULL) + { FATAL("MD5 Digest not found in crypto library"); } enc_key_len = bytes_to_key(cipher, md, (const uint8_t *) pass, enc_key, iv); - if (enc_key_len == 0) { + if (enc_key_len == 0) + { FATAL("Cannot generate key and IV"); } enc_iv_len = cipher_iv_size(cipher); diff --git a/src/encrypt.h b/src/encrypt.h index 0a52ffb3..ae052b32 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -52,7 +52,8 @@ typedef md_info_t digest_type_t; #define kCCContextValid 0 #define kCCContextInvalid -1 -typedef struct { +typedef struct +{ CCCryptorRef cryptor; int valid; CCOperation encrypt; @@ -67,7 +68,8 @@ typedef struct { #endif -typedef struct { +typedef struct +{ cipher_evp_t evp; #ifdef USE_CRYPTO_APPLECC cipher_cc_t cc; diff --git a/src/include.h b/src/include.h index bd6ddfa4..f2c3ad09 100644 --- a/src/include.h +++ b/src/include.h @@ -3,14 +3,14 @@ int udprelay_init(const char *server_host, const char *server_port, #ifdef UDPRELAY_LOCAL - const char *remote_host, const char *remote_port, + const char *remote_host, const char *remote_port, #ifdef UDPRELAY_TUNNEL - const ss_addr_t tunnel_addr, + const ss_addr_t tunnel_addr, #endif #endif #ifdef UDPRELAY_REMOTE - asyncns_t *asyncns, + asyncns_t *asyncns, #endif - int method, int timeout, const char *iface); + int method, int timeout, const char *iface); #endif // _INCLUDE_H diff --git a/src/jconf.c b/src/jconf.c index 44bb482d..2154caa6 100644 --- a/src/jconf.c +++ b/src/jconf.c @@ -54,7 +54,8 @@ void parse_addr(const char *str, ss_addr_t *addr) ret = pch - str; pch = strchr(pch + 1, ':'); } - if (n > 1) { + if (n > 1) + { if (strcmp(str+ret, "]") != 0) { ret = -1; diff --git a/src/json.c b/src/json.c index 0eacf3d6..0ef381ed 100644 --- a/src/json.c +++ b/src/json.c @@ -30,15 +30,15 @@ #include "json.h" #ifdef _MSC_VER - #ifndef _CRT_SECURE_NO_WARNINGS - #define _CRT_SECURE_NO_WARNINGS - #endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif #endif #ifdef __cplusplus - const struct _json_value json_value_none; /* zero-d by ctor */ +const struct _json_value json_value_none; /* zero-d by ctor */ #else - const struct _json_value json_value_none = { 0 }; +const struct _json_value json_value_none = { 0 }; #endif #include @@ -50,91 +50,105 @@ typedef unsigned short json_uchar; static unsigned char hex_value (json_char c) { - if (isdigit((uint8_t)c)) - return c - '0'; - - switch (c) { - case 'a': case 'A': return 0x0A; - case 'b': case 'B': return 0x0B; - case 'c': case 'C': return 0x0C; - case 'd': case 'D': return 0x0D; - case 'e': case 'E': return 0x0E; - case 'f': case 'F': return 0x0F; - default: return 0xFF; - } + if (isdigit((uint8_t)c)) + return c - '0'; + + switch (c) + { + case 'a': + case 'A': + return 0x0A; + case 'b': + case 'B': + return 0x0B; + case 'c': + case 'C': + return 0x0C; + case 'd': + case 'D': + return 0x0D; + case 'e': + case 'E': + return 0x0E; + case 'f': + case 'F': + return 0x0F; + default: + return 0xFF; + } } typedef struct { - unsigned long used_memory; + unsigned long used_memory; - unsigned int uint_max; - unsigned long ulong_max; + unsigned int uint_max; + unsigned long ulong_max; - json_settings settings; - int first_pass; + json_settings settings; + int first_pass; } json_state; static void * default_alloc (size_t size, int zero, void * user_data) { - return zero ? calloc (1, size) : malloc (size); + return zero ? calloc (1, size) : malloc (size); } static void default_free (void * ptr, void * user_data) { - free (ptr); + free (ptr); } static void * json_alloc (json_state * state, unsigned long size, int zero) { - if ((state->ulong_max - state->used_memory) < size) - return 0; + if ((state->ulong_max - state->used_memory) < size) + return 0; - if (state->settings.max_memory - && (state->used_memory += size) > state->settings.max_memory) - { - return 0; - } + if (state->settings.max_memory + && (state->used_memory += size) > state->settings.max_memory) + { + return 0; + } - return state->settings.mem_alloc (size, zero, state->settings.user_data); + return state->settings.mem_alloc (size, zero, state->settings.user_data); } static int new_value - (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type) +(json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type) { - json_value * value; - int values_size; + json_value * value; + int values_size; - if (!state->first_pass) - { - value = *top = *alloc; - *alloc = (*alloc)->_reserved.next_alloc; + if (!state->first_pass) + { + value = *top = *alloc; + *alloc = (*alloc)->_reserved.next_alloc; - if (!*root) - *root = value; + if (!*root) + *root = value; - switch (value->type) - { - case json_array: + switch (value->type) + { + case json_array: if (! (value->u.array.values = (json_value **) json_alloc - (state, value->u.array.length * sizeof (json_value *), 0)) ) + (state, value->u.array.length * sizeof (json_value *), 0)) ) { - return 0; + return 0; } value->u.array.length = 0; break; - case json_object: + case json_object: values_size = sizeof (*value->u.object.values) * value->u.object.length; if (! ((*(void **) &value->u.object.values) = json_alloc - (state, values_size + ((size_t) value->u.object.values), 0)) ) + (state, values_size + ((size_t) value->u.object.values), 0)) ) { - return 0; + return 0; } value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; @@ -142,41 +156,41 @@ static int new_value value->u.object.length = 0; break; - case json_string: + case json_string: if (! (value->u.string.ptr = (json_char *) json_alloc - (state, (value->u.string.length + 1) * sizeof (json_char), 0)) ) + (state, (value->u.string.length + 1) * sizeof (json_char), 0)) ) { - return 0; + return 0; } value->u.string.length = 0; break; - default: + default: break; - }; + }; - return 1; - } + return 1; + } - value = (json_value *) json_alloc (state, sizeof (json_value), 1); + value = (json_value *) json_alloc (state, sizeof (json_value), 1); - if (!value) - return 0; + if (!value) + return 0; - if (!*root) - *root = value; + if (!*root) + *root = value; - value->type = type; - value->parent = *top; + value->type = type; + value->parent = *top; - if (*alloc) - (*alloc)->_reserved.next_alloc = value; + if (*alloc) + (*alloc)->_reserved.next_alloc = value; - *alloc = *top = value; + *alloc = *top = value; - return 1; + return 1; } #define e_off \ @@ -190,347 +204,367 @@ static int new_value do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); static const long - flag_next = 1 << 0, - flag_reproc = 1 << 1, - flag_need_comma = 1 << 2, - flag_seek_value = 1 << 3, - flag_escaped = 1 << 4, - flag_string = 1 << 5, - flag_need_colon = 1 << 6, - flag_done = 1 << 7, - flag_num_negative = 1 << 8, - flag_num_zero = 1 << 9, - flag_num_e = 1 << 10, - flag_num_e_got_sign = 1 << 11, - flag_num_e_negative = 1 << 12, - flag_line_comment = 1 << 13, - flag_block_comment = 1 << 14; +flag_next = 1 << 0, +flag_reproc = 1 << 1, +flag_need_comma = 1 << 2, +flag_seek_value = 1 << 3, +flag_escaped = 1 << 4, +flag_string = 1 << 5, +flag_need_colon = 1 << 6, +flag_done = 1 << 7, +flag_num_negative = 1 << 8, +flag_num_zero = 1 << 9, +flag_num_e = 1 << 10, +flag_num_e_got_sign = 1 << 11, +flag_num_e_negative = 1 << 12, +flag_line_comment = 1 << 13, +flag_block_comment = 1 << 14; json_value * json_parse_ex (json_settings * settings, const json_char * json, size_t length, char * error_buf) { - json_char error [json_error_max]; - unsigned int cur_line; - const json_char * cur_line_begin, * i, * end; - json_value * top, * root, * alloc = 0; - json_state state = { 0 }; - long flags; - long num_digits = 0, num_e = 0; - json_int_t num_fraction = 0; - - /* Skip UTF-8 BOM - */ - if (length >= 3 && ((unsigned char) json [0]) == 0xEF - && ((unsigned char) json [1]) == 0xBB - && ((unsigned char) json [2]) == 0xBF) - { - json += 3; - length -= 3; - } - - error[0] = '\0'; - end = (json + length); - - memcpy (&state.settings, settings, sizeof (json_settings)); - - if (!state.settings.mem_alloc) - state.settings.mem_alloc = default_alloc; - - if (!state.settings.mem_free) - state.settings.mem_free = default_free; - - memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); - memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); - - state.uint_max -= 8; /* limit of how much can be added before next check */ - state.ulong_max -= 8; - - for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass) - { - json_uchar uchar; - unsigned char uc_b1, uc_b2, uc_b3, uc_b4; - json_char * string = 0; - unsigned int string_length = 0; - - top = root = 0; - flags = flag_seek_value; - - cur_line = 1; - cur_line_begin = json; - - for (i = json ;; ++ i) - { - json_char b = (i == end ? 0 : *i); - - if (flags & flag_string) - { - if (!b) - { sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off); - goto e_failed; - } + json_char error [json_error_max]; + unsigned int cur_line; + const json_char * cur_line_begin, * i, * end; + json_value * top, * root, * alloc = 0; + json_state state = { 0 }; + long flags; + long num_digits = 0, num_e = 0; + json_int_t num_fraction = 0; + + /* Skip UTF-8 BOM + */ + if (length >= 3 && ((unsigned char) json [0]) == 0xEF + && ((unsigned char) json [1]) == 0xBB + && ((unsigned char) json [2]) == 0xBF) + { + json += 3; + length -= 3; + } + + error[0] = '\0'; + end = (json + length); + + memcpy (&state.settings, settings, sizeof (json_settings)); + + if (!state.settings.mem_alloc) + state.settings.mem_alloc = default_alloc; + + if (!state.settings.mem_free) + state.settings.mem_free = default_free; + + memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); + memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); + + state.uint_max -= 8; /* limit of how much can be added before next check */ + state.ulong_max -= 8; + + for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass) + { + json_uchar uchar; + unsigned char uc_b1, uc_b2, uc_b3, uc_b4; + json_char * string = 0; + unsigned int string_length = 0; + + top = root = 0; + flags = flag_seek_value; + + cur_line = 1; + cur_line_begin = json; + + for (i = json ;; ++ i) + { + json_char b = (i == end ? 0 : *i); + + if (flags & flag_string) + { + if (!b) + { + sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off); + goto e_failed; + } - if (string_length > state.uint_max) - goto e_overflow; + if (string_length > state.uint_max) + goto e_overflow; - if (flags & flag_escaped) - { - flags &= ~ flag_escaped; - - switch (b) - { - case 'b': string_add ('\b'); break; - case 'f': string_add ('\f'); break; - case 'n': string_add ('\n'); break; - case 'r': string_add ('\r'); break; - case 't': string_add ('\t'); break; - case 'u': - - if (end - i < 4 || - (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF - || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF) + if (flags & flag_escaped) + { + flags &= ~ flag_escaped; + + switch (b) { - sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off); - goto e_failed; - } + case 'b': + string_add ('\b'); + break; + case 'f': + string_add ('\f'); + break; + case 'n': + string_add ('\n'); + break; + case 'r': + string_add ('\r'); + break; + case 't': + string_add ('\t'); + break; + case 'u': - uc_b1 = uc_b1 * 16 + uc_b2; - uc_b2 = uc_b3 * 16 + uc_b4; + if (end - i < 4 || + (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF + || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF) + { + sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off); + goto e_failed; + } - uchar = ((json_char) uc_b1) * 256 + uc_b2; + uc_b1 = uc_b1 * 16 + uc_b2; + uc_b2 = uc_b3 * 16 + uc_b4; - if (sizeof (json_char) >= sizeof (json_uchar) || (uc_b1 == 0 && uc_b2 <= 0x7F)) - { - string_add ((json_char) uchar); - break; - } + uchar = ((json_char) uc_b1) * 256 + uc_b2; + + if (sizeof (json_char) >= sizeof (json_uchar) || (uc_b1 == 0 && uc_b2 <= 0x7F)) + { + string_add ((json_char) uchar); + break; + } + + if (uchar <= 0x7FF) + { + if (state.first_pass) + string_length += 2; + else + { + string [string_length ++] = 0xC0 | ((uc_b2 & 0xC0) >> 6) | ((uc_b1 & 0x7) << 2); + string [string_length ++] = 0x80 | (uc_b2 & 0x3F); + } + + break; + } - if (uchar <= 0x7FF) - { if (state.first_pass) - string_length += 2; + string_length += 3; else - { string [string_length ++] = 0xC0 | ((uc_b2 & 0xC0) >> 6) | ((uc_b1 & 0x7) << 2); - string [string_length ++] = 0x80 | (uc_b2 & 0x3F); + { + string [string_length ++] = 0xE0 | ((uc_b1 & 0xF0) >> 4); + string [string_length ++] = 0x80 | ((uc_b1 & 0xF) << 2) | ((uc_b2 & 0xC0) >> 6); + string [string_length ++] = 0x80 | (uc_b2 & 0x3F); } break; - } - if (state.first_pass) - string_length += 3; - else - { string [string_length ++] = 0xE0 | ((uc_b1 & 0xF0) >> 4); - string [string_length ++] = 0x80 | ((uc_b1 & 0xF) << 2) | ((uc_b2 & 0xC0) >> 6); - string [string_length ++] = 0x80 | (uc_b2 & 0x3F); - } + default: + string_add (b); + }; - break; + continue; + } - default: - string_add (b); - }; + if (b == '\\') + { + flags |= flag_escaped; + continue; + } - continue; - } - - if (b == '\\') - { - flags |= flag_escaped; - continue; - } - - if (b == '"') - { - if (!state.first_pass) - string [string_length] = 0; + if (b == '"') + { + if (!state.first_pass) + string [string_length] = 0; - flags &= ~ flag_string; - string = 0; + flags &= ~ flag_string; + string = 0; - switch (top->type) - { - case json_string: + switch (top->type) + { + case json_string: - top->u.string.length = string_length; - flags |= flag_next; + top->u.string.length = string_length; + flags |= flag_next; - break; + break; - case json_object: + case json_object: - if (state.first_pass) - (*(json_char **) &top->u.object.values) += string_length + 1; - else - { - top->u.object.values [top->u.object.length].name - = (json_char *) top->_reserved.object_mem; + if (state.first_pass) + (*(json_char **) &top->u.object.values) += string_length + 1; + else + { + top->u.object.values [top->u.object.length].name + = (json_char *) top->_reserved.object_mem; - top->u.object.values [top->u.object.length].name_length - = string_length; + top->u.object.values [top->u.object.length].name_length + = string_length; - (*(json_char **) &top->_reserved.object_mem) += string_length + 1; - } + (*(json_char **) &top->_reserved.object_mem) += string_length + 1; + } - flags |= flag_seek_value | flag_need_colon; - continue; + flags |= flag_seek_value | flag_need_colon; + continue; - default: - break; - }; - } - else - { - string_add (b); - continue; + default: + break; + }; + } + else + { + string_add (b); + continue; + } } - } - if (state.settings.settings & json_enable_comments) - { - if (flags & (flag_line_comment | flag_block_comment)) - { - if (flags & flag_line_comment) - { - if (b == '\r' || b == '\n' || !b) - { - flags &= ~ flag_line_comment; - -- i; /* so null can be reproc'd */ - } - - continue; - } - - if (flags & flag_block_comment) - { - if (!b) - { sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off); - goto e_failed; - } - - if (b == '*' && i < (end - 1) && i [1] == '/') - { - flags &= ~ flag_block_comment; - ++ i; /* skip closing sequence */ - } - - continue; - } - } - else if (b == '/') + if (state.settings.settings & json_enable_comments) { - if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object) - { - sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off); - goto e_failed; - } - - if (++ i == end) - { sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off); - goto e_failed; - } - - switch (b = *i) - { - case '/': - flags |= flag_line_comment; - continue; - - case '*': - flags |= flag_block_comment; - continue; - - default: - sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b); - goto e_failed; - }; - } - } + if (flags & (flag_line_comment | flag_block_comment)) + { + if (flags & flag_line_comment) + { + if (b == '\r' || b == '\n' || !b) + { + flags &= ~ flag_line_comment; + -- i; /* so null can be reproc'd */ + } - if (flags & flag_done) - { - if (!b) - break; + continue; + } - switch (b) - { - whitespace: - continue; - - default: - sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b); - goto e_failed; - }; - } - - if (flags & flag_seek_value) - { - switch (b) - { - whitespace: - continue; + if (flags & flag_block_comment) + { + if (!b) + { + sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off); + goto e_failed; + } - case ']': + if (b == '*' && i < (end - 1) && i [1] == '/') + { + flags &= ~ flag_block_comment; + ++ i; /* skip closing sequence */ + } - if (top->type == json_array) - flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; - else - { sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off); - goto e_failed; - } + continue; + } + } + else if (b == '/') + { + if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object) + { + sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off); + goto e_failed; + } - break; + if (++ i == end) + { + sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off); + goto e_failed; + } - default: + switch (b = *i) + { + case '/': + flags |= flag_line_comment; + continue; - if (flags & flag_need_comma) - { - if (b == ',') - { flags &= ~ flag_need_comma; + case '*': + flags |= flag_block_comment; continue; - } - else - { sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b); + + default: + sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b); goto e_failed; - } - } + }; + } + } - if (flags & flag_need_colon) - { - if (b == ':') - { flags &= ~ flag_need_colon; - continue; - } - else - { sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b); + if (flags & flag_done) + { + if (!b) + break; + + switch (b) + { +whitespace: + continue; + + default: + sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b); + goto e_failed; + }; + } + + if (flags & flag_seek_value) + { + switch (b) + { +whitespace: + continue; + + case ']': + + if (top->type == json_array) + flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; + else + { + sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off); goto e_failed; - } - } + } - flags &= ~ flag_seek_value; + break; - switch (b) - { - case '{': + default: + + if (flags & flag_need_comma) + { + if (b == ',') + { + flags &= ~ flag_need_comma; + continue; + } + else + { + sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b); + goto e_failed; + } + } + + if (flags & flag_need_colon) + { + if (b == ':') + { + flags &= ~ flag_need_colon; + continue; + } + else + { + sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b); + goto e_failed; + } + } + + flags &= ~ flag_seek_value; + + switch (b) + { + case '{': if (!new_value (&state, &top, &root, &alloc, json_object)) - goto e_alloc_failure; + goto e_alloc_failure; continue; - case '[': + case '[': if (!new_value (&state, &top, &root, &alloc, json_array)) - goto e_alloc_failure; + goto e_alloc_failure; flags |= flag_seek_value; continue; - case '"': + case '"': if (!new_value (&state, &top, &root, &alloc, json_string)) - goto e_alloc_failure; + goto e_alloc_failure; flags |= flag_string; @@ -539,412 +573,417 @@ json_value * json_parse_ex (json_settings * settings, continue; - case 't': + case 't': if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e') - goto e_unknown_value; + goto e_unknown_value; if (!new_value (&state, &top, &root, &alloc, json_boolean)) - goto e_alloc_failure; + goto e_alloc_failure; top->u.boolean = 1; flags |= flag_next; break; - case 'f': + case 'f': if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e') - goto e_unknown_value; + goto e_unknown_value; if (!new_value (&state, &top, &root, &alloc, json_boolean)) - goto e_alloc_failure; + goto e_alloc_failure; flags |= flag_next; break; - case 'n': + case 'n': if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l') - goto e_unknown_value; + goto e_unknown_value; if (!new_value (&state, &top, &root, &alloc, json_null)) - goto e_alloc_failure; + goto e_alloc_failure; flags |= flag_next; break; - default: + default: if (isdigit ((uint8_t)b) || b == '-') { - if (!new_value (&state, &top, &root, &alloc, json_integer)) - goto e_alloc_failure; + if (!new_value (&state, &top, &root, &alloc, json_integer)) + goto e_alloc_failure; - if (!state.first_pass) - { - while (isdigit ((uint8_t)b) || b == '+' || b == '-' + if (!state.first_pass) + { + while (isdigit ((uint8_t)b) || b == '+' || b == '-' || b == 'e' || b == 'E' || b == '.') - { - if ( (++ i) == end) - { - b = 0; - break; - } + { + if ( (++ i) == end) + { + b = 0; + break; + } - b = *i; - } + b = *i; + } - flags |= flag_next | flag_reproc; - break; - } + flags |= flag_next | flag_reproc; + break; + } - flags &= ~ (flag_num_negative | flag_num_e | + flags &= ~ (flag_num_negative | flag_num_e | flag_num_e_got_sign | flag_num_e_negative | - flag_num_zero); + flag_num_zero); - num_digits = 0; - num_fraction = 0; - num_e = 0; + num_digits = 0; + num_fraction = 0; + num_e = 0; - if (b != '-') - { - flags |= flag_reproc; - break; - } + if (b != '-') + { + flags |= flag_reproc; + break; + } - flags |= flag_num_negative; - continue; + flags |= flag_num_negative; + continue; } else - { sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b); - goto e_failed; + { + sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b); + goto e_failed; } - }; - }; - } - else - { - switch (top->type) + }; + }; + } + else { - case json_object: + switch (top->type) + { + case json_object: - switch (b) - { - whitespace: - continue; + switch (b) + { +whitespace: + continue; - case '"': + case '"': - if (flags & flag_need_comma) - { - sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off); - goto e_failed; - } + if (flags & flag_need_comma) + { + sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off); + goto e_failed; + } - flags |= flag_string; + flags |= flag_string; - string = (json_char *) top->_reserved.object_mem; - string_length = 0; + string = (json_char *) top->_reserved.object_mem; + string_length = 0; - break; + break; - case '}': + case '}': - flags = (flags & ~ flag_need_comma) | flag_next; - break; + flags = (flags & ~ flag_need_comma) | flag_next; + break; - case ',': + case ',': - if (flags & flag_need_comma) - { - flags &= ~ flag_need_comma; - break; - } + if (flags & flag_need_comma) + { + flags &= ~ flag_need_comma; + break; + } - default: + default: - sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b); - goto e_failed; - }; + sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b); + goto e_failed; + }; - break; + break; - case json_integer: - case json_double: + case json_integer: + case json_double: - if (isdigit ((uint8_t)b)) - { - ++ num_digits; + if (isdigit ((uint8_t)b)) + { + ++ num_digits; - if (top->type == json_integer || flags & flag_num_e) - { - if (! (flags & flag_num_e)) - { - if (flags & flag_num_zero) - { sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b); - goto e_failed; + if (top->type == json_integer || flags & flag_num_e) + { + if (! (flags & flag_num_e)) + { + if (flags & flag_num_zero) + { + sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b); + goto e_failed; + } + + if (num_digits == 1 && b == '0') + flags |= flag_num_zero; + } + else + { + flags |= flag_num_e_got_sign; + num_e = (num_e * 10) + (b - '0'); + continue; + } + + top->u.integer = (top->u.integer * 10) + (b - '0'); + continue; } - if (num_digits == 1 && b == '0') - flags |= flag_num_zero; - } - else - { - flags |= flag_num_e_got_sign; - num_e = (num_e * 10) + (b - '0'); + num_fraction = (num_fraction * 10) + (b - '0'); continue; - } - - top->u.integer = (top->u.integer * 10) + (b - '0'); - continue; - } - - num_fraction = (num_fraction * 10) + (b - '0'); - continue; - } - - if (b == '+' || b == '-') - { - if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) - { - flags |= flag_num_e_got_sign; - - if (b == '-') - flags |= flag_num_e_negative; - - continue; - } - } - else if (b == '.' && top->type == json_integer) - { - if (!num_digits) - { sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off); - goto e_failed; - } - - top->type = json_double; - top->u.dbl = (double) top->u.integer; - - num_digits = 0; - continue; - } - - if (! (flags & flag_num_e)) - { - if (top->type == json_double) - { - if (!num_digits) - { sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off); - goto e_failed; - } + } - top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits)); - } + if (b == '+' || b == '-') + { + if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) + { + flags |= flag_num_e_got_sign; + + if (b == '-') + flags |= flag_num_e_negative; - if (b == 'e' || b == 'E') - { - flags |= flag_num_e; + continue; + } + } + else if (b == '.' && top->type == json_integer) + { + if (!num_digits) + { + sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off); + goto e_failed; + } - if (top->type == json_integer) - { top->type = json_double; top->u.dbl = (double) top->u.integer; - } - - num_digits = 0; - flags &= ~ flag_num_zero; - - continue; - } - } - else - { - if (!num_digits) - { sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off); - goto e_failed; - } - - top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e)); - } - - if (flags & flag_num_negative) - { - if (top->type == json_integer) - top->u.integer = - top->u.integer; - else - top->u.dbl = - top->u.dbl; - } - - flags |= flag_next | flag_reproc; - break; - - default: - break; - }; - } - - if (flags & flag_reproc) - { - flags &= ~ flag_reproc; - -- i; - } - - if (flags & flag_next) - { - flags = (flags & ~ flag_next) | flag_need_comma; - - if (!top->parent) - { - /* root value done */ - flags |= flag_done; - continue; + num_digits = 0; + continue; + } + + if (! (flags & flag_num_e)) + { + if (top->type == json_double) + { + if (!num_digits) + { + sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off); + goto e_failed; + } + + top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits)); + } + + if (b == 'e' || b == 'E') + { + flags |= flag_num_e; + + if (top->type == json_integer) + { + top->type = json_double; + top->u.dbl = (double) top->u.integer; + } + + num_digits = 0; + flags &= ~ flag_num_zero; + + continue; + } + } + else + { + if (!num_digits) + { + sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off); + goto e_failed; + } + + top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e)); + } + + if (flags & flag_num_negative) + { + if (top->type == json_integer) + top->u.integer = - top->u.integer; + else + top->u.dbl = - top->u.dbl; + } + + flags |= flag_next | flag_reproc; + break; + + default: + break; + }; } - if (top->parent->type == json_array) - flags |= flag_seek_value; + if (flags & flag_reproc) + { + flags &= ~ flag_reproc; + -- i; + } - if (!state.first_pass) + if (flags & flag_next) { - json_value * parent = top->parent; + flags = (flags & ~ flag_next) | flag_need_comma; - switch (parent->type) - { - case json_object: + if (!top->parent) + { + /* root value done */ - parent->u.object.values + flags |= flag_done; + continue; + } + + if (top->parent->type == json_array) + flags |= flag_seek_value; + + if (!state.first_pass) + { + json_value * parent = top->parent; + + switch (parent->type) + { + case json_object: + + parent->u.object.values [parent->u.object.length].value = top; - break; + break; - case json_array: + case json_array: - parent->u.array.values - [parent->u.array.length] = top; + parent->u.array.values + [parent->u.array.length] = top; - break; + break; - default: - break; - }; - } + default: + break; + }; + } - if ( (++ top->parent->u.array.length) > state.uint_max) - goto e_overflow; + if ( (++ top->parent->u.array.length) > state.uint_max) + goto e_overflow; - top = top->parent; + top = top->parent; - continue; - } - } + continue; + } + } - alloc = root; - } + alloc = root; + } - return root; + return root; e_unknown_value: - sprintf (error, "%d:%d: Unknown value", cur_line, e_off); - goto e_failed; + sprintf (error, "%d:%d: Unknown value", cur_line, e_off); + goto e_failed; e_alloc_failure: - strcpy (error, "Memory allocation failure"); - goto e_failed; + strcpy (error, "Memory allocation failure"); + goto e_failed; e_overflow: - sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off); - goto e_failed; + sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off); + goto e_failed; e_failed: - if (error_buf) - { - if (*error) - strcpy (error_buf, error); - else - strcpy (error_buf, "Unknown error"); - } + if (error_buf) + { + if (*error) + strcpy (error_buf, error); + else + strcpy (error_buf, "Unknown error"); + } - if (state.first_pass) - alloc = root; + if (state.first_pass) + alloc = root; - while (alloc) - { - top = alloc->_reserved.next_alloc; - state.settings.mem_free (alloc, state.settings.user_data); - alloc = top; - } + while (alloc) + { + top = alloc->_reserved.next_alloc; + state.settings.mem_free (alloc, state.settings.user_data); + alloc = top; + } - if (!state.first_pass) - json_value_free_ex (&state.settings, root); + if (!state.first_pass) + json_value_free_ex (&state.settings, root); - return 0; + return 0; } json_value * json_parse (const json_char * json, size_t length) { - json_settings settings = { 0 }; - return json_parse_ex (&settings, json, length, 0); + json_settings settings = { 0 }; + return json_parse_ex (&settings, json, length, 0); } void json_value_free_ex (json_settings * settings, json_value * value) { - json_value * cur_value; + json_value * cur_value; - if (!value) - return; + if (!value) + return; - value->parent = 0; + value->parent = 0; - while (value) - { - switch (value->type) - { - case json_array: + while (value) + { + switch (value->type) + { + case json_array: if (!value->u.array.length) { - settings->mem_free (value->u.array.values, settings->user_data); - break; + settings->mem_free (value->u.array.values, settings->user_data); + break; } value = value->u.array.values [-- value->u.array.length]; continue; - case json_object: + case json_object: if (!value->u.object.length) { - settings->mem_free (value->u.object.values, settings->user_data); - break; + settings->mem_free (value->u.object.values, settings->user_data); + break; } value = value->u.object.values [-- value->u.object.length].value; continue; - case json_string: + case json_string: settings->mem_free (value->u.string.ptr, settings->user_data); break; - default: + default: break; - }; + }; - cur_value = value; - value = value->parent; - settings->mem_free (cur_value, settings->user_data); - } + cur_value = value; + value = value->parent; + settings->mem_free (cur_value, settings->user_data); + } } void json_value_free (json_value * value) { - json_settings settings = { 0 }; - settings.mem_free = default_free; - json_value_free_ex (&settings, value); + json_settings settings = { 0 }; + settings.mem_free = default_free; + json_value_free_ex (&settings, value); } diff --git a/src/json.h b/src/json.h index cf9f0dd5..61d65aea 100644 --- a/src/json.h +++ b/src/json.h @@ -32,41 +32,41 @@ #define _JSON_H #ifndef json_char - #define json_char char +#define json_char char #endif #ifndef json_int_t - #ifndef _MSC_VER - #include - #define json_int_t int64_t - #else - #define json_int_t __int64 - #endif +#ifndef _MSC_VER +#include +#define json_int_t int64_t +#else +#define json_int_t __int64 +#endif #endif #include #ifdef __cplusplus - #include +#include - extern "C" - { +extern "C" +{ #endif typedef struct { - unsigned long max_memory; - int settings; + unsigned long max_memory; + int settings; - /* Custom allocator support (leave null to use malloc/free) - */ + /* Custom allocator support (leave null to use malloc/free) + */ - void * (* mem_alloc) (size_t, int zero, void * user_data); - void (* mem_free) (void *, void * user_data); + void * (* mem_alloc) (size_t, int zero, void * user_data); + void (* mem_free) (void *, void * user_data); - void * user_data; /* will be passed to mem_alloc and mem_free */ + void * user_data; /* will be passed to mem_alloc and mem_free */ } json_settings; @@ -74,14 +74,14 @@ typedef struct typedef enum { - json_none, - json_object, - json_array, - json_integer, - json_double, - json_string, - json_boolean, - json_null + json_none, + json_object, + json_array, + json_integer, + json_double, + json_string, + json_boolean, + json_null } json_type; @@ -89,181 +89,186 @@ extern const struct _json_value json_value_none; typedef struct _json_value { - struct _json_value * parent; - - json_type type; - - union - { - int boolean; - json_int_t integer; - double dbl; + struct _json_value * parent; - struct - { - unsigned int length; - json_char * ptr; /* null terminated */ + json_type type; - } string; + union + { + int boolean; + json_int_t integer; + double dbl; - struct - { - unsigned int length; + struct + { + unsigned int length; + json_char * ptr; /* null terminated */ - struct - { - json_char * name; - unsigned int name_length; + } string; - struct _json_value * value; + struct + { + unsigned int length; - } * values; - - #if defined(__cplusplus) && __cplusplus >= 201103L - decltype(values) begin () const - { return values; - } - decltype(values) end () const - { return values + length; - } - #endif - - } object; + struct + { + json_char * name; + unsigned int name_length; + + struct _json_value * value; + + } * values; + +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin () const + { + return values; + } + decltype(values) end () const + { + return values + length; + } +#endif - struct - { - unsigned int length; - struct _json_value ** values; + } object; - #if defined(__cplusplus) && __cplusplus >= 201103L - decltype(values) begin () const - { return values; - } - decltype(values) end () const - { return values + length; - } - #endif + struct + { + unsigned int length; + struct _json_value ** values; + +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin () const + { + return values; + } + decltype(values) end () const + { + return values + length; + } +#endif - } array; + } array; - } u; + } u; - union - { - struct _json_value * next_alloc; - void * object_mem; + union + { + struct _json_value * next_alloc; + void * object_mem; - } _reserved; + } _reserved; - /* Some C++ operator sugar */ + /* Some C++ operator sugar */ - #ifdef __cplusplus +#ifdef __cplusplus - public: + public: - inline _json_value () - { memset (this, 0, sizeof (_json_value)); - } + inline _json_value () + { + memset (this, 0, sizeof (_json_value)); + } - inline const struct _json_value &operator [] (int index) const - { + inline const struct _json_value &operator [] (int index) const + { if (type != json_array || index < 0 - || ((unsigned int) index) >= u.array.length) + || ((unsigned int) index) >= u.array.length) { - return json_value_none; + return json_value_none; } return *u.array.values [index]; - } + } - inline const struct _json_value &operator [] (const char * index) const - { + inline const struct _json_value &operator [] (const char * index) const + { if (type != json_object) - return json_value_none; + return json_value_none; for (unsigned int i = 0; i < u.object.length; ++ i) - if (!strcmp (u.object.values [i].name, index)) - return *u.object.values [i].value; + if (!strcmp (u.object.values [i].name, index)) + return *u.object.values [i].value; return json_value_none; - } + } - inline operator const char * () const - { + inline operator const char * () const + { switch (type) { - case json_string: - return u.string.ptr; + case json_string: + return u.string.ptr; - default: - return ""; + default: + return ""; }; - } + } - inline operator json_int_t () const - { + inline operator json_int_t () const + { switch (type) { - case json_integer: - return u.integer; + case json_integer: + return u.integer; - case json_double: - return (json_int_t) u.dbl; + case json_double: + return (json_int_t) u.dbl; - default: - return 0; + default: + return 0; }; - } + } - inline operator bool () const - { + inline operator bool () const + { if (type != json_boolean) - return false; + return false; return u.boolean != 0; - } + } - inline operator double () const - { + inline operator double () const + { switch (type) { - case json_integer: - return (double) u.integer; + case json_integer: + return (double) u.integer; - case json_double: - return u.dbl; + case json_double: + return u.dbl; - default: - return 0; + default: + return 0; }; - } + } - #endif +#endif -} json_value; + } json_value; -json_value * json_parse (const json_char * json, - size_t length); + json_value * json_parse (const json_char * json, + size_t length); #define json_error_max 128 -json_value * json_parse_ex (json_settings * settings, - const json_char * json, - size_t length, - char * error); + json_value * json_parse_ex (json_settings * settings, + const json_char * json, + size_t length, + char * error); -void json_value_free (json_value *); + void json_value_free (json_value *); -/* Not usually necessary, unless you used a custom mem_alloc and now want to - * use a custom mem_free. - */ -void json_value_free_ex (json_settings * settings, - json_value *); + /* Not usually necessary, unless you used a custom mem_alloc and now want to + * use a custom mem_free. + */ + void json_value_free_ex (json_settings * settings, + json_value *); #ifdef __cplusplus - } /* extern "C" */ +} /* extern "C" */ #endif #endif diff --git a/src/local.c b/src/local.c index 81f290d8..2b72b251 100644 --- a/src/local.c +++ b/src/local.c @@ -361,7 +361,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) return; } - if (request->cmd == 3) { + if (request->cmd == 3) + { close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; diff --git a/src/tunnel.c b/src/tunnel.c index 4c06119c..9fc24419 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -874,7 +874,7 @@ int main (int argc, char **argv) { LOGD("udprelay enabled."); udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port, - tunnel_addr, m, listen_ctx.timeout, iface); + tunnel_addr, m, listen_ctx.timeout, iface); } // setuid diff --git a/src/udprelay.c b/src/udprelay.c index 2b497892..826224dd 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -158,23 +158,24 @@ static char *get_addr_str(const struct sockaddr *sa) char port[PORTSTRLEN] = {0}; uint16_t p; - switch(sa->sa_family) { - case AF_INET: - inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), - addr, INET_ADDRSTRLEN); - p = ntohs(((struct sockaddr_in *)sa)->sin_port); - sprintf(port, "%d", p); - break; + switch(sa->sa_family) + { + case AF_INET: + inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), + addr, INET_ADDRSTRLEN); + p = ntohs(((struct sockaddr_in *)sa)->sin_port); + sprintf(port, "%d", p); + break; - case AF_INET6: - inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), - addr, INET6_ADDRSTRLEN); - p = ntohs(((struct sockaddr_in *)sa)->sin_port); - sprintf(port, "%d", p); - break; + case AF_INET6: + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), + addr, INET6_ADDRSTRLEN); + p = ntohs(((struct sockaddr_in *)sa)->sin_port); + sprintf(port, "%d", p); + break; - default: - strncpy(s, "Unknown AF", SS_ADDRSTRLEN); + default: + strncpy(s, "Unknown AF", SS_ADDRSTRLEN); } int addr_len = strlen(addr); @@ -504,7 +505,8 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) #ifdef UDPRELAY_LOCAL buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); - if (buf == NULL){ + if (buf == NULL) + { if (verbose) { ERROR("udprelay_server_ss_decrypt_all"); @@ -587,7 +589,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) #ifdef UDPRELAY_REMOTE buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); - if (buf == NULL){ + if (buf == NULL) + { if (verbose) { ERROR("udprelay_server_ss_decrypt_all"); @@ -808,7 +811,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) } struct query_ctx *query_ctx = new_query_ctx(query, buf + addr_header_len, - buf_len - addr_header_len); + buf_len - addr_header_len); query_ctx->server_ctx = server_ctx; query_ctx->addr_header_len = addr_header_len; query_ctx->src_addr = src_addr; @@ -820,7 +823,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) else { int s = sendto(remote_ctx->fd, buf + addr_header_len, - buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr)); + buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr)); if (s == -1) { @@ -848,15 +851,15 @@ void free_cb(void *element) int udprelay_init(const char *server_host, const char *server_port, #ifdef UDPRELAY_LOCAL - const char *remote_host, const char *remote_port, + const char *remote_host, const char *remote_port, #ifdef UDPRELAY_TUNNEL - const ss_addr_t tunnel_addr, + const ss_addr_t tunnel_addr, #endif #endif #ifdef UDPRELAY_REMOTE - asyncns_t *asyncns, + asyncns_t *asyncns, #endif - int method, int timeout, const char *iface) + int method, int timeout, const char *iface) { // Inilitialize ev loop diff --git a/src/utils.c b/src/utils.c index 37e619ae..e576b374 100644 --- a/src/utils.c +++ b/src/utils.c @@ -68,83 +68,83 @@ char *itoa(int i) int run_as(const char *user) { #ifndef __MINGW32__ - if (user[0]) + if (user[0]) { #ifdef HAVE_GETPWNAM_R - struct passwd pwdbuf, *pwd; - size_t buflen; - int err; + struct passwd pwdbuf, *pwd; + size_t buflen; + int err; - for (buflen = 128;; buflen *= 2) + for (buflen = 128;; buflen *= 2) { - char buf[buflen]; /* variable length array */ + char buf[buflen]; /* variable length array */ - /* Note that we use getpwnam_r() instead of getpwnam(), - which returns its result in a statically allocated buffer and - cannot be considered thread safe. */ - err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); - if(err == 0 && pwd) + /* Note that we use getpwnam_r() instead of getpwnam(), + which returns its result in a statically allocated buffer and + cannot be considered thread safe. */ + err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); + if(err == 0 && pwd) { - /* setgid first, because we may not be allowed to do it anymore after setuid */ - if (setgid(pwd->pw_gid) != 0) + /* setgid first, because we may not be allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid) != 0) { - LOGE("Could not change group id to that of run_as user '%s': %s", - user,strerror(errno)); - return 0; - } + LOGE("Could not change group id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } - if (setuid(pwd->pw_uid) != 0) + if (setuid(pwd->pw_uid) != 0) { - LOGE("Could not change user id to that of run_as user '%s': %s", - user,strerror(errno)); - return 0; - } - break; - } - else if (err != ERANGE) + LOGE("Could not change user id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + break; + } + else if (err != ERANGE) { - if(err) - LOGE("run_as user '%s' could not be found: %s",user,strerror(err)); - else - LOGE("run_as user '%s' could not be found.",user); - return 0; - } - else if (buflen >= 16*1024) + if(err) + LOGE("run_as user '%s' could not be found: %s",user,strerror(err)); + else + LOGE("run_as user '%s' could not be found.",user); + return 0; + } + else if (buflen >= 16*1024) { - /* If getpwnam_r() seems defective, call it quits rather than - keep on allocating ever larger buffers until we crash. */ - LOGE("getpwnam_r() requires more than %u bytes of buffer space.",(unsigned)buflen); - return 0; - } - /* Else try again with larger buffer. */ - } + /* If getpwnam_r() seems defective, call it quits rather than + keep on allocating ever larger buffers until we crash. */ + LOGE("getpwnam_r() requires more than %u bytes of buffer space.",(unsigned)buflen); + return 0; + } + /* Else try again with larger buffer. */ + } #else - /* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */ - struct passwd *pwd; + /* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */ + struct passwd *pwd; - if (!(pwd=getpwnam(user))) + if (!(pwd=getpwnam(user))) { - LOGE("run_as user %s could not be found.",user); - return 0; - } - /* setgid first, because we may not allowed to do it anymore after setuid */ - if (setgid(pwd->pw_gid) != 0) + LOGE("run_as user %s could not be found.",user); + return 0; + } + /* setgid first, because we may not allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid) != 0) { - LOGE("Could not change group id to that of run_as user '%s': %s", - user,strerror(errno)); - return 0; - } - if (setuid(pwd->pw_uid) != 0) + LOGE("Could not change group id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + if (setuid(pwd->pw_uid) != 0) { - LOGE("Could not change user id to that of run_as user '%s': %s", - user,strerror(errno)); - return 0; - } + LOGE("Could not change user id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } #endif - } + } #endif //__MINGW32__ - return 1; + return 1; } diff --git a/src/win32.c b/src/win32.c index c00f5f9e..8f50dd91 100644 --- a/src/win32.c +++ b/src/win32.c @@ -11,10 +11,12 @@ void winsock_init(void) int ret; wVersionRequested = MAKEWORD(1, 1); ret = WSAStartup(wVersionRequested, &wsaData); - if (ret != 0) { + if (ret != 0) + { FATAL("Could not initialize winsock"); } - if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { + if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) + { WSACleanup(); FATAL("Could not find a usable version of winsock"); } @@ -28,11 +30,12 @@ void winsock_cleanup(void) void ss_error(const char *s) { LPVOID *msg = NULL; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL); - if (msg != NULL) { + if (msg != NULL) + { LOGE("%s: %s", s, (char *)msg); LocalFree(msg); } @@ -43,7 +46,8 @@ int setnonblocking(int fd) u_long iMode = 0; long int iResult; iResult = ioctlsocket(fd, FIONBIO, &iMode); - if (iResult != NO_ERROR) { + if (iResult != NO_ERROR) + { LOGE("ioctlsocket failed with error: %ld\n", iResult); } return iResult; @@ -61,15 +65,16 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) unsigned long s = size; ZeroMemory(&ss, sizeof(ss)); ss.ss_family = af; - switch (af) { - case AF_INET: - ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; - break; - default: - return NULL; + switch (af) + { + case AF_INET: + ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; + break; + case AF_INET6: + ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; + break; + default: + return NULL; } return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL; }