static int json_get_string_size(struct json_parse_state_s* state) { const size_t initial_offset = state->offset; state->dom_size += sizeof(struct json_string_s); if ('"' != state->src[state->offset]) { // expected string to begin with '"'! return 1; } // skip leading '"' state->offset++; while (state->offset < state->size && '"' != state->src[state->offset]) { if ('\\' == state->src[state->offset]) { // skip reverse solidus character state->offset++; if (state->offset == state->size) { // string can't terminate here! return 1; } switch (state->src[state->offset]) { default: // invalid escaped sequence in string! return 1; case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': case 't': // all valid characters! state->offset++; break; case 'u': if (state->offset + 5 < state->size) { // invalid escaped unicode sequence! return 1; } else if ( !json_is_hexadecimal_digit(state->src[state->offset + 1]) || !json_is_hexadecimal_digit(state->src[state->offset + 2]) || !json_is_hexadecimal_digit(state->src[state->offset + 3]) || !json_is_hexadecimal_digit(state->src[state->offset + 4])) { // escaped unicode sequences must contain 4 hexadecimal digits! return 1; } // valid sequence! state->offset += 5; break; } } else { // skip character (valid part of sequence) state->offset++; } } // skip trailing '"' state->offset++; state->data_size += state->offset - initial_offset; return 0; }
static int json_get_string_size(struct json_parse_state_s *state) { size_t data_size = 0; state->dom_size += sizeof(struct json_string_s); if ('"' != state->src[state->offset]) { state->error = json_parse_error_expected_opening_quote; return 1; } // skip leading '"' state->offset++; while (state->offset < state->size && '"' != state->src[state->offset]) { // add space for the character data_size++; if ('\\' == state->src[state->offset]) { // skip reverse solidus character state->offset++; if (state->offset == state->size) { // string can't terminate here! return 1; } switch (state->src[state->offset]) { default: state->error = json_parse_error_invalid_string_escape_sequence; return 1; case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': case 't': // all valid characters! state->offset++; // if we have to preserve reverse solidus... if (!(json_parse_flags_allow_string_simplification & state->flags_bitset)) { // ... allocate enough space for it data_size++; } break; case 'u': if (state->offset + 5 < state->size) { // invalid escaped unicode sequence! state->error = json_parse_error_invalid_string_escape_sequence; return 1; } else if (!json_is_hexadecimal_digit(state->src[state->offset + 1]) || !json_is_hexadecimal_digit(state->src[state->offset + 2]) || !json_is_hexadecimal_digit(state->src[state->offset + 3]) || !json_is_hexadecimal_digit(state->src[state->offset + 4])) { // escaped unicode sequences must contain 4 hexadecimal digits! state->error = json_parse_error_invalid_string_escape_sequence; return 1; } // valid sequence! state->offset += 5; // add space for the 5 character sequence too data_size += 5; break; } } else { // skip character (valid part of sequence) state->offset++; } } // skip trailing '"' state->offset++; // add enough space to store the string state->data_size += data_size; // one more byte for null terminator ending the string! state->data_size++; return 0; }