commit c71f98b: [Fix] Backport PR from libucl
Vsevolod Stakhov
vsevolod at highsecure.ru
Thu Jan 6 14:07:04 UTC 2022
Author: Vsevolod Stakhov
Date: 2022-01-06 14:05:35 +0000
URL: https://github.com/rspamd/rspamd/commit/c71f98b2422d7c758db2d0370374408ed2c45618 (HEAD -> master)
[Fix] Backport PR from libucl
https://github.com/vstakhov/libucl/pull/260
---
contrib/libucl/ucl_parser.c | 57 +++++++++++++++++++++++++++++----------------
contrib/libucl/ucl_util.c | 10 ++++----
2 files changed, 43 insertions(+), 24 deletions(-)
diff --git a/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c
index 8ccbf05af..5ed72d0bb 100644
--- a/contrib/libucl/ucl_parser.c
+++ b/contrib/libucl/ucl_parser.c
@@ -47,6 +47,9 @@ struct ucl_parser_saved_state {
*/
#define ucl_chunk_skipc(chunk, p) \
do { \
+ if (p == chunk->end) { \
+ break; \
+ } \
if (*(p) == '\n') { \
(chunk)->line ++; \
(chunk)->column = 0; \
@@ -394,6 +397,9 @@ ucl_check_variable (struct ucl_parser *parser, const char *ptr,
}
p ++;
}
+ if(p == end) {
+ (*out_len) ++;
+ }
}
else if (*ptr != '$') {
/* Not count escaped dollar sign */
@@ -417,13 +423,14 @@ ucl_check_variable (struct ucl_parser *parser, const char *ptr,
* Expand a single variable
* @param parser
* @param ptr
- * @param remain
+ * @param in_len
* @param dest
+ * @param out_len
* @return
*/
static const char *
ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
- size_t remain, unsigned char **dest)
+ size_t in_len, unsigned char **dest, size_t out_len)
{
unsigned char *d = *dest, *dst;
const char *p = ptr + 1, *ret;
@@ -434,7 +441,8 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
bool strict = false;
ret = ptr + 1;
- remain --;
+ out_len --;
+ in_len --;
if (*p == '$') {
*d++ = *p++;
@@ -443,28 +451,31 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
}
else if (*p == '{') {
p ++;
+ in_len --;
strict = true;
ret += 2;
- remain -= 2;
+ out_len -= 2;
}
LL_FOREACH (parser->variables, var) {
- if (remain >= var->var_len) {
+ if (out_len >= var->value_len && in_len >= (var->var_len + strict)) {
if (memcmp (p, var->var, var->var_len) == 0) {
- memcpy (d, var->value, var->value_len);
- ret += var->var_len;
- d += var->value_len;
- found = true;
- break;
+ if (!strict || p[var->var_len] == '}') {
+ memcpy (d, var->value, var->value_len);
+ ret += var->var_len;
+ d += var->value_len;
+ found = true;
+ break;
+ }
}
}
}
if (!found) {
if (strict && parser->var_handler != NULL) {
- if (parser->var_handler (p, remain, &dst, &dstlen, &need_free,
+ if (parser->var_handler (p, out_len, &dst, &dstlen, &need_free,
parser->var_data)) {
memcpy (d, dst, dstlen);
- ret += remain;
+ ret += out_len;
d += dstlen;
found = true;
if (need_free) {
@@ -475,7 +486,7 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
/* Leave variable as is */
if (!found) {
- if (strict) {
+ if (strict && out_len >= 2) {
/* Copy '${' */
memcpy (d, ptr, 2);
d += 2;
@@ -505,7 +516,7 @@ ucl_expand_variable (struct ucl_parser *parser, unsigned char **dst,
const char *src, size_t in_len)
{
const char *p, *end = src + in_len;
- unsigned char *d;
+ unsigned char *d, *d_end;
size_t out_len = 0;
bool vars_found = false;
@@ -516,7 +527,7 @@ ucl_expand_variable (struct ucl_parser *parser, unsigned char **dst,
p = src;
while (p != end) {
- if (*p == '$') {
+ if (*p == '$' && p + 1 != end) {
p = ucl_check_variable (parser, p + 1, end - p - 1, &out_len, &vars_found);
}
else {
@@ -537,10 +548,11 @@ ucl_expand_variable (struct ucl_parser *parser, unsigned char **dst,
}
d = *dst;
+ d_end = d + out_len;
p = src;
- while (p != end) {
- if (*p == '$') {
- p = ucl_expand_single_variable (parser, p, end - p, &d);
+ while (p != end && d != d_end) {
+ if (*p == '$' && p + 1 != end) {
+ p = ucl_expand_single_variable (parser, p, end - p, &d, d_end - d);
}
else {
*d++ = *p++;
@@ -1054,13 +1066,13 @@ ucl_lex_json_string (struct ucl_parser *parser,
}
else if (c == '\\') {
ucl_chunk_skipc (chunk, p);
- c = *p;
if (p >= chunk->end) {
ucl_set_err (parser, UCL_ESYNTAX, "unfinished escape character",
&parser->err);
return false;
}
- else if (ucl_test_character (c, UCL_CHARACTER_ESCAPE)) {
+ c = *p;
+ if (ucl_test_character (c, UCL_CHARACTER_ESCAPE)) {
if (c == 'u') {
ucl_chunk_skipc (chunk, p);
for (i = 0; i < 4 && p < chunk->end; i ++) {
@@ -1829,6 +1841,11 @@ ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk)
while (p < chunk->end && *p >= 'A' && *p <= 'Z') {
p ++;
}
+ if(p == chunk->end) {
+ ucl_set_err (parser, UCL_ESYNTAX,
+ "unterminated multiline value", &parser->err);
+ return false;
+ }
if (*p =='\n') {
/* Set chunk positions and start multiline parsing */
chunk->remain -= p - c + 1;
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index e97e3ab9b..13544af28 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -1927,7 +1927,7 @@ ucl_inherit_handler (const unsigned char *data, size_t len,
/* Some sanity checks */
if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) {
- ucl_create_err (&parser->err, "Unable to find inherited object %*.s",
+ ucl_create_err (&parser->err, "Unable to find inherited object %.*s",
(int)len, data);
return false;
}
@@ -2185,7 +2185,7 @@ ucl_strnstr (const char *s, const char *find, int len)
mlen = strlen (find);
do {
do {
- if ((sc = *s++) == 0 || len-- == 0)
+ if ((sc = *s++) == 0 || len-- < mlen)
return (NULL);
} while (sc != c);
} while (strncmp (s, find, mlen) != 0);
@@ -3602,9 +3602,11 @@ ucl_object_copy_internal (const ucl_object_t *other, bool allow_array)
/* deep copy of values stored */
if (other->trash_stack[UCL_TRASH_KEY] != NULL) {
- new->trash_stack[UCL_TRASH_KEY] =
- strdup (other->trash_stack[UCL_TRASH_KEY]);
+ new->trash_stack[UCL_TRASH_KEY] = NULL;
if (other->key == (const char *)other->trash_stack[UCL_TRASH_KEY]) {
+ new->trash_stack[UCL_TRASH_KEY] = malloc(other->keylen + 1);
+ memcpy(new->trash_stack[UCL_TRASH_KEY], other->trash_stack[UCL_TRASH_KEY], other->keylen);
+ new->trash_stack[UCL_TRASH_KEY][other->keylen] = '\0';
new->key = new->trash_stack[UCL_TRASH_KEY];
}
}
More information about the Commits
mailing list