| 1196 | } |
| 1197 | |
| 1198 | static int toml_parse_string(const char *text, size_t len, toml_string_t *parsed) { |
| 1199 | if (!text || !parsed || len < 2 || (text[0] != '"' && text[0] != '\'')) { |
| 1200 | return TOML_EDIT_ERR; |
| 1201 | } |
| 1202 | char quote = text[0]; |
| 1203 | if (len >= 3 && text[1] == quote && text[2] == quote) { |
| 1204 | return TOML_EDIT_ERR; |
| 1205 | } |
| 1206 | toml_buffer_t value = {0}; |
| 1207 | size_t pos = 1; |
| 1208 | while (pos < len) { |
| 1209 | unsigned char ch = (unsigned char)text[pos++]; |
| 1210 | if (ch == (unsigned char)quote) { |
| 1211 | if (!value.data && toml_buffer_reserve(&value, 0) != TOML_EDIT_OK) { |
| 1212 | return TOML_EDIT_ERR; |
| 1213 | } |
| 1214 | parsed->data = value.data; |
| 1215 | parsed->len = value.len; |
| 1216 | parsed->consumed = pos; |
| 1217 | return TOML_EDIT_OK; |
| 1218 | } |
| 1219 | if (ch < 0x20 && ch != '\t') { |
| 1220 | toml_buffer_dispose(&value); |
| 1221 | return TOML_EDIT_ERR; |
| 1222 | } |
| 1223 | if (ch == 0x7f) { |
| 1224 | toml_buffer_dispose(&value); |
| 1225 | return TOML_EDIT_ERR; |
| 1226 | } |
| 1227 | if (quote == '\'' || ch != '\\') { |
| 1228 | if (toml_buffer_append_char(&value, (char)ch) != TOML_EDIT_OK) { |
| 1229 | toml_buffer_dispose(&value); |
| 1230 | return TOML_EDIT_ERR; |
| 1231 | } |
| 1232 | continue; |
| 1233 | } |
| 1234 | if (pos >= len) { |
| 1235 | toml_buffer_dispose(&value); |
| 1236 | return TOML_EDIT_ERR; |
| 1237 | } |
| 1238 | unsigned char escaped = (unsigned char)text[pos++]; |
| 1239 | char decoded; |
| 1240 | switch (escaped) { |
| 1241 | case 'b': |
| 1242 | decoded = '\b'; |
| 1243 | break; |
| 1244 | case 't': |
| 1245 | decoded = '\t'; |
| 1246 | break; |
| 1247 | case 'n': |
| 1248 | decoded = '\n'; |
| 1249 | break; |
| 1250 | case 'f': |
| 1251 | decoded = '\f'; |
| 1252 | break; |
| 1253 | case 'r': |
| 1254 | decoded = '\r'; |
| 1255 | break; |
no test coverage detected