| 250 | } |
| 251 | |
| 252 | static int jl_parse_string(jl_parser_t *parser, size_t *start_out, size_t *end_out) { |
| 253 | if (parser->pos >= parser->length) { |
| 254 | return -1; |
| 255 | } |
| 256 | unsigned char quote = (unsigned char)parser->text[parser->pos]; |
| 257 | if (quote != '"' && (parser->strict || quote != '\'')) { |
| 258 | return -1; |
| 259 | } |
| 260 | |
| 261 | size_t start = parser->pos++; |
| 262 | while (parser->pos < parser->length) { |
| 263 | unsigned char c = (unsigned char)parser->text[parser->pos++]; |
| 264 | if (c == quote) { |
| 265 | if (start_out) { |
| 266 | *start_out = start; |
| 267 | } |
| 268 | if (end_out) { |
| 269 | *end_out = parser->pos; |
| 270 | } |
| 271 | return 0; |
| 272 | } |
| 273 | if (c < 0x20U) { |
| 274 | return -1; |
| 275 | } |
| 276 | if (c != '\\') { |
| 277 | if (!parser->strict && c == 0xE2U && parser->length - parser->pos >= 2U && |
| 278 | (unsigned char)parser->text[parser->pos] == 0x80U && |
| 279 | ((unsigned char)parser->text[parser->pos + 1U] == 0xA8U || |
| 280 | (unsigned char)parser->text[parser->pos + 1U] == 0xA9U)) { |
| 281 | return -1; |
| 282 | } |
| 283 | continue; |
| 284 | } |
| 285 | if (parser->pos >= parser->length) { |
| 286 | return -1; |
| 287 | } |
| 288 | |
| 289 | unsigned char escaped = (unsigned char)parser->text[parser->pos++]; |
| 290 | if (escaped == 'u') { |
| 291 | if (parser->length - parser->pos < 4U) { |
| 292 | return -1; |
| 293 | } |
| 294 | for (size_t i = 0; i < 4U; i++) { |
| 295 | if (!jl_is_hex((unsigned char)parser->text[parser->pos + i])) { |
| 296 | return -1; |
| 297 | } |
| 298 | } |
| 299 | parser->pos += 4U; |
| 300 | continue; |
| 301 | } |
| 302 | if (!parser->strict && escaped == 'x') { |
| 303 | if (parser->length - parser->pos < 2U || |
| 304 | !jl_is_hex((unsigned char)parser->text[parser->pos]) || |
| 305 | !jl_is_hex((unsigned char)parser->text[parser->pos + 1U])) { |
| 306 | return -1; |
| 307 | } |
| 308 | parser->pos += 2U; |
| 309 | continue; |
no test coverage detected