in sdk/src/azure/core/az_json_reader.c [240:355]
AZ_NODISCARD static az_result _az_json_reader_process_string(az_json_reader* ref_json_reader)
{
// Move past the first '"' character
ref_json_reader->_internal.bytes_consumed++;
az_span token = _get_remaining_json(ref_json_reader);
int32_t remaining_size = az_span_size(token);
if (remaining_size < 1)
{
_az_RETURN_IF_FAILED(_az_json_reader_get_next_buffer(ref_json_reader, &token, false));
remaining_size = az_span_size(token);
}
int32_t current_index = 0;
int32_t string_length = 0;
uint8_t* token_ptr = az_span_ptr(token);
uint8_t next_byte = token_ptr[0];
// Clear the state of any previous string token.
ref_json_reader->token._internal.string_has_escaped_chars = false;
while (true)
{
if (next_byte == '"')
{
break;
}
if (next_byte == '\\')
{
ref_json_reader->token._internal.string_has_escaped_chars = true;
current_index++;
string_length++;
if (current_index >= remaining_size)
{
_az_RETURN_IF_FAILED(_az_json_reader_get_next_buffer(ref_json_reader, &token, false));
current_index = 0;
token_ptr = az_span_ptr(token);
remaining_size = az_span_size(token);
}
next_byte = token_ptr[current_index];
if (next_byte == 'u')
{
current_index++;
string_length++;
// Expecting 4 hex digits to follow the escaped 'u'
for (int32_t i = 0; i < 4; i++)
{
if (current_index >= remaining_size)
{
_az_RETURN_IF_FAILED(_az_json_reader_get_next_buffer(ref_json_reader, &token, false));
current_index = 0;
token_ptr = az_span_ptr(token);
remaining_size = az_span_size(token);
}
string_length++;
next_byte = token_ptr[current_index++];
if (!isxdigit(next_byte))
{
return AZ_ERROR_UNEXPECTED_CHAR;
}
}
// We have already skipped past the u and 4 hex digits. The loop accounts for incrementing
// by 1 more, so subtract one to account for that.
current_index--;
string_length--;
}
else
{
if (!_az_is_valid_escaped_character(next_byte))
{
return AZ_ERROR_UNEXPECTED_CHAR;
}
}
}
else
{
// Control characters are invalid within a JSON string and should be correctly escaped.
if (next_byte < _az_ASCII_SPACE_CHARACTER)
{
return AZ_ERROR_UNEXPECTED_CHAR;
}
}
current_index++;
string_length++;
if (current_index >= remaining_size)
{
_az_RETURN_IF_FAILED(_az_json_reader_get_next_buffer(ref_json_reader, &token, false));
current_index = 0;
token_ptr = az_span_ptr(token);
remaining_size = az_span_size(token);
}
next_byte = token_ptr[current_index];
}
_az_json_reader_update_state(
ref_json_reader,
AZ_JSON_TOKEN_STRING,
az_span_slice(token, 0, current_index),
current_index,
string_length);
// Add 1 to number of bytes consumed to account for the last '"' character.
ref_json_reader->_internal.bytes_consumed++;
ref_json_reader->_internal.total_bytes_consumed++;
return AZ_OK;
}