diff options
author | Liam <30486941+liamHowatt@users.noreply.github.com> | 2024-05-22 08:14:12 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-22 14:14:12 +0200 |
commit | 3301686ec5b93df10545c5756fef2f9eef0562fd (patch) | |
tree | 5ef93210a655a937560f6c6a4cd455dba7aa8f9c | |
parent | 25c469db58e0cfc0cc0177de8621a1f11a48a89a (diff) | |
download | lvgl-3301686ec5b93df10545c5756fef2f9eef0562fd.tar.gz lvgl-3301686ec5b93df10545c5756fef2f9eef0562fd.zip |
feat(stdlib): strncpy consistency and add strlcpy (#6204)
-rw-r--r-- | src/libs/fsdrv/lv_fs_fatfs.c | 4 | ||||
-rw-r--r-- | src/libs/fsdrv/lv_fs_posix.c | 5 | ||||
-rw-r--r-- | src/libs/fsdrv/lv_fs_stdio.c | 10 | ||||
-rw-r--r-- | src/libs/fsdrv/lv_fs_win32.c | 5 | ||||
-rw-r--r-- | src/others/file_explorer/lv_file_explorer.c | 3 | ||||
-rw-r--r-- | src/others/observer/lv_observer.c | 8 | ||||
-rw-r--r-- | src/stdlib/builtin/lv_string_builtin.c | 19 | ||||
-rw-r--r-- | src/stdlib/clib/lv_string_clib.c | 16 | ||||
-rw-r--r-- | src/stdlib/lv_string.h | 15 | ||||
-rw-r--r-- | src/stdlib/rtthread/lv_string_rtthread.c | 11 | ||||
-rw-r--r-- | tests/src/test_cases/test_observer.c | 10 | ||||
-rw-r--r-- | tests/unity/unity_support.c | 2 |
12 files changed, 78 insertions, 30 deletions
diff --git a/src/libs/fsdrv/lv_fs_fatfs.c b/src/libs/fsdrv/lv_fs_fatfs.c index 071f5e2c0..c0fec20ca 100644 --- a/src/libs/fsdrv/lv_fs_fatfs.c +++ b/src/libs/fsdrv/lv_fs_fatfs.c @@ -252,6 +252,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'; @@ -265,7 +267,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); diff --git a/src/libs/fsdrv/lv_fs_posix.c b/src/libs/fsdrv/lv_fs_posix.c index d9ba1170c..f583b9a08 100644 --- a/src/libs/fsdrv/lv_fs_posix.c +++ b/src/libs/fsdrv/lv_fs_posix.c @@ -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); diff --git a/src/libs/fsdrv/lv_fs_stdio.c b/src/libs/fsdrv/lv_fs_stdio.c index 4925308c4..1c3849aeb 100644 --- a/src/libs/fsdrv/lv_fs_stdio.c +++ b/src/libs/fsdrv/lv_fs_stdio.c @@ -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; @@ -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; diff --git a/src/libs/fsdrv/lv_fs_win32.c b/src/libs/fsdrv/lv_fs_win32.c index 26d50614b..fd90f279f 100644 --- a/src/libs/fsdrv/lv_fs_win32.c +++ b/src/libs/fsdrv/lv_fs_win32.c @@ -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, ""); diff --git a/src/others/file_explorer/lv_file_explorer.c b/src/others/file_explorer/lv_file_explorer.c index 40a7a383c..ac68078be 100644 --- a/src/others/file_explorer/lv_file_explorer.c +++ b/src/others/file_explorer/lv_file_explorer.c @@ -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); diff --git a/src/others/observer/lv_observer.c b/src/others/observer/lv_observer.c index 0b6e94a36..b13291498 100644 --- a/src/others/observer/lv_observer.c +++ b/src/others/observer/lv_observer.c @@ -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; @@ -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); diff --git a/src/stdlib/builtin/lv_string_builtin.c b/src/stdlib/builtin/lv_string_builtin.c index bc4551bbb..071e2d97b 100644 --- a/src/stdlib/builtin/lv_string_builtin.c +++ b/src/stdlib/builtin/lv_string_builtin.c @@ -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; } diff --git a/src/stdlib/clib/lv_string_clib.c b/src/stdlib/clib/lv_string_clib.c index bec286e7a..2f1015187 100644 --- a/src/stdlib/clib/lv_string_clib.c +++ b/src/stdlib/clib/lv_string_clib.c @@ -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) diff --git a/src/stdlib/lv_string.h b/src/stdlib/lv_string.h index a7dcc7c30..b3da79fe0 100644 --- a/src/stdlib/lv_string.h +++ b/src/stdlib/lv_string.h @@ -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); diff --git a/src/stdlib/rtthread/lv_string_rtthread.c b/src/stdlib/rtthread/lv_string_rtthread.c index c2a12a117..6077db609 100644 --- a/src/stdlib/rtthread/lv_string_rtthread.c +++ b/src/stdlib/rtthread/lv_string_rtthread.c @@ -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); diff --git a/tests/src/test_cases/test_observer.c b/tests/src/test_cases/test_observer.c index 7122a4126..fa94ea1dc 100644 --- a/tests/src/test_cases/test_observer.c +++ b/tests/src/test_cases/test_observer.c @@ -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) diff --git a/tests/unity/unity_support.c b/tests/unity/unity_support.c index a2a563977..4907b978a 100644 --- a/tests/unity/unity_support.c +++ b/tests/unity/unity_support.c @@ -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]; |