YANG parser BUGFIX improve checking of input data when parsing
Despite the testcase is connected with special UTF8 character, it is
actually detected as unexpected end-of-input since the character starts
with a NULL-byte. In such a case libyang is not able to detect that
after the NULL-byte are still some data to read, it just interpret it as
end of input string.
Other, not-supported (by RFC) UTF8 characters should be detected
correctly with different error message.
Fixes #780
diff --git a/src/common.h b/src/common.h
index ae375a5..24cb523 100644
--- a/src/common.h
+++ b/src/common.h
@@ -175,7 +175,7 @@
#define LY_VCODE_INCHAR LYVE_SYNTAX, "Invalid character 0x%x."
#define LY_VCODE_INSTREXP LYVE_SYNTAX, "Invalid character sequence \"%.*s\", expected %s."
-#define LY_VCODE_EOF LYVE_SYNTAX, "Unexpected end-of-file."
+#define LY_VCODE_EOF LYVE_SYNTAX, "Unexpected end-of-input."
#define LY_VCODE_NTERM LYVE_SYNTAX, "%s not terminated."
#define LY_VCODE_NSUPP LYVE_SYNTAX, "%s not supported."
#define LY_VCODE_INSTMT LYVE_SYNTAX_YANG, "Invalid keyword \"%s\"."
diff --git a/src/parser_yang.c b/src/parser_yang.c
index d274fde..5d94c13 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -362,7 +362,7 @@
}
if (!**data && (comment > 1)) {
- LOGVAL_YANG(ctx, LYVE_SYNTAX, "Unexpected end-of-file, non-terminated comment.");
+ LOGVAL_YANG(ctx, LYVE_SYNTAX, "Unexpected end-of-input, non-terminated comment.");
return LY_EVALID;
}
@@ -673,6 +673,10 @@
}
}
+ /* unexpected end of loop */
+ LOGVAL_YANG(ctx, LY_VCODE_EOF);
+ return LY_EVALID;
+
str_end:
/* terminating NULL byte for buf */
if (*word_b) {
@@ -4790,7 +4794,7 @@
yang_parse_submodule(struct lys_parser_ctx *context, const char *data, struct lysp_submodule **submod)
{
LY_ERR ret = LY_SUCCESS;
- char *word, *buf;
+ char *word;
size_t word_len;
enum yang_keyword kw;
struct lysp_submodule *mod_p = NULL;
@@ -4819,17 +4823,15 @@
LY_CHECK_GOTO(ret, cleanup);
/* read some trailing spaces or new lines */
- ret = get_argument(context, &data, Y_MAYBE_STR_ARG, NULL, &word, &buf, &word_len);
- LY_CHECK_GOTO(ret, cleanup);
-
- if (word) {
- LOGVAL_YANG(context, LYVE_SYNTAX, "Invalid character sequence \"%.*s\", expected end-of-file.",
- word_len, word);
- free(buf);
+ while(*data && isspace(*data)) {
+ data++;
+ }
+ if (*data) {
+ LOGVAL_YANG(context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after submodule, expected end-of-input.",
+ 15, data, strlen(data) > 15 ? "..." : "");
ret = LY_EVALID;
goto cleanup;
}
- assert(!buf);
mod_p->parsing = 0;
*submod = mod_p;
@@ -4846,7 +4848,7 @@
yang_parse_module(struct lys_parser_ctx *context, const char *data, struct lys_module *mod)
{
LY_ERR ret = LY_SUCCESS;
- char *word, *buf;
+ char *word;
size_t word_len;
enum yang_keyword kw;
struct lysp_module *mod_p = NULL;
@@ -4876,17 +4878,15 @@
LY_CHECK_GOTO(ret, cleanup);
/* read some trailing spaces or new lines */
- ret = get_argument(context, &data, Y_MAYBE_STR_ARG, NULL, &word, &buf, &word_len);
- LY_CHECK_GOTO(ret, cleanup);
-
- if (word) {
- LOGVAL_YANG(context, LYVE_SYNTAX, "Invalid character sequence \"%.*s\", expected end-of-file.",
- word_len, word);
- free(buf);
+ while(*data && isspace(*data)) {
+ data++;
+ }
+ if (*data) {
+ LOGVAL_YANG(context, LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after module, expected end-of-input.",
+ 15, data, strlen(data) > 15 ? "..." : "");
ret = LY_EVALID;
goto cleanup;
}
- assert(!buf);
mod_p->parsing = 0;
mod->parsed = mod_p;
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index 46137b4..28fbac8 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -217,13 +217,13 @@
ctx.ctx = NULL;
ctx.line = 1;
- str = " // this is a text of / one * line */ comment\nargument";
+ str = " // this is a text of / one * line */ comment\nargument;";
assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
- assert_string_equal("argument", word);
+ assert_string_equal("argument;", word);
assert_null(buf);
assert_int_equal(8, len);
- str = "/* this is a \n * text // of / block * comment */\"arg\" + \"ume\" \n + \n \"nt\"";
+ str = "/* this is a \n * text // of / block * comment */\"arg\" + \"ume\" \n + \n \"nt\";";
assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
assert_string_equal("argument", word);
assert_ptr_equal(buf, word);
@@ -236,7 +236,7 @@
str = p = " this is a not terminated comment x";
assert_int_equal(LY_EVALID, skip_comment(&ctx, &str, 2));
- logbuf_assert("Unexpected end-of-file, non-terminated comment. Line number 5.");
+ logbuf_assert("Unexpected end-of-input, non-terminated comment. Line number 5.");
assert_true(str[0] == '\0');
}
@@ -1031,7 +1031,7 @@
free(mod);
m->parsed = NULL;
assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
- logbuf_assert("Invalid character sequence \"module\", expected end-of-file. Line number 3.");
+ logbuf_assert("Trailing garbage \"module q {names...\" after module, expected end-of-input. Line number 3.");
mod = mod_renew(&ctx);
str = "prefix " SCHEMA_BEGINNING "}";
@@ -1094,7 +1094,7 @@
lysp_submodule_free(ctx.ctx, submod);
submod = NULL;
assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
- logbuf_assert("Invalid character sequence \"module\", expected end-of-file. Line number 3.");
+ logbuf_assert("Trailing garbage \"module q {names...\" after submodule, expected end-of-input. Line number 3.");
str = "prefix " SCHEMA_BEGINNING "}";
assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
diff --git a/tests/src/test_xml.c b/tests/src/test_xml.c
index 671a1cf..22fc3e6 100644
--- a/tests/src/test_xml.c
+++ b/tests/src/test_xml.c
@@ -316,13 +316,13 @@
str = "";
assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
assert_null(buf);
- logbuf_assert("Unexpected end-of-file. Line number 2.");
+ logbuf_assert("Unexpected end-of-input. Line number 2.");
ctx.status = LYXML_ELEM_CONTENT;
str = p = "xxx";
assert_int_equal(LY_EVALID, lyxml_get_string(&ctx, &str, &buf, &buf_len, &out, &len, &dynamic));
assert_null(buf);
- logbuf_assert("Unexpected end-of-file. Line number 2.");
+ logbuf_assert("Unexpected end-of-input. Line number 2.");
assert_ptr_equal(p, str); /* input data not eaten */
/* valid strings */