| 697 | } |
| 698 | |
| 699 | static bool jl_key_equals(const char *text, size_t start, size_t end, const char *target) { |
| 700 | size_t target_length = strlen(target); |
| 701 | size_t target_pos = 0; |
| 702 | bool quoted = end > start + 1U && (text[start] == '"' || text[start] == '\''); |
| 703 | size_t pos = quoted ? start + 1U : start; |
| 704 | size_t limit = quoted ? end - 1U : end; |
| 705 | |
| 706 | while (pos < limit) { |
| 707 | unsigned char c = (unsigned char)text[pos++]; |
| 708 | if (c != '\\') { |
| 709 | if (!jl_match_output(&c, 1U, target, target_length, &target_pos)) { |
| 710 | return false; |
| 711 | } |
| 712 | continue; |
| 713 | } |
| 714 | if (pos >= limit) { |
| 715 | return false; |
| 716 | } |
| 717 | unsigned char escaped = (unsigned char)text[pos++]; |
| 718 | if (escaped == '\n' || escaped == '\r') { |
| 719 | if (escaped == '\r' && pos < limit && text[pos] == '\n') { |
| 720 | pos++; |
| 721 | } |
| 722 | continue; |
| 723 | } |
| 724 | |
| 725 | uint32_t codepoint = escaped; |
| 726 | switch (escaped) { |
| 727 | case 'b': |
| 728 | codepoint = '\b'; |
| 729 | break; |
| 730 | case 'f': |
| 731 | codepoint = '\f'; |
| 732 | break; |
| 733 | case 'n': |
| 734 | codepoint = '\n'; |
| 735 | break; |
| 736 | case 'r': |
| 737 | codepoint = '\r'; |
| 738 | break; |
| 739 | case 't': |
| 740 | codepoint = '\t'; |
| 741 | break; |
| 742 | case 'v': |
| 743 | codepoint = '\v'; |
| 744 | break; |
| 745 | case '0': |
| 746 | codepoint = 0; |
| 747 | break; |
| 748 | case 'x': |
| 749 | if (limit - pos < 2U) { |
| 750 | return false; |
| 751 | } |
| 752 | codepoint = (jl_hex_value((unsigned char)text[pos]) << 4U) | |
| 753 | jl_hex_value((unsigned char)text[pos + 1U]); |
| 754 | pos += 2U; |
| 755 | break; |
| 756 | case 'u': |
no test coverage detected