Skip to content

Commit

Permalink
utils: Add safer strnlen function
Browse files Browse the repository at this point in the history
The function searches for the terminating `NULL` character in the given
string up to a given maximun length.
  • Loading branch information
LukasWoodtli committed Jan 4, 2025
1 parent 8493582 commit 36b8ce5
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 0 deletions.
12 changes: 12 additions & 0 deletions core/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,3 +1155,15 @@ lwm2m_data_type_t utils_depthToDatatype(uri_depth_t depth)

return LWM2M_TYPE_UNDEFINED;
}

size_t utils_strnlen(const char *str, size_t max_size) {
if (str == NULL) {
return 0;
}
const char *pos = memchr(str, '\0', max_size);
if (pos == NULL) {
return max_size;
} else {
return pos - str;
}
}
9 changes: 9 additions & 0 deletions core/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,14 @@ lwm2m_server_t *utils_findBootstrapServer(lwm2m_context_t *contextP, void *fromS
#if defined(LWM2M_SERVER_MODE) || defined(LWM2M_BOOTSTRAP_SERVER_MODE)
lwm2m_client_t *utils_findClient(lwm2m_context_t *contextP, void *fromSessionH);
#endif
/** A safer version of `strlen`. Finds the number of chars (bytes) of the given string up to a given max. length.
*
* The behaviour is undefined if the provided maximum length is bigger than the reserved memory for the given string.
*
* @param str The null-terminated string to find the length of.
* @param max_size Max size of string.
* @return The size of the string if it is smaller or equal to max_size. Otherwise max_size.
*/
size_t utils_strnlen(const char *str, size_t max_size);

#endif /* WAKAAMA_UTILS_H */
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(TEST_SOURCES
core_logging_tests.c
core_registration_tests.c
core_uritests.c
core_utils_tests.c
data_senml_cbor_tests.c
data_senml_json_tests.c
data_tlv_json_lwm2m_data_test.c
Expand Down
104 changes: 104 additions & 0 deletions tests/core_utils_tests.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*******************************************************************************
*
* Copyright (c) 2025 GARDENA GmbH
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Lukas Woodtli, GARDENA GmbH - Please refer to git log
*
*******************************************************************************/
#include "CUnit/Basic.h"
#include "tests.h"
#include "utils.h"

void test_strnlen_null(void) {
size_t len = utils_strnlen(NULL, 10);
CU_ASSERT_EQUAL(len, 0);
}

void test_strnlen_0(void) {
const char *string = "";
size_t len = utils_strnlen(string, 10);
CU_ASSERT_EQUAL(len, 0);
}

void test_strnlen_1(void) {
const char *string = "a";
size_t len = utils_strnlen(string, 10);
CU_ASSERT_EQUAL(len, 1);
}

void test_strnlen_2(void) {
const char *string = "ab";
size_t len = utils_strnlen(string, 10);
CU_ASSERT_EQUAL(len, 2);
}

void test_strnlen_max_len_0(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 0);
CU_ASSERT_EQUAL(len, 0);
}

void test_strnlen_max_len_1(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 1);
CU_ASSERT_EQUAL(len, 1);
}

void test_strnlen_max_len_2(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 2);
CU_ASSERT_EQUAL(len, 2);
}

void test_strnlen_max_len_3(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 3);
CU_ASSERT_EQUAL(len, 3);
}

void test_strnlen_max_len_4(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 4);
CU_ASSERT_EQUAL(len, 3);
}

void test_strnlen_max_len_5(void) {
const char *string = "abc";
size_t len = utils_strnlen(string, 5);
CU_ASSERT_EQUAL(len, 3);
}

static struct TestTable table[] = {
{"test_strnlen_null()", test_strnlen_null},
{"test_strnlen_0()", test_strnlen_0},
{"test_strnlen_1()", test_strnlen_1},
{"test_strnlen_2()", test_strnlen_2},
{"test_strnlen_max_len_0()", test_strnlen_max_len_0},
{"test_strnlen_max_len_1()", test_strnlen_max_len_1},
{"test_strnlen_max_len_2()", test_strnlen_max_len_2},
{"test_strnlen_max_len_3()", test_strnlen_max_len_3},
{"test_strnlen_max_len_4()", test_strnlen_max_len_4},
{"test_strnlen_max_len_5()", test_strnlen_max_len_5},
{NULL, NULL},
};

CU_ErrorCode create_utils_suit(void) {
CU_pSuite pSuite = NULL;

pSuite = CU_add_suite("Suite_utils", NULL, NULL);
if (NULL == pSuite) {
return CU_get_error();
}

return add_tests(pSuite, table);
}
1 change: 1 addition & 0 deletions tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ CU_ErrorCode create_logging_test_suit(void);
#ifdef LWM2M_SERVER_MODE
CU_ErrorCode create_registration_test_suit(void);
#endif
CU_ErrorCode create_utils_suit(void);
#endif /* TESTS_H_ */
3 changes: 3 additions & 0 deletions tests/unittests.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ int main(void) {
goto exit;
#endif

if (CUE_SUCCESS != create_utils_suit())
goto exit;

CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
CU_basic_show_failures(CU_get_failure_list());
Expand Down

0 comments on commit 36b8ce5

Please sign in to comment.