libyang BUGFIX fix inverted pattern when string data is parsing
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 643d144..c11dafd 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -489,7 +489,6 @@
API LY_ERR
ly_type_validate_patterns(struct lysc_pattern **patterns, const char *str, size_t str_len, struct ly_err_item **err)
{
- LY_ERR ret = LY_SUCCESS;
int rc;
LY_ARRAY_COUNT_TYPE u;
char *errmsg;
@@ -506,33 +505,30 @@
}
rc = pcre2_match(patterns[u]->code, (PCRE2_SPTR)str, str_len, 0, PCRE2_ANCHORED | PCRE2_ENDANCHORED, match_data, NULL);
- if (rc == PCRE2_ERROR_NOMATCH) {
- if (asprintf(&errmsg, "String \"%.*s\" does not conform to the pattern \"%s\".", (int)str_len, str, patterns[u]->expr) == -1) {
+ pcre2_match_data_free(match_data);
+
+ if ((rc != PCRE2_ERROR_NOMATCH) && (rc < 0)) {
+ PCRE2_UCHAR pcre2_errmsg[LY_PCRE2_MSG_LIMIT] = {0};
+ pcre2_get_error_message(rc, pcre2_errmsg, LY_PCRE2_MSG_LIMIT);
+
+ *err = ly_err_new(LY_LLERR, LY_ESYS, 0, strdup((const char *)pcre2_errmsg), NULL, NULL);
+ return LY_ESYS;
+ } else if (((rc == PCRE2_ERROR_NOMATCH) && (patterns[u]->inverted == 0)) ||
+ ((rc != PCRE2_ERROR_NOMATCH) && (patterns[u]->inverted == 1))) {
+ LY_ERR ret = 0;
+ const char *inverted = patterns[u]->inverted == 0 ? " " : " inverted ";
+ if (asprintf(&errmsg, "String \"%.*s\" does not conform to the%spattern \"%s\".",
+ (int)str_len, str, inverted, patterns[u]->expr) == -1) {
*err = ly_err_new(LY_LLERR, LY_EMEM, 0, LY_EMEM_MSG, NULL, NULL);
ret = LY_EMEM;
} else {
*err = ly_err_new(LY_LLERR, LY_ESYS, 0, errmsg, NULL, NULL);
ret = LY_EVALID;
}
- goto cleanup;
- } else if (rc < 0) {
- /* error */
- PCRE2_UCHAR pcre2_errmsg[LY_PCRE2_MSG_LIMIT] = {0};
- pcre2_get_error_message(rc, pcre2_errmsg, LY_PCRE2_MSG_LIMIT);
-
- *err = ly_err_new(LY_LLERR, LY_ESYS, 0, strdup((const char *)pcre2_errmsg), NULL, NULL);
- ret = LY_ESYS;
- goto cleanup;
- }
-
-cleanup:
- pcre2_match_data_free(match_data);
- if (ret) {
- break;
+ return ret;
}
}
-
- return ret;
+ return LY_SUCCESS;
}
API LY_ERR
diff --git a/tests/utests/data/test_types.c b/tests/utests/data/test_types.c
index 8c47f32..08c4142 100644
--- a/tests/utests/data/test_types.c
+++ b/tests/utests/data/test_types.c
@@ -52,6 +52,7 @@
"leaf dec64 {type decimal64 {fraction-digits 1; range 1.5..10;}}"
"leaf dec64-norestr {type decimal64 {fraction-digits 18;}}"
"leaf str {type string {length 8..10; pattern '[a-z ]*';}}"
+ "leaf str-invert {type string {pattern '[a-z ]*' {modifier invert-match;}}}"
"leaf str-norestr {type string;}"
"leaf str-utf8 {type string{length 2..5; pattern '€*';}}"
"leaf bool {type boolean;}"
@@ -253,6 +254,16 @@
TEST_PATTERN_1(tree, "str", 1, STRING, "teststring");
lyd_free_all(tree);
+ /* inverted match */
+ CHECK_PARSE_LYD("<str-invert xmlns=\"urn:tests:types\">TESTSTRING</str-invert>", tree);
+ assert_non_null(tree);
+ tree = tree->next;
+ TEST_PATTERN_1(tree, "str-invert", 1, STRING, "TESTSTRING");
+ lyd_free_all(tree);
+
+ TEST_TYPE_ERROR("str-invert", "teststring",
+ "String \"teststring\" does not conform to the inverted pattern \"[a-z ]*\".", "1");
+
/* multibyte characters (€ encodes as 3-byte UTF8 character, length restriction is 2-5) */
CHECK_PARSE_LYD("<str-utf8 xmlns=\"urn:tests:types\">€€</str-utf8>", tree);
assert_non_null(tree);