Skip to content

Commit

Permalink
date and time UPDATE gross errors check
Browse files Browse the repository at this point in the history
Fixes #2072
  • Loading branch information
michalvasko committed Aug 8, 2023
1 parent 00be3d8 commit 2b7e161
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/plugins_types/date_and_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @author Michal Vasko <[email protected]>
* @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.
Expand Down Expand Up @@ -112,7 +112,10 @@ lyplg_type_store_date_and_time(const struct ly_ctx *ctx, const struct lysc_type

/* 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 */
Expand Down
36 changes: 35 additions & 1 deletion src/tree_data_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,28 @@ ly_time_str2time(const char *value, time_t *time, char **fractions_s)
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;

Expand All @@ -1626,12 +1648,24 @@ ly_time_str2time(const char *value, time_t *time, char **fractions_s)
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;
}
Expand Down
16 changes: 11 additions & 5 deletions tests/utests/types/yang_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
}

Expand Down Expand Up @@ -111,11 +111,17 @@ test_data_xml(void **state)
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");
Expand All @@ -131,10 +137,10 @@ test_data_xml(void **state)
"/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.");
Expand Down

0 comments on commit 2b7e161

Please sign in to comment.