| 868 | } |
| 869 | |
| 870 | static bool agent_json_key_equals(const char *data, size_t start, size_t end, const char *key) { |
| 871 | if (end < start) { |
| 872 | return false; |
| 873 | } |
| 874 | size_t key_offset = 0U; |
| 875 | size_t key_len = strlen(key); |
| 876 | for (size_t cursor = start; cursor < end;) { |
| 877 | unsigned value = (unsigned char)data[cursor++]; |
| 878 | if (value == '\\') { |
| 879 | if (cursor >= end) { |
| 880 | return false; |
| 881 | } |
| 882 | char escape = data[cursor++]; |
| 883 | if (escape == 'u' || escape == 'x') { |
| 884 | size_t digits = escape == 'u' ? 4U : 2U; |
| 885 | if (end - cursor < digits) { |
| 886 | return false; |
| 887 | } |
| 888 | value = 0U; |
| 889 | for (size_t i = 0U; i < digits; i++) { |
| 890 | unsigned char digit = (unsigned char)data[cursor++]; |
| 891 | if (digit >= '0' && digit <= '9') { |
| 892 | value = value * 16U + (unsigned)(digit - '0'); |
| 893 | } else if (digit >= 'a' && digit <= 'f') { |
| 894 | value = value * 16U + (unsigned)(digit - 'a' + 10U); |
| 895 | } else if (digit >= 'A' && digit <= 'F') { |
| 896 | value = value * 16U + (unsigned)(digit - 'A' + 10U); |
| 897 | } else { |
| 898 | return false; |
| 899 | } |
| 900 | } |
| 901 | } else if (strchr("\\/\"'", escape)) { |
| 902 | value = (unsigned char)escape; |
| 903 | } else { |
| 904 | return false; |
| 905 | } |
| 906 | } |
| 907 | if (value > 0x7fU || key_offset >= key_len || (unsigned char)key[key_offset++] != value) { |
| 908 | return false; |
| 909 | } |
| 910 | } |
| 911 | return key_offset == key_len; |
| 912 | } |
| 913 | |
| 914 | /* Returns 0 found, 1 absent, -1 malformed/ambiguous/not-an-object. */ |
| 915 | static int agent_json_find_member(const char *data, size_t object_start, size_t object_end, |
no outgoing calls
no test coverage detected