Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 0 additions & 121 deletions src/ly_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1955,124 +1955,3 @@ ly_parse_nodeid(const char **id, const char **prefix, uint32_t *prefix_len, cons

return LY_SUCCESS;
}

LY_ERR
ly_parse_instance_predicate(const char **pred, uint32_t limit, LYD_FORMAT format, const char **prefix, uint32_t *prefix_len,
const char **id, uint32_t *id_len, const char **value, uint32_t *value_len, const char **errmsg)
{
LY_ERR ret = LY_EVALID;
const char *in = *pred;
uint32_t offset = 1;
uint8_t expr = 0; /* 0 - position predicate; 1 - leaf-list-predicate; 2 - key-predicate */
char quot;

assert(in[0] == '[');

*prefix = *id = *value = NULL;
*prefix_len = *id_len = *value_len = 0;

/* leading *WSP */
for ( ; isspace(in[offset]); offset++) {}

if (isdigit(in[offset])) {
/* pos: "[" *WSP positive-integer-value *WSP "]" */
if (in[offset] == '0') {
/* zero */
*errmsg = "The position predicate cannot be zero.";
goto error;
}

/* positive-integer-value */
*value = &in[offset++];
for ( ; isdigit(in[offset]); offset++) {}
*value_len = &in[offset] - *value;

} else if (in[offset] == '.') {
/* leaf-list-predicate: "[" *WSP "." *WSP "=" *WSP quoted-string *WSP "]" */
*id = &in[offset];
*id_len = 1;
offset++;
expr = 1;
} else if (in[offset] == '-') {
/* typically negative value */
*errmsg = "Invalid instance predicate format (negative position or invalid node-identifier).";
goto error;
} else {
/* key-predicate: "[" *WSP node-identifier *WSP "=" *WSP quoted-string *WSP "]" */
in = &in[offset];
if (ly_parse_nodeid(&in, prefix, prefix_len, id, id_len)) {
*errmsg = "Invalid node-identifier.";
goto error;
}
if ((format == LYD_XML) && !(*prefix)) {
/* all node names MUST be qualified with explicit namespace prefix */
*errmsg = "Missing prefix of a node name.";
goto error;
}
offset = in - *pred;
in = *pred;
expr = 2;
}

if (expr) {
/* *WSP "=" *WSP quoted-string *WSP "]" */
for ( ; isspace(in[offset]); offset++) {}

if (in[offset] != '=') {
if (expr == 1) {
*errmsg = "Unexpected character instead of \'=\' in leaf-list-predicate.";
} else { /* 2 */
*errmsg = "Unexpected character instead of \'=\' in key-predicate.";
}
goto error;
}
offset++;
for ( ; isspace(in[offset]); offset++) {}

/* quoted-string */
quot = in[offset++];
if ((quot != '\'') && (quot != '\"')) {
*errmsg = "String value is not quoted.";
goto error;
}
*value = &in[offset];
for ( ; offset < limit && (in[offset] != quot || (offset && in[offset - 1] == '\\')); offset++) {}
if (in[offset] == quot) {
*value_len = &in[offset] - *value;
offset++;
} else {
*errmsg = "Value is not terminated quoted-string.";
goto error;
}
}

/* *WSP "]" */
for ( ; isspace(in[offset]); offset++) {}
if (in[offset] != ']') {
if (expr == 0) {
*errmsg = "Predicate (pos) is not terminated by \']\' character.";
} else if (expr == 1) {
*errmsg = "Predicate (leaf-list-predicate) is not terminated by \']\' character.";
} else { /* 2 */
*errmsg = "Predicate (key-predicate) is not terminated by \']\' character.";
}
goto error;
}
offset++;

if (offset <= limit) {
*pred = &in[offset];
return LY_SUCCESS;
}

/* we read after the limit */
*errmsg = "Predicate is incomplete.";
*prefix = *id = *value = NULL;
*prefix_len = *id_len = *value_len = 0;
offset = limit;
ret = LY_EINVAL;

error:
*pred = &in[offset];
return ret;
}
23 changes: 0 additions & 23 deletions src/ly_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -804,29 +804,6 @@ LY_ERR ly_parse_uint(const char *val_str, uint32_t val_len, uint64_t max, int ba
*/
LY_ERR ly_parse_nodeid(const char **id, const char **prefix, uint32_t *prefix_len, const char **name, uint32_t *name_len);

/**
* @brief parse instance-identifier's predicate, supports key-predicate, leaf-list-predicate and pos rules from YANG ABNF Grammar.
*
* @param[in,out] pred Predicate string (including the leading '[') to parse. The string is updated according to what was parsed
* (even for error case, so it can be used to determine which substring caused failure).
* @param[in] limit Limiting length of the @p pred. Function expects NULL terminated string which is not overread.
* The limit value is not checked with each character, so it can be overread and the failure is detected later.
* @param[in] format Input format of the data containing the @p pred.
* @param[out] prefix Start of the node-identifier's prefix if any, NULL in case of pos or leaf-list-predicate rules.
* @param[out] prefix_len Length of the parsed @p prefix.
* @param[out] id Start of the node-identifier's identifier string, NULL in case of pos rule, "." in case of leaf-list-predicate rule.
* @param[out] id_len Length of the parsed @p id.
* @param[out] value Start of the quoted-string (without quotation marks), not NULL in case of success.
* @param[out] value_len Length of the parsed @p value.
* @param[out] errmsg Error message string in case of error.
* @return LY_SUCCESS in case a complete predicate was parsed.
* @return LY_EVALID in case of invalid predicate form.
* @return LY_EINVAL in case of reaching @p limit when parsing @p pred.
*/
LY_ERR ly_parse_instance_predicate(const char **pred, uint32_t limit, LYD_FORMAT format,
const char **prefix, uint32_t *prefix_len, const char **id, uint32_t *id_len,
const char **value, uint32_t *value_len, const char **errmsg);

/**
* @brief mmap(2) wrapper to map input files into memory to unify parsing.
*
Expand Down
Loading