diff --git a/src/base/json.c b/src/base/json.c index 1d5ffda267dc332adc574ef2868ca02e315b257f..a634bb674beded5e3ca5d4b349182dec415ec005 100644 --- a/src/base/json.c +++ b/src/base/json.c @@ -36,14 +36,58 @@ skip(char *s) is_paren = 0; \ if (str[0] == __JSON_SEP) { \ ++str; \ - char *end = strchr(str, __JSON_SEP); \ + const char *begin = str, *end; \ + for (;;) { \ + end = strchr(begin, __JSON_SEP); \ + if (*(end - 1) == '\\') { \ + begin = end + 1; \ + continue; \ + } \ + break; \ + } \ len = (end - str); \ is_paren = 1; \ } else \ len = strcspn(str, __JSON_SPACE __JSON_BEGIN __JSON_END); \ if (level == asked_level && len < LKT_LINE_MAX - 1) \ strncpy(dest, str, len); \ - str += len + is_paren; \ + str += len; \ + /* Also decode '\"' => '"' */ \ + if (is_paren) { \ + ++str; \ + __replace(key, "\\\"", "\""); \ + __replace(val, "\\\"", "\""); \ + } \ +} + +/* WARN: strlen(from) >= strlen(to) */ +static inline int +__replace(char *string, const char *from, const char *to) +{ + if (strlen(from) < strlen(to)) { + LOG_ERROR("JSON", "The size of the 'to' string must be inferior " + "or equal to the size of the 'from' string"); + return 1; + } + if (strstr(to, from)) { + LOG_ERROR("JSON", "At least one string '%s' has been found in '%s', exit " + "before looping until the end of the universe", from, to); + return 1; + } + + size_t step = strlen(from) - strlen(to); + char *start = string; + for (;;) { + start = strstr(start, from); + if (start == NULL || *start == '\0') + break; + strncpy(start, to, strlen(to)); + start += strlen(to); + memmove(start, start + step, strlen(start + step) * sizeof(char)); + start[strlen(start) - step] = '\0'; + } + + return 0; } int