aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam <30486941+liamHowatt@users.noreply.github.com>2024-05-22 08:14:12 -0400
committerGitHub <noreply@github.com>2024-05-22 14:14:12 +0200
commit3301686ec5b93df10545c5756fef2f9eef0562fd (patch)
tree5ef93210a655a937560f6c6a4cd455dba7aa8f9c
parent25c469db58e0cfc0cc0177de8621a1f11a48a89a (diff)
downloadlvgl-3301686ec5b93df10545c5756fef2f9eef0562fd.tar.gz
lvgl-3301686ec5b93df10545c5756fef2f9eef0562fd.zip
feat(stdlib): strncpy consistency and add strlcpy (#6204)
-rw-r--r--src/libs/fsdrv/lv_fs_fatfs.c4
-rw-r--r--src/libs/fsdrv/lv_fs_posix.c5
-rw-r--r--src/libs/fsdrv/lv_fs_stdio.c10
-rw-r--r--src/libs/fsdrv/lv_fs_win32.c5
-rw-r--r--src/others/file_explorer/lv_file_explorer.c3
-rw-r--r--src/others/observer/lv_observer.c8
-rw-r--r--src/stdlib/builtin/lv_string_builtin.c19
-rw-r--r--src/stdlib/clib/lv_string_clib.c16
-rw-r--r--src/stdlib/lv_string.h15
-rw-r--r--src/stdlib/rtthread/lv_string_rtthread.c11
-rw-r--r--tests/src/test_cases/test_observer.c10
-rw-r--r--tests/unity/unity_support.c2
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];