Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/utest/testcases/kernel/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
menu "Kernel Testcase"

config UTEST_OBJECT_TC
bool "object test"
default y

config UTEST_MEMHEAP_TC
bool "memheap stability test"
default y
Expand Down
3 changes: 3 additions & 0 deletions examples/utest/testcases/kernel/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ cwd = GetCurrentDir()
src = []
CPPPATH = [cwd]

if GetDepend(['UTEST_OBJECT_TC']):
src += ['object_tc.c']

if GetDepend(['UTEST_MEMHEAP_TC']):
src += ['memheap_tc.c']

Expand Down
97 changes: 97 additions & 0 deletions examples/utest/testcases/kernel/object_tc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-07-18 kurisaW First commit
*/

#include <utest.h>
#include <rtthread.h>
#include <string.h>

/**
* @brief Test case for verifying object name handling functionality
*
* @note This test suite validates:
* 1. Proper truncation of long object names
* 2. Correct NULL name handling
* 3. Exact length name preservation
* 4. Both static and dynamic object initialization
* 5. Memory safety and boundary conditions
*/

static void test_object_name_handling(void)
{
struct rt_object static_obj1;
struct rt_object static_obj2;
struct rt_object static_obj3;
rt_object_t dyn_obj = RT_NULL;
char test_name[RT_NAME_MAX + 5];

for (int i = 0; i < sizeof(test_name) - 1; i++)
{
test_name[i] = 'A' + (i % 26);
}
test_name[sizeof(test_name) - 1] = '\0';

/* Test 1: Static Object Initialization - Extra Long Name */
rt_object_init(&static_obj1, RT_Object_Class_Thread, test_name);
uassert_true(rt_strlen(static_obj1.name) <= RT_NAME_MAX - 1);
uassert_true(static_obj1.name[RT_NAME_MAX - 1] == '\0');

/* Test 2: Dynamic Object Allocation */
dyn_obj = rt_object_allocate(RT_Object_Class_Thread, test_name);
uassert_not_null(dyn_obj);
if (dyn_obj)
{
uassert_true(rt_strlen(dyn_obj->name) <= RT_NAME_MAX - 1);
uassert_true(dyn_obj->name[RT_NAME_MAX - 1] == '\0');
rt_object_delete(dyn_obj);
dyn_obj = RT_NULL;
}

/* Test 3: NULL Name Handling - Using New Static Object */
rt_object_init(&static_obj2, RT_Object_Class_Thread, NULL);
uassert_true(static_obj2.name[0] == '\0');

/* Test 4: Dynamic Object with NULL Name */
dyn_obj = rt_object_allocate(RT_Object_Class_Thread, NULL);
uassert_not_null(dyn_obj);
if (dyn_obj)
{
uassert_true(dyn_obj->name[0] == '\0');
rt_object_delete(dyn_obj);
dyn_obj = RT_NULL;
}

/* Test 5: Fixed-Length Name - Using Third Static Object */
char exact_name[RT_NAME_MAX];
rt_memset(exact_name, 'B', RT_NAME_MAX - 1);
exact_name[RT_NAME_MAX - 1] = '\0';

rt_object_init(&static_obj3, RT_Object_Class_Thread, exact_name);
uassert_str_equal(static_obj3.name, exact_name);

rt_object_detach(&static_obj1);
rt_object_detach(&static_obj2);
rt_object_detach(&static_obj3);
}

static rt_err_t testcase_init(void)
{
return RT_EOK;
}

static rt_err_t testcase_cleanup(void)
{
return RT_EOK;
}

static void test_object_suite(void)
{
UTEST_UNIT_RUN(test_object_name_handling);
}
UTEST_TC_EXPORT(test_object_suite, "testcases.kernel.object_test", testcase_init, testcase_cleanup, 10);
30 changes: 26 additions & 4 deletions src/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ void rt_object_init(struct rt_object *object,
const char *name)
{
rt_base_t level;
rt_size_t len;
#ifdef RT_DEBUGING_ASSERT
struct rt_list_node *node = RT_NULL;
#endif /* RT_DEBUGING_ASSERT */
Expand Down Expand Up @@ -390,10 +391,20 @@ void rt_object_init(struct rt_object *object,
/* set object type to static */
object->type = type | RT_Object_Class_Static;
#if RT_NAME_MAX > 0
rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
if (name)
{
len = rt_strlen(name);
len = len > RT_NAME_MAX - 1 ? RT_NAME_MAX - 1 : len;
rt_memcpy(object->name, name, len);
object->name[len] = '\0';
}
else
{
object->name[0] = '\0';
}
#else
object->name = name;
#endif /* RT_NAME_MAX > 0 */
#endif

RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));

Expand Down Expand Up @@ -461,6 +472,7 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{
struct rt_object *object;
rt_base_t level;
rt_size_t len;
struct rt_object_information *information;
#ifdef RT_USING_MODULE
struct rt_dlmodule *module = dlmodule_self();
Expand Down Expand Up @@ -491,10 +503,20 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
object->flag = 0;

#if RT_NAME_MAX > 0
rt_strncpy(object->name, name, RT_NAME_MAX - 1); /* copy name */
if (name)
{
len = rt_strlen(name);
len = len > RT_NAME_MAX - 1 ? RT_NAME_MAX - 1 : len;
rt_memcpy(object->name, name, len);
object->name[len] = '\0';
}
else
{
object->name[0] = '\0';
}
#else
object->name = name;
#endif /* RT_NAME_MAX > 0 */
#endif

RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));

Expand Down
Loading