str += is_escaped;
if (str[0] != '"')
return -EINVAL;
- str++;
if (!is_escaped) {
/* unescape double quotation '\"'->'"' */
- for (i = j = str; *i != '"'; i++, j++) {
+ for (j = str, i = str + 1; *i != '"'; i++, j++) {
if (*i == '\0')
return -EINVAL;
if (i[0] == '\\' && i[1] == '"')
*j = *i;
}
j[0] = '\0';
+ /*
+ * The return value must be terminated by two subsequent NULs
+ * so it could be safely interpreted as nulstr.
+ */
+ j[1] = '\0';
} else {
_cleanup_free_ char *unescaped = NULL;
ssize_t l;
/* find the end position of value */
- for (i = str; *i != '"'; i++) {
+ for (i = str + 1; *i != '"'; i++) {
if (i[0] == '\\')
i++;
if (*i == '\0')
}
i[0] = '\0';
- l = cunescape_length(str, i - str, 0, &unescaped);
+ l = cunescape_length(str + 1, i - (str + 1), 0, &unescaped);
if (l < 0)
return l;
- assert(l <= i - str);
+ assert(l <= i - (str + 1));
memcpy(str, unescaped, l + 1);
+ /*
+ * The return value must be terminated by two subsequent NULs
+ * so it could be safely interpreted as nulstr.
+ */
+ str[l + 1] = '\0';
}
*ret_value = str;
} else {
assert_se(streq_ptr(value, expected_value));
assert_se(endpos == str + strlen(in));
+ /*
+ * The return value must be terminated by two subsequent NULs
+ * so it could be safely interpreted as nulstr.
+ */
+ assert_se(value[strlen(value) + 1] == '\0');
}
}