| 1158 | } |
| 1159 | |
| 1160 | static int toml_parse_string(const char *text, size_t len, toml_string_t *parsed) { |
| 1161 | if (!text || !parsed || len < 2 || (text[0] != '"' && text[0] != '\'')) { |
| 1162 | return TOML_EDIT_ERR; |
| 1163 | } |
| 1164 | char quote = text[0]; |
| 1165 | if (len >= 3 && text[1] == quote && text[2] == quote) { |
| 1166 | return TOML_EDIT_ERR; |
| 1167 | } |
| 1168 | toml_buffer_t value = {0}; |
| 1169 | size_t pos = 1; |
| 1170 | while (pos < len) { |
| 1171 | unsigned char ch = (unsigned char)text[pos++]; |
| 1172 | if (ch == (unsigned char)quote) { |
| 1173 | if (!value.data && toml_buffer_reserve(&value, 0) != TOML_EDIT_OK) { |
| 1174 | return TOML_EDIT_ERR; |
| 1175 | } |
| 1176 | parsed->data = value.data; |
| 1177 | parsed->len = value.len; |
| 1178 | parsed->consumed = pos; |
| 1179 | return TOML_EDIT_OK; |
| 1180 | } |
| 1181 | if (ch < 0x20 && ch != '\t') { |
| 1182 | toml_buffer_dispose(&value); |
| 1183 | return TOML_EDIT_ERR; |
| 1184 | } |
| 1185 | if (ch == 0x7f) { |
| 1186 | toml_buffer_dispose(&value); |
| 1187 | return TOML_EDIT_ERR; |
| 1188 | } |
| 1189 | if (quote == '\'' || ch != '\\') { |
| 1190 | if (toml_buffer_append_char(&value, (char)ch) != TOML_EDIT_OK) { |
| 1191 | toml_buffer_dispose(&value); |
| 1192 | return TOML_EDIT_ERR; |
| 1193 | } |
| 1194 | continue; |
| 1195 | } |
| 1196 | if (pos >= len) { |
| 1197 | toml_buffer_dispose(&value); |
| 1198 | return TOML_EDIT_ERR; |
| 1199 | } |
| 1200 | unsigned char escaped = (unsigned char)text[pos++]; |
| 1201 | char decoded; |
| 1202 | switch (escaped) { |
| 1203 | case 'b': |
| 1204 | decoded = '\b'; |
| 1205 | break; |
| 1206 | case 't': |
| 1207 | decoded = '\t'; |
| 1208 | break; |
| 1209 | case 'n': |
| 1210 | decoded = '\n'; |
| 1211 | break; |
| 1212 | case 'f': |
| 1213 | decoded = '\f'; |
| 1214 | break; |
| 1215 | case 'r': |
| 1216 | decoded = '\r'; |
| 1217 | break; |
no test coverage detected