diff --git a/sys/clif/clif.c b/sys/clif/clif.c index 7376a196d9..b52b7565dc 100644 --- a/sys/clif/clif.c +++ b/sys/clif/clif.c @@ -251,12 +251,14 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr) assert(attr); const char *pos = input; const char *end = input + input_len; - bool quoted = false; + unsigned quotes = 0; bool scan_value = false; /* initialize attr */ attr->value = NULL; attr->key = NULL; + attr->key_len = 0; + attr->value_len = 0; if (input_len == 0) { return CLIF_NOT_FOUND; @@ -283,10 +285,11 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr) /* check if the value is quoted and prepare pointer for value scan */ pos++; if (pos == end) { - break; + /* found attribute-value separator but no value */ + return CLIF_NOT_FOUND; } else if (*pos == '"') { - quoted = true; + quotes++; pos++; } attr->value = (char *)pos; @@ -299,15 +302,23 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr) if (scan_value) { /* iterate over value */ while (pos < end) { - if (quoted) { + if (quotes == 1) { + /* we can safely access *(pos - 1) because at least one + * character was detected to get to this point */ if (*pos == '"' && *(pos - 1) != '\\') { /* found unescaped quote */ attr->value_len = pos - attr->value; + quotes++; pos++; break; } } else { + if (*pos == '"') { + /* not valid */ + return CLIF_NOT_FOUND; + } + if (*pos == LF_ATTR_SEPARATOR_C || *pos == LF_LINK_SEPARATOR_C) { /* value ends */ attr->value_len = pos - attr->value; @@ -316,6 +327,11 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr) } pos++; } + + if (!attr->value_len) { + DEBUG("Empty value found"); + return CLIF_NOT_FOUND; + } } else { /* buffer exhausted and no special character found, calculate length of @@ -323,6 +339,12 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr) attr->key_len = pos - attr->key; } + /* either the value is unquoted (0) or quoted (2) */ + if (quotes % 2U) { + DEBUG("Incorrect number of unescaped quotes found: %d\n", quotes); + return CLIF_NOT_FOUND; + } + return pos - input; }