diff --git a/CHANGELOG.md b/CHANGELOG.md index 1529e044..7a906329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 The git repositories are hosted at the following sites: * https://bacnet.sourceforge.net/ -* https://github.com/bacnet*stack +* https://github.com/bacnet-stack/bacnet-stack/ ## [Unreleased] @@ -22,6 +22,8 @@ The git repositories are hosted at the following sites: ### Fixed +Fixed datetime decode of invalid application tag. (#495) + ## [1.2.0] - 2023-09-11 ### Security diff --git a/src/bacnet/datetime.c b/src/bacnet/datetime.c index e26b7782..cf4c7908 100644 --- a/src/bacnet/datetime.c +++ b/src/bacnet/datetime.c @@ -1125,7 +1125,7 @@ int bacnet_datetime_decode( } len = bacnet_date_application_decode( &apdu[apdu_len], apdu_size - apdu_len, bdate); - if (len < 0) { + if (len <= 0) { return BACNET_STATUS_ERROR; } apdu_len += len; @@ -1134,7 +1134,7 @@ int bacnet_datetime_decode( } len = bacnet_time_application_decode( &apdu[apdu_len], apdu_size - apdu_len, btime); - if (len < 0) { + if (len <= 0) { return BACNET_STATUS_ERROR; } apdu_len += len; diff --git a/test/bacnet/datetime/src/main.c b/test/bacnet/datetime/src/main.c index 6e798f34..430b6e57 100644 --- a/test/bacnet/datetime/src/main.c +++ b/test/bacnet/datetime/src/main.c @@ -44,6 +44,7 @@ #include #include #include "bacnet/datetime.h" +#include "bacnet/basic/sys/days.h" #include "bacnet/bacdcode.h" /* define our epic beginnings */ @@ -133,7 +134,6 @@ static void testBACnetDateTimeAdd(void) zassert_equal(diff, 0, NULL); } -#if 0 /*TODO: Change to use external methods */ static void testBACnetDateTimeSeconds(void) { uint8_t hour = 0, minute = 0, second = 0; @@ -143,17 +143,17 @@ static void testBACnetDateTimeSeconds(void) for (hour = 0; hour < 24; hour++) { for (minute = 0; minute < 60; minute += 3) { for (second = 0; second < 60; second += 17) { - seconds = seconds_since_midnight(hour, minute, second); - seconds_since_midnight_into_hms( + seconds = datetime_hms_to_seconds_since_midnight( + hour, minute, second); + datetime_hms_from_seconds_since_midnight( seconds, &test_hour, &test_minute, &test_second); - test_seconds = - seconds_since_midnight(test_hour, test_minute, test_second); + test_seconds = datetime_hms_to_seconds_since_midnight( + test_hour, test_minute, test_second); zassert_equal(seconds, test_seconds, NULL); } } } } -#endif #if defined(CONFIG_ZTEST_NEW_API) ZTEST(wp_tests, testBACnetDate) @@ -369,7 +369,6 @@ static void testWildcardDateTime(void) return; } -#if 0 /*TODO: Change to use external methods */ static void testDayOfYear(void) { uint32_t days = 0; @@ -379,17 +378,17 @@ static void testDayOfYear(void) BACNET_DATE bdate; BACNET_DATE test_bdate; - days = day_of_year(1900, 1, 1); + days = days_of_year(1900, 1, 1); zassert_equal(days, 1, NULL); - day_of_year_into_md(days, 1900, &month, &day); + days_of_year_to_month_day(days, 1900, &month, &day); zassert_equal(month, 1, NULL); zassert_equal(day, 1, NULL); for (year = 1900; year <= 2154; year++) { for (month = 1; month <= 12; month++) { - for (day = 1; day <= datetime_month_days(year, month); day++) { - days = day_of_year(year, month, day); - day_of_year_into_md(days, year, &test_month, &test_day); + for (day = 1; day <= days_per_month(year, month); day++) { + days = days_of_year(year, month, day); + days_of_year_to_month_day(days, year, &test_month, &test_day); zassert_equal(month, test_month, NULL); zassert_equal(day, test_day, NULL); } @@ -397,16 +396,16 @@ static void testDayOfYear(void) } for (year = 1900; year <= 2154; year++) { for (month = 1; month <= 12; month++) { - for (day = 1; day <= datetime_month_days(year, month); day++) { + for (day = 1; day <= days_per_month(year, month); day++) { datetime_set_date(&bdate, year, month, day); days = datetime_day_of_year(&bdate); datetime_day_of_year_into_date(days, year, &test_bdate); - zassert_true(datetime_compare_date(&bdate, &test_bdate), 0, NULL); + zassert_equal(datetime_compare_date(&bdate, &test_bdate), 0, + "year=%u month=%u day=%u", year, month, day); } } } } -#endif static void testDateEpochConversionCompare(uint16_t year, uint8_t month, @@ -448,7 +447,6 @@ static void testDateEpochConversion(void) BACNET_EPOCH_YEAR + 0xFF - 1, 12, 31, 23, 59, 59, 0); } -#if 0 /*TODO: Change to use external methods */ static void testDateEpoch(void) { uint32_t days = 0; @@ -456,19 +454,19 @@ static void testDateEpoch(void) uint8_t month = 0, test_month = 0; uint8_t day = 0, test_day = 0; - days = days_since_epoch(BACNET_EPOCH_YEAR, 1, 1); - zassert_equal(days, 0, NULL); - days_since_epoch_into_ymd(days, &year, &month, &day); + days = days_since_epoch(BACNET_EPOCH_YEAR, BACNET_EPOCH_YEAR, 1, 1); + zassert_equal(days, 1, "days=%lu", (unsigned long)days); + days_since_epoch_to_date(BACNET_EPOCH_YEAR, days, &year, &month, &day); zassert_equal(year, BACNET_EPOCH_YEAR, NULL); zassert_equal(month, 1, NULL); zassert_equal(day, 1, NULL); for (year = BACNET_EPOCH_YEAR; year < (BACNET_EPOCH_YEAR + 0xFF); year++) { for (month = 1; month <= 12; month++) { - for (day = 1; day <= datetime_month_days(year, month); day++) { - days = days_since_epoch(year, month, day); - days_since_epoch_into_ymd( - days, &test_year, &test_month, &test_day); + for (day = 1; day <= days_per_month(year, month); day++) { + days = days_since_epoch(BACNET_EPOCH_YEAR, year, month, day); + days_since_epoch_to_date(BACNET_EPOCH_YEAR, days, &test_year, + &test_month, &test_day); zassert_equal(year, test_year, NULL); zassert_equal(month, test_month, NULL); zassert_equal(day, test_day, NULL); @@ -476,7 +474,6 @@ static void testDateEpoch(void) } } } -#endif #if defined(CONFIG_ZTEST_NEW_API) ZTEST(wp_tests, testBACnetDayOfWeek) @@ -520,8 +517,9 @@ static void testDatetimeCodec(void) uint8_t tag_number = 10; BACNET_DATE_TIME datetimeIn; BACNET_DATE_TIME datetimeOut; - int inLen; - int outLen; + int apdu_len; + int test_len; + int null_len; int diff; bool status; @@ -530,40 +528,55 @@ static void testDatetimeCodec(void) status = datetime_time_init_ascii(&datetimeIn.time, "5:06:07.8"); zassert_true(status, NULL); /* application */ - inLen = bacapp_encode_datetime(NULL, &datetimeIn); - zassert_true(inLen <= sizeof(apdu), NULL); - inLen = bacapp_encode_datetime(apdu, &datetimeIn); - outLen = bacnet_datetime_decode(apdu, inLen, &datetimeOut); - zassert_equal(inLen, outLen, NULL); + apdu_len = bacapp_encode_datetime(NULL, &datetimeIn); + zassert_true(apdu_len <= sizeof(apdu), NULL); + null_len = bacapp_encode_datetime(NULL, &datetimeIn); + apdu_len = bacapp_encode_datetime(apdu, &datetimeIn); + zassert_equal(apdu_len, null_len, NULL); + zassert_true(apdu_len > 0, NULL); + null_len = bacnet_datetime_decode(apdu, apdu_len, NULL); + test_len = bacnet_datetime_decode(apdu, apdu_len, &datetimeOut); + zassert_equal(apdu_len, null_len, NULL); + zassert_equal(apdu_len, test_len, NULL); + zassert_true(apdu_len > 0, NULL); diff = datetime_compare(&datetimeOut, &datetimeIn); zassert_equal(diff, 0, NULL); + /* test for invalid date tag */ + apdu_len = bacapp_encode_datetime(apdu, &datetimeIn); + encode_tag(apdu, BACNET_APPLICATION_TAG_REAL, false, 4); + test_len = bacnet_datetime_decode(&apdu[0], apdu_len, &datetimeOut); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); + /* test for invalid time tag */ + apdu_len = bacapp_encode_datetime(apdu, &datetimeIn); + encode_tag(&apdu[5], BACNET_APPLICATION_TAG_REAL, false, 4); + test_len = bacnet_datetime_decode(apdu, apdu_len, &datetimeOut); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); /* ERROR too short APDU */ - while (inLen) { - inLen--; - outLen = bacnet_datetime_decode(apdu, inLen, &datetimeOut); - zassert_equal(outLen, BACNET_STATUS_ERROR, NULL); + apdu_len = bacapp_encode_datetime(apdu, &datetimeIn); + while (apdu_len) { + apdu_len--; + test_len = bacnet_datetime_decode(apdu, apdu_len, &datetimeOut); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); } /* context */ - inLen = bacapp_encode_context_datetime(NULL, tag_number, &datetimeIn); - zassert_true(inLen <= sizeof(apdu), NULL); - inLen = bacapp_encode_context_datetime(apdu, tag_number, &datetimeIn); - outLen = - bacnet_datetime_context_decode(apdu, inLen, tag_number, &datetimeOut); - zassert_equal(inLen, outLen, NULL); + apdu_len = bacapp_encode_context_datetime(NULL, tag_number, &datetimeIn); + zassert_true(apdu_len <= sizeof(apdu), NULL); + apdu_len = bacapp_encode_context_datetime(apdu, tag_number, &datetimeIn); + test_len = bacnet_datetime_context_decode( + apdu, apdu_len, tag_number, &datetimeOut); + zassert_equal(apdu_len, test_len, NULL); /* ERROR too short APDU */ - while (inLen) { - inLen--; - outLen = bacnet_datetime_context_decode( - apdu, inLen, tag_number, &datetimeOut); - zassert_equal(outLen, BACNET_STATUS_ERROR, NULL); + while (apdu_len) { + apdu_len--; + test_len = bacnet_datetime_context_decode( + apdu, apdu_len, tag_number, &datetimeOut); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); } diff = datetime_compare(&datetimeOut, &datetimeIn); zassert_equal(diff, 0, NULL); } -#if 0 /*TODO: Change to use external methods */ -static void testDatetimeConvertUTCSpecific( - BACNET_DATE_TIME *utc_time, +static void testDatetimeConvertUTCSpecific(BACNET_DATE_TIME *utc_time, BACNET_DATE_TIME *local_time, int16_t utc_offset_minutes, int8_t dst_adjust_minutes) @@ -588,9 +601,7 @@ static void testDatetimeConvertUTCSpecific( zassert_equal( local_time->time.hundredths, test_local_time.time.hundredths, NULL); } -#endif -#if 0 /*TODO: Change to use external methods */ static void testDatetimeConvertUTC(void) { BACNET_DATE_TIME local_time; @@ -614,30 +625,27 @@ static void testDatetimeConvertUTC(void) testDatetimeConvertUTCSpecific( &utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes); } -#endif /** * @} */ #if defined(CONFIG_ZTEST_NEW_API) -ZTEST_SUITE(wp_tests, NULL, NULL, NULL, NULL, NULL); +ZTEST_SUITE(datetime_tests, NULL, NULL, NULL, NULL, NULL); #else void test_main(void) { -#if 0 - ztest_unit_test(testDateEpoch), - ztest_unit_test(testBACnetDateTimeSeconds), - ztest_unit_test(testDayOfYear), -#endif - ztest_test_suite(wp_tests, ztest_unit_test(testBACnetDate), + ztest_test_suite(datetime_tests, ztest_unit_test(testBACnetDate), ztest_unit_test(testBACnetTime), ztest_unit_test(testBACnetDateTime), ztest_unit_test(testBACnetDayOfWeek), ztest_unit_test(testDateEpochConversion), ztest_unit_test(testBACnetDateTimeAdd), ztest_unit_test(testBACnetDateTimeWildcard), ztest_unit_test(testDatetimeCodec), - ztest_unit_test(testWildcardDateTime)); + ztest_unit_test(testWildcardDateTime), ztest_unit_test(testDateEpoch), + ztest_unit_test(testBACnetDateTimeSeconds), + ztest_unit_test(testDayOfYear), + ztest_unit_test(testDatetimeConvertUTC)); - ztest_run_test_suite(wp_tests); + ztest_run_test_suite(datetime_tests); } #endif