date and time UPDATE gross errors check
Fixes #2072
diff --git a/src/plugins_types/date_and_time.c b/src/plugins_types/date_and_time.c
index dbde52f..f772f97 100644
--- a/src/plugins_types/date_and_time.c
+++ b/src/plugins_types/date_and_time.c
@@ -3,7 +3,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief ietf-yang-types date-and-time type plugin.
*
- * Copyright (c) 2019-2021 CESNET, z.s.p.o.
+ * Copyright (c) 2019-2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -112,7 +112,10 @@
/* convert to UNIX time and fractions of second */
ret = ly_time_str2time(value, &val->time, &val->fractions_s);
- LY_CHECK_GOTO(ret, cleanup);
+ if (ret) {
+ ret = ly_err_new(err, ret, 0, NULL, NULL, ly_last_errmsg());
+ goto cleanup;
+ }
if (!strncmp(((char *)value + value_len) - 6, "-00:00", 6)) {
/* unknown timezone */
diff --git a/src/tree_data_common.c b/src/tree_data_common.c
index 4602e98..8d1de06 100644
--- a/src/tree_data_common.c
+++ b/src/tree_data_common.c
@@ -1606,6 +1606,28 @@
tm.tm_min = atoi(&value[14]);
tm.tm_sec = atoi(&value[17]);
+ /* explicit checks for some gross errors */
+ if (tm.tm_mon > 11) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time month \"%d\".", tm.tm_mon);
+ return LY_EINVAL;
+ }
+ if ((tm.tm_mday < 1) || (tm.tm_mday > 31)) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time day of month \"%d\".", tm.tm_mday);
+ return LY_EINVAL;
+ }
+ if (tm.tm_hour > 23) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time hours \"%d\".", tm.tm_hour);
+ return LY_EINVAL;
+ }
+ if (tm.tm_min > 59) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time minutes \"%d\".", tm.tm_min);
+ return LY_EINVAL;
+ }
+ if (tm.tm_sec > 60) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time seconds \"%d\".", tm.tm_sec);
+ return LY_EINVAL;
+ }
+
t = timegm(&tm);
i = 19;
@@ -1626,12 +1648,24 @@
shift = 0;
} else {
shift = strtol(&value[i], NULL, 10);
+ if (shift > 23) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time timezone hour \"%" PRIi64 "\".", shift);
+ return LY_EINVAL;
+ }
shift = shift * 60 * 60; /* convert from hours to seconds */
- shift_m = strtol(&value[i + 4], NULL, 10) * 60; /* includes conversion from minutes to seconds */
+
+ shift_m = strtol(&value[i + 4], NULL, 10);
+ if (shift_m > 59) {
+ LOGERR(NULL, LY_EINVAL, "Invalid date-and-time timezone minutes \"%" PRIi64 "\".", shift_m);
+ return LY_EINVAL;
+ }
+ shift_m *= 60; /* convert from minutes to seconds */
+
/* correct sign */
if (shift < 0) {
shift_m *= -1;
}
+
/* connect hours and minutes of the shift */
shift = shift + shift_m;
}
diff --git a/tests/utests/types/yang_types.c b/tests/utests/types/yang_types.c
index 60649ef..0f78455 100644
--- a/tests/utests/types/yang_types.c
+++ b/tests/utests/types/yang_types.c
@@ -52,11 +52,11 @@
lyd_free_all(tree); \
}
-#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA, RET) \
{\
struct lyd_node *tree; \
const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
- CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, RET, tree); \
assert_null(tree); \
}
@@ -111,11 +111,17 @@
TEST_SUCCESS_XML("a", "l", "2017-02-01T00:00:00-00:00", STRING, "2017-02-01T00:00:00-00:00");
TEST_SUCCESS_XML("a", "l", "2021-02-29T00:00:00-00:00", STRING, "2021-03-01T00:00:00-00:00");
- TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00");
+ TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00", LY_EVALID);
CHECK_LOG_CTX("Unsatisfied pattern - \"2005-05-31T23:15:15.-08:00\" does not conform to "
"\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[\\+\\-]\\d{2}:\\d{2})\".",
"Schema location \"/a:l\", line number 1.");
+ TEST_ERROR_XML("a", "l", "2023-16-15T20:13:01+01:00", LY_EINVAL);
+ CHECK_LOG_CTX("Invalid date-and-time month \"15\".", "Schema location \"/a:l\", line number 1.");
+
+ TEST_ERROR_XML("a", "l", "2023-10-15T20:13:01+95:00", LY_EINVAL);
+ CHECK_LOG_CTX("Invalid date-and-time timezone hour \"95\".", "Schema location \"/a:l\", line number 1.");
+
/* hex-string */
TEST_SUCCESS_XML("a", "l21", "DB:BA:12:54:fa", STRING, "db:ba:12:54:fa");
TEST_SUCCESS_XML("a", "l22", "f81D4fAE-7dec-11d0-A765-00a0c91E6BF6", STRING, "f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
@@ -131,10 +137,10 @@
"/a:node1/node2[node3/b:node4]/b:node5 | b:node6 and (b:node7)");
TEST_SUCCESS_XML("a", "l3", "/l3[. = '4']", STRING, "/l3[.='4']");
- TEST_ERROR_XML("a", "l3", "/a:l3[. = '4']");
+ TEST_ERROR_XML("a", "l3", "/a:l3[. = '4']", LY_EVALID);
CHECK_LOG_CTX("Failed to resolve prefix \"a\".", "Schema location \"/a:l3\", line number 1.");
TEST_ERROR_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library", "l3",
- "/yl:yang-library/yl:datastore/yl::name");
+ "/yl:yang-library/yl:datastore/yl::name", LY_EVALID);
CHECK_LOG_CTX("Storing value failed.", "Schema location \"/a:l3\", line number 1.");
CHECK_LOG_CTX("Invalid character 'y'[31] of expression '/yl:yang-library/yl:datastore/yl::name'.",
"Schema location \"/a:l3\", line number 1.");