1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 01:53:51 +01:00

sys/clif: fix attribute parsing and comply with tests

This commit is contained in:
Leandro Lanzieri 2021-03-04 15:04:32 +01:00
parent 9e2e99fafb
commit 311ed225ae
No known key found for this signature in database
GPG Key ID: F4E9A721761C7593

View File

@ -251,12 +251,14 @@ ssize_t clif_get_attr(const char *input, size_t input_len, clif_attr_t *attr)
assert(attr); assert(attr);
const char *pos = input; const char *pos = input;
const char *end = input + input_len; const char *end = input + input_len;
bool quoted = false; unsigned quotes = 0;
bool scan_value = false; bool scan_value = false;
/* initialize attr */ /* initialize attr */
attr->value = NULL; attr->value = NULL;
attr->key = NULL; attr->key = NULL;
attr->key_len = 0;
attr->value_len = 0;
if (input_len == 0) { if (input_len == 0) {
return CLIF_NOT_FOUND; 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 */ /* check if the value is quoted and prepare pointer for value scan */
pos++; pos++;
if (pos == end) { if (pos == end) {
break; /* found attribute-value separator but no value */
return CLIF_NOT_FOUND;
} }
else if (*pos == '"') { else if (*pos == '"') {
quoted = true; quotes++;
pos++; pos++;
} }
attr->value = (char *)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) { if (scan_value) {
/* iterate over value */ /* iterate over value */
while (pos < end) { 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) != '\\') { if (*pos == '"' && *(pos - 1) != '\\') {
/* found unescaped quote */ /* found unescaped quote */
attr->value_len = pos - attr->value; attr->value_len = pos - attr->value;
quotes++;
pos++; pos++;
break; break;
} }
} }
else { else {
if (*pos == '"') {
/* not valid */
return CLIF_NOT_FOUND;
}
if (*pos == LF_ATTR_SEPARATOR_C || *pos == LF_LINK_SEPARATOR_C) { if (*pos == LF_ATTR_SEPARATOR_C || *pos == LF_LINK_SEPARATOR_C) {
/* value ends */ /* value ends */
attr->value_len = pos - attr->value; 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++; pos++;
} }
if (!attr->value_len) {
DEBUG("Empty value found");
return CLIF_NOT_FOUND;
}
} }
else { else {
/* buffer exhausted and no special character found, calculate length of /* 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; 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; return pos - input;
} }