Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stdlib): strncpy consistency and add strlcpy #6204

Merged
merged 4 commits into from
May 22, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/libs/fsdrv/lv_fs_fatfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len)
{
LV_UNUSED(drv);
if(fn_len == 0) return LV_FS_RES_INV_PARAM;

FRESULT res;
FILINFO fno;
fn[0] = '\0';
Expand All @@ -261,7 +263,7 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint3
if(fno.fattrib & AM_DIR) {
lv_snprintf(fn, fn_len, "/%s", fno.fname);
}
else lv_strncpy(fn, fno.fname, fn_len);
else lv_strlcpy(fn, fno.fname, fn_len);

} while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0);

Expand Down
5 changes: 3 additions & 2 deletions src/libs/fsdrv/lv_fs_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,17 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len)
{
LV_UNUSED(drv);
if(fn_len == 0) return LV_FS_RES_INV_PARAM;

struct dirent * entry;
do {
entry = readdir(dir_p);
if(entry) {
if(entry->d_type == DT_DIR) lv_snprintf(fn, fn_len, "/%s", entry->d_name);
else lv_strncpy(fn, entry->d_name, fn_len);
else lv_strlcpy(fn, entry->d_name, fn_len);
}
else {
lv_strncpy(fn, "", fn_len);
lv_strlcpy(fn, "", fn_len);
}
} while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0);

Expand Down
10 changes: 6 additions & 4 deletions src/libs/fsdrv/lv_fs_stdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len)
{
LV_UNUSED(drv);
if(fn_len == 0) return LV_FS_RES_INV_PARAM;

dir_handle_t * handle = (dir_handle_t *)dir_p;
#ifndef WIN32
struct dirent * entry;
Expand All @@ -284,16 +286,16 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint3
if(entry) {
/*Note, DT_DIR is not defined in C99*/
if(entry->d_type == DT_DIR) lv_snprintf(fn, fn_len, "/%s", entry->d_name);
else lv_strncpy(fn, entry->d_name, fn_len);
else lv_strlcpy(fn, entry->d_name, fn_len);
}
else {
lv_strncpy(fn, "", fn_len);
lv_strlcpy(fn, "", fn_len);
}
} while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0);
#else
lv_strncpy(fn, handle->next_fn, fn_len);
lv_strlcpy(fn, handle->next_fn, fn_len);

lv_strncpy(handle->next_fn, "", fn_len);
lv_strcpy(handle->next_fn, "");
WIN32_FIND_DATAA fdata;

if(FindNextFileA(handle->dir_p, &fdata) == false) return LV_FS_RES_OK;
Expand Down
5 changes: 3 additions & 2 deletions src/libs/fsdrv/lv_fs_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,10 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len)
{
LV_UNUSED(drv);
LV_UNUSED(fn_len);
if(fn_len == 0) return LV_FS_RES_INV_PARAM;

dir_handle_t * handle = (dir_handle_t *)dir_p;
lv_strcpy(fn, handle->next_fn);
lv_strlcpy(fn, handle->next_fn, fn_len);
lv_fs_res_t current_error = handle->next_error;
lv_strcpy(handle->next_fn, "");

Expand Down
3 changes: 1 addition & 2 deletions src/others/file_explorer/lv_file_explorer.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,7 @@ static void show_dir(lv_obj_t * obj, const char * path)
/*Move the table to the top*/
lv_obj_scroll_to_y(explorer->file_table, 0, LV_ANIM_OFF);

lv_memzero(explorer->current_path, sizeof(explorer->current_path));
lv_strncpy(explorer->current_path, path, sizeof(explorer->current_path) - 1);
lv_strlcpy(explorer->current_path, path, sizeof(explorer->current_path));
lv_label_set_text_fmt(explorer->path_label, LV_SYMBOL_EYE_OPEN" %s", path);

size_t current_path_len = lv_strlen(explorer->current_path);
Expand Down
8 changes: 4 additions & 4 deletions src/others/observer/lv_observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ int32_t lv_subject_get_previous_int(lv_subject_t * subject)
void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value)
{
lv_memzero(subject, sizeof(lv_subject_t));
lv_strncpy(buf, value, size);
if(prev_buf) lv_strncpy(prev_buf, value, size);
lv_strlcpy(buf, value, size);
if(prev_buf) lv_strlcpy(prev_buf, value, size);

subject->type = LV_SUBJECT_TYPE_STRING;
subject->size = size;
Expand All @@ -136,10 +136,10 @@ void lv_subject_copy_string(lv_subject_t * subject, const char * buf)

if(subject->size < 1) return;
if(subject->prev_value.pointer) {
lv_strncpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size - 1);
lv_strlcpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size);
}

lv_strncpy((char *)subject->value.pointer, buf, subject->size - 1);
lv_strlcpy((char *)subject->value.pointer, buf, subject->size);

lv_subject_notify(subject);

Expand Down
19 changes: 17 additions & 2 deletions src/stdlib/builtin/lv_string_builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,28 @@ size_t lv_strlen(const char * str)
return i;
}

size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
size_t i = 0;
if(dst_size > 0) {
for(; i < dst_size - 1 && src[i]; i++) {
dst[i] = src[i];
}
dst[i] = '\0';
}
while(src[i]) i++;
return i;
}

char * lv_strncpy(char * dst, const char * src, size_t dst_size)
{
size_t i;
for(i = 0; i < dst_size - 1 && src[i]; i++) {
for(i = 0; i < dst_size && src[i]; i++) {
dst[i] = src[i];
}
dst[i] = '\0';
for(; i < dst_size; i++) {
dst[i] = '\0';
}
return dst;
}

Expand Down
16 changes: 11 additions & 5 deletions src/stdlib/clib/lv_string_clib.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,20 @@ size_t lv_strlen(const char * str)
return strlen(str);
}

char * lv_strncpy(char * dst, const char * src, size_t dest_size)
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
if(dest_size > 0) {
dst[0] = '\0';
strncat(dst, src, dest_size - 1);
size_t src_len = strlen(src);
if(dst_size > 0) {
size_t copy_size = src_len < dst_size ? src_len : dst_size - 1;
memcpy(dst, src, copy_size);
dst[copy_size] = '\0';
}
return src_len;
}

return dst;
char * lv_strncpy(char * dst, const char * src, size_t dest_size)
{
return strncpy(dst, src, dest_size);
}

char * lv_strcpy(char * dst, const char * src)
Expand Down
15 changes: 13 additions & 2 deletions src/stdlib/lv_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,22 @@ static inline void lv_memzero(void * dst, size_t len)
size_t lv_strlen(const char * str);

/**
* @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst.
* @brief Copies up to dst_size-1 (non-null) characters from src to dst. A null terminator is always added.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param dest_size Maximum number of characters to be copied to dst, including the null character.
* @param dst_size Maximum number of characters to be copied to dst, including the null character.
* @return The length of src. The return value is equivalent to the value returned by lv_strlen(src)
*/
size_t lv_strlcpy(char * dst, const char * src, size_t dst_size);

/**
* @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst
* and fills the remaining length with null bytes.
* @param dst Pointer to the destination array where the content is to be copied.
* @param src Pointer to the source of data to be copied.
* @param dest_size Maximum number of characters to be copied to dst.
* @return A pointer to the destination array, which is dst.
* @note dst will not be null terminated if dest_size bytes were copied from src before the end of src was reached.
*/
char * lv_strncpy(char * dst, const char * src, size_t dest_size);

Expand Down
11 changes: 11 additions & 0 deletions src/stdlib/rtthread/lv_string_rtthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ int32_t lv_memcmp(const void * p1, const void * p2, size_t len)
return rt_memcmp(p1, p2, len);
}

size_t lv_strlcpy(char * dst, const char * src, size_t dst_size)
{
size_t src_len = lv_strlen(src);
if(dst_size > 0) {
size_t copy_size = src_len < dst_size ? src_len : dst_size - 1;
lv_memcpy(dst, src, copy_size);
dst[copy_size] = '\0';
}
return src_len;
}

char * lv_strncpy(char * dst, const char * src, size_t dest_size)
{
return rt_strncpy(dst, src, dest_size);
Expand Down
10 changes: 5 additions & 5 deletions tests/src/test_cases/test_observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,26 +95,26 @@ void test_observer_string(void)

/*Clip long text*/
lv_subject_copy_string(&subject, "text to be clipped to 32 chars.this should be clipped");
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars.", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("how are you?", lv_subject_get_previous_string(&subject));

/*Check if the previous string is clipped correctly*/
lv_subject_copy_string(&subject, "a");
TEST_ASSERT_EQUAL_STRING("a", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars", lv_subject_get_previous_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars.", lv_subject_get_previous_string(&subject));

/*Ignore incorrect types*/
lv_subject_set_pointer(&subject, NULL);
TEST_ASSERT_EQUAL_STRING("a", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars", lv_subject_get_previous_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars.", lv_subject_get_previous_string(&subject));

lv_subject_set_color(&subject, lv_color_black());
TEST_ASSERT_EQUAL_STRING("a", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars", lv_subject_get_previous_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars.", lv_subject_get_previous_string(&subject));

lv_subject_set_int(&subject, 10);
TEST_ASSERT_EQUAL_STRING("a", lv_subject_get_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars", lv_subject_get_previous_string(&subject));
TEST_ASSERT_EQUAL_STRING("text to be clipped to 32 chars.", lv_subject_get_previous_string(&subject));
}

void test_observer_pointer(void)
Expand Down
2 changes: 1 addition & 1 deletion tests/unity/unity_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static bool screenhot_compare(const char * fn_ref, const char * mode, uint8_t to

if(err) {
char fn_ref_no_ext[128];
strcpy(fn_ref_no_ext, fn_ref);
lv_strlcpy(fn_ref_no_ext, fn_ref, sizeof(fn_ref_no_ext));
fn_ref_no_ext[strlen(fn_ref_no_ext) - 4] = '\0';

char fn_err_full[256];
Expand Down