From 3b40ede1b877ffd5356532ffd35d9bebb3d782cf Mon Sep 17 00:00:00 2001 From: jdfiguer Date: Thu, 13 Jun 2024 13:07:50 -0400 Subject: [PATCH 1/2] Fix #1458, Moves OS_strnlen to public API and adds static analysis comments This commit addresses issues flagged during static analysis by: - Adding JSC 2.1 disposition comments. - Making OS_strnlen publicly accessible and replacing strlen with it. --- src/os/inc/osapi-clock.h | 1 + src/os/inc/osapi-common.h | 15 ++++++ src/os/shared/inc/os-shared-common.h | 21 -------- src/os/shared/src/osapi-common.c | 17 ++++++ src/os/shared/src/osapi-condvar.c | 4 +- src/os/shared/src/osapi-errors.c | 3 +- .../shared/src/coveragetest-common.c | 23 ++++++++ .../shared/src/coveragetest-filesys.c | 53 ++++++++++++++++++- .../shared/src/coveragetest-idmap.c | 1 + src/ut-stubs/osapi-common-stubs.c | 17 ++++++ 10 files changed, 131 insertions(+), 24 deletions(-) diff --git a/src/os/inc/osapi-clock.h b/src/os/inc/osapi-clock.h index 50cc82c6d..ae059e6c3 100644 --- a/src/os/inc/osapi-clock.h +++ b/src/os/inc/osapi-clock.h @@ -215,6 +215,7 @@ static inline int64 OS_TimeGetTotalMicroseconds(OS_time_t tm) */ static inline OS_time_t OS_TimeFromTotalMicroseconds(int64 tm) { + /* SAD: Overflow is not considered a concern because tm would need to be over 29,227 years in microseconds */ OS_time_t ostm = {tm * OS_TIME_TICKS_PER_USEC}; return ostm; } diff --git a/src/os/inc/osapi-common.h b/src/os/inc/osapi-common.h index cc1f24549..55ed74372 100644 --- a/src/os/inc/osapi-common.h +++ b/src/os/inc/osapi-common.h @@ -233,6 +233,21 @@ void OS_ApplicationExit(int32 Status); */ int32 OS_RegisterEventHandler(OS_EventHandler_t handler); +/*-------------------------------------------------------------------------------------*/ +/** + * @brief get string length + * + * Provides an OSAL routine to get the functionality + * of the (non-C99) "strnlen()" function, via the + * C89/C99 standard "memchr()" function instead. + * + * @param[in] s The input string + * @param[in] maxlen Maximum length to check + * @retval Length of the string or maxlen, whichever is smaller. + + */ +size_t OS_strnlen(const char *s, size_t maxlen); + /**@}*/ #endif /* OSAPI_COMMON_H */ diff --git a/src/os/shared/inc/os-shared-common.h b/src/os/shared/inc/os-shared-common.h index e84249835..e602e8f87 100644 --- a/src/os/shared/inc/os-shared-common.h +++ b/src/os/shared/inc/os-shared-common.h @@ -129,25 +129,4 @@ void OS_IdleLoop_Impl(void); ------------------------------------------------------------------*/ void OS_ApplicationShutdown_Impl(void); -/*---------------------------------------------------------------- - - Purpose: Utility function to safely find the length of a string - within a fixed-size array buffer. - - Provides a local OSAL routine to get the functionality - of the (non-C99) "strnlen()" function, via the - C89/C99 standard "memchr()" function instead. - - ------------------------------------------------------------------*/ -static inline size_t OS_strnlen(const char *s, size_t maxlen) -{ - const char *end = (const char *)memchr(s, 0, maxlen); - if (end != NULL) - { - /* actual length of string is difference */ - maxlen = end - s; - } - return maxlen; -} - #endif /* OS_SHARED_COMMON_H */ diff --git a/src/os/shared/src/osapi-common.c b/src/os/shared/src/osapi-common.c index 6e13a7170..c669ed594 100644 --- a/src/os/shared/src/osapi-common.c +++ b/src/os/shared/src/osapi-common.c @@ -423,3 +423,20 @@ void OS_ApplicationShutdown(uint8 flag) */ OS_ApplicationShutdown_Impl(); } + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +size_t OS_strnlen(const char *s, size_t maxlen) +{ + const char *end = (const char *)memchr(s, 0, maxlen); + if (end != NULL) + { + /* actual length of string is difference */ + maxlen = end - s; + } + return maxlen; +} diff --git a/src/os/shared/src/osapi-condvar.c b/src/os/shared/src/osapi-condvar.c index 1407c5262..4bed5c7a6 100644 --- a/src/os/shared/src/osapi-condvar.c +++ b/src/os/shared/src/osapi-condvar.c @@ -66,6 +66,7 @@ OS_condvar_internal_record_t OS_condvar_table[OS_MAX_CONDVARS]; *-----------------------------------------------------------------*/ int32 OS_CondVarAPI_Init(void) { + // SAD: Using memset as sizeof(OS_condvar_table) ensures correct array size memset(OS_condvar_table, 0, sizeof(OS_condvar_table)); return OS_SUCCESS; } @@ -291,6 +292,7 @@ int32 OS_CondVarGetInfo(osal_id_t var_id, OS_condvar_prop_t *condvar_prop) /* Check parameters */ OS_CHECK_POINTER(condvar_prop); + // SAD: Using memset as sizeof(OS_condvar_prop_t) ensures correct array size memset(condvar_prop, 0, sizeof(OS_condvar_prop_t)); return_code = OS_ObjectIdGetById(OS_LOCK_MODE_GLOBAL, OS_OBJECT_TYPE_OS_CONDVAR, var_id, &token); @@ -298,7 +300,7 @@ int32 OS_CondVarGetInfo(osal_id_t var_id, OS_condvar_prop_t *condvar_prop) { record = OS_OBJECT_TABLE_GET(OS_global_condvar_table, token); - strncpy(condvar_prop->name, record->name_entry, sizeof(condvar_prop->name) - 1); + snprintf(condvar_prop->name, sizeof(condvar_prop->name), "%s", record->name_entry); condvar_prop->creator = record->creator; return_code = OS_CondVarGetInfo_Impl(&token, condvar_prop); diff --git a/src/os/shared/src/osapi-errors.c b/src/os/shared/src/osapi-errors.c index 41573bd4c..4a915a793 100644 --- a/src/os/shared/src/osapi-errors.c +++ b/src/os/shared/src/osapi-errors.c @@ -110,6 +110,7 @@ char *OS_StatusToString(osal_status_t status, os_status_string_t *status_string) if (status_string != NULL) { + // SAD: No need to check snprintf return; OS_STATUS_STRING_LENGTH (12) is ample for all status values snprintf(*status_string, sizeof(*status_string), "%ld", OS_StatusToInteger(status)); string = *status_string; } @@ -149,7 +150,7 @@ int32 OS_GetErrorName(int32 error_num, os_err_name_t *err_name) { strncpy(*err_name, Error->Name, sizeof(*err_name) - 1); (*err_name)[sizeof(*err_name) - 1] = 0; - return_code = OS_SUCCESS; + return_code = OS_SUCCESS; } else { diff --git a/src/unit-test-coverage/shared/src/coveragetest-common.c b/src/unit-test-coverage/shared/src/coveragetest-common.c index 8ee1b8986..f42b2e789 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-common.c +++ b/src/unit-test-coverage/shared/src/coveragetest-common.c @@ -332,6 +332,28 @@ void Test_OS_NotifyEvent(void) OS_SharedGlobalVars.EventHandler = NULL; } +void Test_OS_strnlen(void) +{ + + size_t result; + char str[OS_MAX_FILE_NAME]; + + memset(str, 0xFF, sizeof(str)); + + /* Test case where null character is not found */ + result = OS_strnlen(str, sizeof(str)); + + UtAssert_INT32_EQ(result, sizeof(str)); + + + /* Test case where null character is found */ + str[OS_MAX_FILE_NAME - 1] = '\0'; + + result = OS_strnlen(str, sizeof(str)); + + UtAssert_INT32_EQ(result, sizeof(str) - 1); +} + /* ------------------- End of test cases --------------------------------------*/ /* Osapi_Test_Setup @@ -364,4 +386,5 @@ void UtTest_Setup(void) ADD_TEST(OS_ApplicationExit); ADD_TEST(OS_NotifyEvent); ADD_TEST(OS_API_Teardown); + ADD_TEST(OS_strnlen); } diff --git a/src/unit-test-coverage/shared/src/coveragetest-filesys.c b/src/unit-test-coverage/shared/src/coveragetest-filesys.c index 551b00fd0..56e8b47c5 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-filesys.c +++ b/src/unit-test-coverage/shared/src/coveragetest-filesys.c @@ -410,6 +410,7 @@ void Test_OS_TranslatePath(void) * int32 OS_TranslatePath(const char *VirtualPath, char *LocalPath) */ char LocalBuffer[OS_MAX_PATH_LEN]; + char DoubleBuffer[2 * OS_MAX_PATH_LEN]; int32 expected = OS_SUCCESS; int32 actual = ~OS_SUCCESS; @@ -421,37 +422,68 @@ void Test_OS_TranslatePath(void) strcpy(OS_filesys_table[1].virtual_mountpt, "/cf"); strcpy(OS_filesys_table[1].system_mountpt, "/mnt/cf"); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_SUCCESS", (long)actual); UtAssert_True(strcmp(LocalBuffer, "/mnt/cf/test") == 0, "OS_TranslatePath(/cf/test) (%s) == /mnt/cf/test", LocalBuffer); + /* VirtPathLen >= OS_MAX_PATH_LEN */ + memset(DoubleBuffer, 0xFF, sizeof(DoubleBuffer) - 1); + DoubleBuffer[sizeof(DoubleBuffer) - 1] = '\0'; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(DoubleBuffer)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); + OSAPI_TEST_FUNCTION_RC(OS_TranslatePath(DoubleBuffer, LocalBuffer), OS_FS_ERR_PATH_TOO_LONG); + /* Check various error paths */ UtAssert_INT32_EQ(OS_TranslatePath("/cf/test", NULL), OS_INVALID_POINTER); UtAssert_INT32_EQ(OS_TranslatePath(NULL, LocalBuffer), OS_INVALID_POINTER); UT_SetDefaultReturnValue(UT_KEY(OCS_memchr), OS_ERROR); expected = OS_FS_ERR_PATH_TOO_LONG; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_TOO_LONG", (long)actual); - UT_ClearDefaultReturnValue(UT_KEY(OCS_memchr)); /* Invalid no '/' */ expected = OS_FS_ERR_PATH_INVALID; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("invalid/")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("invalid", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 2, OS_ERROR); expected = OS_FS_ERR_NAME_TOO_LONG; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_NAME_TOO_LONG", (long)actual); /* Invalid no leading '/' */ expected = OS_FS_ERR_PATH_INVALID; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("invalid/")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("invalid/", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetBySearch), OS_ERR_NAME_NOT_FOUND); + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); UT_ClearDefaultReturnValue(UT_KEY(OS_ObjectIdGetBySearch)); @@ -459,17 +491,29 @@ void Test_OS_TranslatePath(void) /* VirtPathLen < VirtPathBegin */ UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 4, OS_ERROR); expected = OS_FS_ERR_PATH_INVALID; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); /* (SysMountPointLen + VirtPathLen) > OS_MAX_LOCAL_PATH_LEN */ UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 3, OS_ERROR); expected = OS_FS_ERR_PATH_TOO_LONG; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_PATH_TOO_LONG", (long)actual); OS_filesys_table[1].flags = 0; expected = OS_ERR_INCORRECT_OBJ_STATE; + UT_ResetState(UT_KEY(OS_strnlen)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_ERR_INCORRECT_OBJ_STATE", (long)actual); } @@ -497,17 +541,20 @@ void Test_OS_FileSys_FindVirtMountPoint(void) OS_filesys_table[1].flags = 0; OS_filesys_table[1].virtual_mountpt[0] = 0; + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (unmounted) == false", refstr); OS_filesys_table[1].flags = OS_FILESYS_FLAG_IS_MOUNTED_VIRTUAL; /* Branch coverage for mismatches */ + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); memset(OS_filesys_table[1].virtual_mountpt, 'a', sizeof(OS_filesys_table[1].virtual_mountpt)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); @@ -515,21 +562,25 @@ void Test_OS_FileSys_FindVirtMountPoint(void) /* Verify cases where one is a substring of the other - * these should also return false */ strncpy(OS_filesys_table[1].virtual_mountpt, "/ut11", sizeof(OS_filesys_table[1].virtual_mountpt)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); strncpy(OS_filesys_table[1].virtual_mountpt, "/u", sizeof(OS_filesys_table[1].virtual_mountpt)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); strncpy(OS_filesys_table[1].virtual_mountpt, "/ut", sizeof(OS_filesys_table[1].virtual_mountpt)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(result, "OS_FileSys_FindVirtMountPoint(%s) (nominal) == true", refstr); /* Passing case with reference ending in "/" */ strncpy(OS_filesys_table[1].virtual_mountpt, "/ut", sizeof(OS_filesys_table[1].virtual_mountpt)); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr1, &token, &refobj); UtAssert_True(result, "OS_FileSys_FindVirtMountPoint(%s) (nominal) == true", refstr); } diff --git a/src/unit-test-coverage/shared/src/coveragetest-idmap.c b/src/unit-test-coverage/shared/src/coveragetest-idmap.c index 1b8f8ea8a..100108a7d 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-idmap.c +++ b/src/unit-test-coverage/shared/src/coveragetest-idmap.c @@ -1087,6 +1087,7 @@ void Test_OS_GetResourceName(void) OSAPI_TEST_FUNCTION_RC(OS_GetResourceName(token.obj_id, NameBuffer, sizeof(NameBuffer)), OS_SUCCESS); UtAssert_True(strcmp(NameBuffer, "UTTask") == 0, "NameBuffer (%s) == UTTask", NameBuffer); + UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(rptr->name_entry)); OSAPI_TEST_FUNCTION_RC(OS_GetResourceName(token.obj_id, NameBuffer, OSAL_SIZE_C(2)), OS_ERR_NAME_TOO_LONG); /* Null entry */ diff --git a/src/ut-stubs/osapi-common-stubs.c b/src/ut-stubs/osapi-common-stubs.c index d3e85afb6..acb87a579 100644 --- a/src/ut-stubs/osapi-common-stubs.c +++ b/src/ut-stubs/osapi-common-stubs.c @@ -111,3 +111,20 @@ int32 OS_RegisterEventHandler(OS_EventHandler_t handler) return UT_GenStub_GetReturnValue(OS_RegisterEventHandler, int32); } + +/* + * ---------------------------------------------------- + * Generated stub function for OS_strnlen() + * ---------------------------------------------------- + */ +size_t OS_strnlen(const char *s, size_t maxlen) +{ + UT_GenStub_SetupReturnBuffer(OS_strnlen, size_t); + + UT_GenStub_AddParam(OS_strnlen, const char *, s); + UT_GenStub_AddParam(OS_strnlen, size_t, maxlen); + + UT_GenStub_Execute(OS_strnlen, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_strnlen, size_t); +} From 44763aa5d207b8b1aa4af28ce94f80d9313a272a Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 24 Jun 2024 18:21:06 -0400 Subject: [PATCH 2/2] Fix #1465, add default handler for OS_strnlen Calls to "OS_strnlen" are likely needed to return an actual length, so make a default handler that does return a length. The value may still be overridden in tests, though. --- .../shared/src/coveragetest-common.c | 1 - .../shared/src/coveragetest-filesys.c | 63 ++-------------- .../shared/src/coveragetest-idmap.c | 1 - src/ut-stubs/CMakeLists.txt | 1 + src/ut-stubs/osapi-common-handlers.c | 72 +++++++++++++++++++ src/ut-stubs/osapi-common-stubs.c | 4 +- 6 files changed, 82 insertions(+), 60 deletions(-) create mode 100644 src/ut-stubs/osapi-common-handlers.c diff --git a/src/unit-test-coverage/shared/src/coveragetest-common.c b/src/unit-test-coverage/shared/src/coveragetest-common.c index f42b2e789..271b30744 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-common.c +++ b/src/unit-test-coverage/shared/src/coveragetest-common.c @@ -345,7 +345,6 @@ void Test_OS_strnlen(void) UtAssert_INT32_EQ(result, sizeof(str)); - /* Test case where null character is found */ str[OS_MAX_FILE_NAME - 1] = '\0'; diff --git a/src/unit-test-coverage/shared/src/coveragetest-filesys.c b/src/unit-test-coverage/shared/src/coveragetest-filesys.c index 56e8b47c5..3ba4f14a1 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-filesys.c +++ b/src/unit-test-coverage/shared/src/coveragetest-filesys.c @@ -410,7 +410,6 @@ void Test_OS_TranslatePath(void) * int32 OS_TranslatePath(const char *VirtualPath, char *LocalPath) */ char LocalBuffer[OS_MAX_PATH_LEN]; - char DoubleBuffer[2 * OS_MAX_PATH_LEN]; int32 expected = OS_SUCCESS; int32 actual = ~OS_SUCCESS; @@ -422,98 +421,55 @@ void Test_OS_TranslatePath(void) strcpy(OS_filesys_table[1].virtual_mountpt, "/cf"); strcpy(OS_filesys_table[1].system_mountpt, "/mnt/cf"); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_SUCCESS", (long)actual); UtAssert_True(strcmp(LocalBuffer, "/mnt/cf/test") == 0, "OS_TranslatePath(/cf/test) (%s) == /mnt/cf/test", LocalBuffer); - /* VirtPathLen >= OS_MAX_PATH_LEN */ - memset(DoubleBuffer, 0xFF, sizeof(DoubleBuffer) - 1); - DoubleBuffer[sizeof(DoubleBuffer) - 1] = '\0'; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(DoubleBuffer)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); - OSAPI_TEST_FUNCTION_RC(OS_TranslatePath(DoubleBuffer, LocalBuffer), OS_FS_ERR_PATH_TOO_LONG); - /* Check various error paths */ UtAssert_INT32_EQ(OS_TranslatePath("/cf/test", NULL), OS_INVALID_POINTER); UtAssert_INT32_EQ(OS_TranslatePath(NULL, LocalBuffer), OS_INVALID_POINTER); - UT_SetDefaultReturnValue(UT_KEY(OCS_memchr), OS_ERROR); expected = OS_FS_ERR_PATH_TOO_LONG; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); - actual = OS_TranslatePath("/cf/test", LocalBuffer); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 1, OS_MAX_PATH_LEN + 1); + actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_TOO_LONG", (long)actual); + UT_ResetState(UT_KEY(OS_strnlen)); /* Invalid no '/' */ expected = OS_FS_ERR_PATH_INVALID; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("invalid/")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("invalid", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); - UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 2, OS_ERROR); + UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 1, OS_ERROR); expected = OS_FS_ERR_NAME_TOO_LONG; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_NAME_TOO_LONG", (long)actual); /* Invalid no leading '/' */ expected = OS_FS_ERR_PATH_INVALID; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("invalid/")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("invalid/", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetBySearch), OS_ERR_NAME_NOT_FOUND); - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath() (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); UT_ClearDefaultReturnValue(UT_KEY(OS_ObjectIdGetBySearch)); /* VirtPathLen < VirtPathBegin */ - UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 4, OS_ERROR); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 1, 1); expected = OS_FS_ERR_PATH_INVALID; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_PATH_INVALID", (long)actual); /* (SysMountPointLen + VirtPathLen) > OS_MAX_LOCAL_PATH_LEN */ - UT_SetDeferredRetcode(UT_KEY(OCS_memchr), 3, OS_ERROR); + UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, OS_MAX_LOCAL_PATH_LEN + 1); expected = OS_FS_ERR_PATH_TOO_LONG; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_FS_ERR_PATH_TOO_LONG", (long)actual); OS_filesys_table[1].flags = 0; expected = OS_ERR_INCORRECT_OBJ_STATE; - UT_ResetState(UT_KEY(OS_strnlen)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen("/cf/test")); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 2, strlen(OS_filesys_table[1].system_mountpt)); - UT_SetDeferredRetcode(UT_KEY(OS_strnlen), 3, strlen(OS_filesys_table[1].virtual_mountpt)); actual = OS_TranslatePath("/cf/test", LocalBuffer); UtAssert_True(actual == expected, "OS_TranslatePath(/cf/test) (%ld) == OS_ERR_INCORRECT_OBJ_STATE", (long)actual); } @@ -541,20 +497,17 @@ void Test_OS_FileSys_FindVirtMountPoint(void) OS_filesys_table[1].flags = 0; OS_filesys_table[1].virtual_mountpt[0] = 0; - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (unmounted) == false", refstr); OS_filesys_table[1].flags = OS_FILESYS_FLAG_IS_MOUNTED_VIRTUAL; /* Branch coverage for mismatches */ - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); memset(OS_filesys_table[1].virtual_mountpt, 'a', sizeof(OS_filesys_table[1].virtual_mountpt)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); @@ -562,25 +515,21 @@ void Test_OS_FileSys_FindVirtMountPoint(void) /* Verify cases where one is a substring of the other - * these should also return false */ strncpy(OS_filesys_table[1].virtual_mountpt, "/ut11", sizeof(OS_filesys_table[1].virtual_mountpt)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); strncpy(OS_filesys_table[1].virtual_mountpt, "/u", sizeof(OS_filesys_table[1].virtual_mountpt)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(!result, "OS_FileSys_FindVirtMountPoint(%s) (mountpt=%s) == false", refstr, OS_filesys_table[1].virtual_mountpt); strncpy(OS_filesys_table[1].virtual_mountpt, "/ut", sizeof(OS_filesys_table[1].virtual_mountpt)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr, &token, &refobj); UtAssert_True(result, "OS_FileSys_FindVirtMountPoint(%s) (nominal) == true", refstr); /* Passing case with reference ending in "/" */ strncpy(OS_filesys_table[1].virtual_mountpt, "/ut", sizeof(OS_filesys_table[1].virtual_mountpt)); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(OS_filesys_table[1].virtual_mountpt)); result = OS_FileSys_FindVirtMountPoint((void *)refstr1, &token, &refobj); UtAssert_True(result, "OS_FileSys_FindVirtMountPoint(%s) (nominal) == true", refstr); } diff --git a/src/unit-test-coverage/shared/src/coveragetest-idmap.c b/src/unit-test-coverage/shared/src/coveragetest-idmap.c index 100108a7d..1b8f8ea8a 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-idmap.c +++ b/src/unit-test-coverage/shared/src/coveragetest-idmap.c @@ -1087,7 +1087,6 @@ void Test_OS_GetResourceName(void) OSAPI_TEST_FUNCTION_RC(OS_GetResourceName(token.obj_id, NameBuffer, sizeof(NameBuffer)), OS_SUCCESS); UtAssert_True(strcmp(NameBuffer, "UTTask") == 0, "NameBuffer (%s) == UTTask", NameBuffer); - UT_SetDefaultReturnValue(UT_KEY(OS_strnlen), strlen(rptr->name_entry)); OSAPI_TEST_FUNCTION_RC(OS_GetResourceName(token.obj_id, NameBuffer, OSAL_SIZE_C(2)), OS_ERR_NAME_TOO_LONG); /* Null entry */ diff --git a/src/ut-stubs/CMakeLists.txt b/src/ut-stubs/CMakeLists.txt index 0e08cff30..1b3908d35 100644 --- a/src/ut-stubs/CMakeLists.txt +++ b/src/ut-stubs/CMakeLists.txt @@ -60,6 +60,7 @@ add_library(ut_osapi_stubs STATIC osapi-clock-stubs.c osapi-clock-handlers.c osapi-common-stubs.c + osapi-common-handlers.c osapi-condvar-stubs.c osapi-countsem-stubs.c osapi-countsem-handlers.c diff --git a/src/ut-stubs/osapi-common-handlers.c b/src/ut-stubs/osapi-common-handlers.c new file mode 100644 index 000000000..0cc8371aa --- /dev/null +++ b/src/ut-stubs/osapi-common-handlers.c @@ -0,0 +1,72 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * + * Stub implementations for the functions defined in the OSAL API + * + * The stub implementation can be used for unit testing applications built + * on top of OSAL. The stubs do not do any real function, but allow + * the return code to be crafted such that error paths in the application + * can be executed. + */ + +#include "osapi-common.h" /* OSAL public API for this subsystem */ +#include "utstub-helpers.h" + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_strnlen' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_strnlen(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + const char *s; + const char *end; + size_t maxlen; + size_t retval; + int32 status; + + if (UT_Stub_GetInt32StatusCode(Context, &status)) + { + /* If a retval was supplied in the test case, then use it */ + retval = status; + } + else + { + s = UT_Hook_GetArgValueByName(Context, "s", const char *); + maxlen = UT_Hook_GetArgValueByName(Context, "maxlen", size_t); + + /* This is basically the real impl of strnlen, as it + * usually needs to give back the appropriate value in + * order to follow the expected path */ + end = memchr(s, 0, maxlen); + if (end == NULL) + { + retval = maxlen; + } + else + { + retval = end - s; + } + } + + UT_Stub_SetReturnValue(FuncKey, retval); +} diff --git a/src/ut-stubs/osapi-common-stubs.c b/src/ut-stubs/osapi-common-stubs.c index acb87a579..6ca8c0699 100644 --- a/src/ut-stubs/osapi-common-stubs.c +++ b/src/ut-stubs/osapi-common-stubs.c @@ -25,6 +25,8 @@ #include "osapi-common.h" #include "utgenstub.h" +void UT_DefaultHandler_OS_strnlen(void *, UT_EntryKey_t, const UT_StubContext_t *); + /* * ---------------------------------------------------- * Generated stub function for OS_API_Init() @@ -124,7 +126,7 @@ size_t OS_strnlen(const char *s, size_t maxlen) UT_GenStub_AddParam(OS_strnlen, const char *, s); UT_GenStub_AddParam(OS_strnlen, size_t, maxlen); - UT_GenStub_Execute(OS_strnlen, Basic, NULL); + UT_GenStub_Execute(OS_strnlen, Basic, UT_DefaultHandler_OS_strnlen); return UT_GenStub_GetReturnValue(OS_strnlen, size_t); }