Beispiel #1
0
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;
}
Beispiel #2
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;
}