From f6c719d7ec71cc7771c46d3daa390924a3871ba3 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Mon, 14 Nov 2022 11:32:34 -0500 Subject: replace strlcpy with strmemccpy replace applicable calls to strlcpy with calls to strmemccpy which null terminates on truncation in theory the strmemccpy calls should be slightly faster since they don't traverse the rest of the source string on truncation but I seriously doubt there is too much of that going on in the code base Change-Id: Ia0251514e36a6242bbf3f03c5e0df123aba60ed2 --- apps/bookmark.c | 4 +-- apps/buffering.c | 1 - apps/cuesheet.c | 22 ++++++------ apps/debug_menu.c | 7 ++-- apps/gui/folder_select.c | 6 ++-- apps/gui/option_select.c | 8 ++--- apps/gui/skin_engine/skin_backdrops.c | 2 +- apps/gui/skin_engine/skin_parser.c | 2 +- apps/gui/skin_engine/skin_tokens.c | 2 +- apps/gui/statusbar-skinned.c | 1 - apps/hosted/android/keyboard.c | 2 +- apps/iap/iap-lingo4.c | 11 +++--- apps/menus/eq_menu.c | 2 +- apps/misc.c | 6 ++-- apps/onplay.c | 6 ++-- apps/open_plugin.c | 4 +-- apps/playlist.c | 12 +++---- apps/playlist_catalog.c | 12 +++---- apps/playlist_viewer.c | 6 ++-- apps/radio/presets.c | 4 +-- apps/radio/radioart.c | 2 +- apps/recorder/albumart.c | 4 +-- apps/recorder/keyboard.c | 2 +- apps/recorder/pcm_record.c | 4 +-- apps/root_menu.c | 2 +- apps/screens.c | 8 ++--- apps/settings.c | 35 ++++++++++--------- apps/settings_list.c | 4 +-- apps/shortcuts.c | 10 +++--- apps/tagcache.c | 8 ++--- apps/tagtree.c | 18 +++++----- apps/talk.c | 27 +++++++++------ apps/tree.c | 10 +++--- firmware/SOURCES | 1 + firmware/buflib.c | 4 +-- firmware/common/dircache.c | 8 ++--- firmware/common/strlcpy.c | 64 ++++++++++++++--------------------- firmware/common/strmemccpy.c | 38 +++++++++++++++++++++ firmware/drivers/lcd-bitmap-common.c | 2 +- firmware/font.c | 2 +- firmware/general.c | 4 +-- firmware/include/string-extra.h | 1 + firmware/include/strmemccpy.h | 32 ++++++++++++++++++ 43 files changed, 236 insertions(+), 174 deletions(-) create mode 100644 firmware/common/strmemccpy.c create mode 100644 firmware/include/strmemccpy.h diff --git a/apps/bookmark.c b/apps/bookmark.c index d594c51320..0cc2807609 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c @@ -1075,7 +1075,7 @@ static bool parse_bookmark(const char *bookmark, const bool parse_filenames, con { size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s); len = MIN(TEMP_BUF_SIZE - 1, len); - strlcpy(global_temp_buffer, s, len + 1); + strmemccpy(global_temp_buffer, s, len + 1); if (end != NULL) { @@ -1089,7 +1089,7 @@ static bool parse_bookmark(const char *bookmark, const bool parse_filenames, con end++; } } - strlcpy(global_filename, end, MAX_PATH); + strmemccpy(global_filename, end, MAX_PATH); } } diff --git a/apps/buffering.c b/apps/buffering.c index 8661a42ab8..9743c9c319 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -20,7 +20,6 @@ ****************************************************************************/ #include "config.h" #include -#include "strlcpy.h" #include "system.h" #include "storage.h" #include "thread.h" diff --git a/apps/cuesheet.c b/apps/cuesheet.c index da14147262..561be6a677 100644 --- a/apps/cuesheet.c +++ b/apps/cuesheet.c @@ -58,7 +58,7 @@ static bool search_for_cuesheet(const char *path, struct cuesheet_file *cue_file slash_cuepath = &cuepath[slash - path]; dot = strrchr(slash_cuepath, '.'); if (dot) - strlcpy(dot, ".cue", MAX_PATH - (dot-cuepath)); + strmemccpy(dot, ".cue", MAX_PATH - (dot-cuepath)); if (!dot || !file_exists(cuepath)) { @@ -72,14 +72,14 @@ static bool search_for_cuesheet(const char *path, struct cuesheet_file *cue_file skip: if ((len+4) >= MAX_PATH) return false; - strlcpy(cuepath, path, MAX_PATH); + strmemccpy(cuepath, path, MAX_PATH); strlcat(cuepath, ".cue", MAX_PATH); if (!file_exists(cuepath)) return false; } } - strlcpy(cue_file->path, cuepath, MAX_PATH); + strmemccpy(cue_file->path, cuepath, MAX_PATH); return true; } @@ -91,7 +91,7 @@ bool look_for_cuesheet_file(struct mp3entry *track_id3, struct cuesheet_file *cu cue_file->pos = track_id3->embedded_cuesheet.pos; cue_file->size = track_id3->embedded_cuesheet.size; cue_file->encoding = track_id3->embedded_cuesheet.encoding; - strlcpy(cue_file->path, track_id3->path, MAX_PATH); + strmemccpy(cue_file->path, track_id3->path, MAX_PATH); return true; } @@ -363,7 +363,7 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue) } else { - strlcpy(dest, string, count); + strmemccpy(dest, string, count); } } } @@ -386,7 +386,7 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue) strcpy(cue->file, cue->path); char *slash = strrchr(cue->file, '/'); if (!slash++) slash = cue->file; - strlcpy(slash, line, MAX_PATH - (slash - cue->file)); + strmemccpy(slash, line, MAX_PATH - (slash - cue->file)); } /* If some songs don't have performer info, we copy the cuesheet performer */ @@ -394,10 +394,10 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue) for (i = 0; i < cue->track_count; i++) { if (*(cue->tracks[i].performer) == '\0') - strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3); + strmemccpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3); if (*(cue->tracks[i].songwriter) == '\0') - strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3); + strmemccpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3); } return true; @@ -441,7 +441,7 @@ static const char* list_get_name_cb(int selected_item, struct cuesheet *cue = (struct cuesheet *)data; if (selected_item & 1) - strlcpy(buffer, cue->tracks[selected_item/2].title, buffer_len); + strmemccpy(buffer, cue->tracks[selected_item/2].title, buffer_len); else snprintf(buffer, buffer_len, "%02d. %s", selected_item/2+1, cue->tracks[selected_item/2].performer); @@ -508,7 +508,7 @@ void browse_cuesheet(struct cuesheet *cue) /* check that this cue is the same one that would be found by a search from playback */ char file[MAX_PATH]; - strlcpy(file, cue->file, MAX_PATH); + strmemccpy(file, cue->file, MAX_PATH); if (!strcmp(cue->path, file) || /* if embedded */ (search_for_cuesheet(file, &cue_file) && @@ -535,7 +535,7 @@ bool display_cuesheet_content(char* filename) if (!cue || bufsize < sizeof(struct cuesheet)) return false; - strlcpy(cue_file.path, filename, MAX_PATH); + strmemccpy(cue_file.path, filename, MAX_PATH); cue_file.pos = 0; cue_file.size = 0; diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 0b0bc8fc2b..5ebaa3a3f4 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "lcd.h" #include "lang.h" #include "menu.h" @@ -1274,7 +1274,7 @@ static int disk_callback(int btn, struct gui_synclist *lists) { card_name[i] = card_extract_bits(card->cid, (103-8*i), 8); } - strlcpy(card_name, card_name, sizeof(card_name)); + strmemccpy(card_name, card_name, sizeof(card_name)); simplelist_addline( "%s Rev %d.%d", card_name, (int) card_extract_bits(card->cid, 63, 4), @@ -1628,8 +1628,7 @@ static int ata_smart_attr_to_string( slen += len; } - if (!memccpy (str+slen, buf, '\0', size-slen)) - (str+slen)[size-slen - 1] = '\0'; + strmemccpy(str+slen, buf, size-slen); } return 1; /* ok */ diff --git a/apps/gui/folder_select.c b/apps/gui/folder_select.c index 50d25e7305..a76d77562b 100644 --- a/apps/gui/folder_select.c +++ b/apps/gui/folder_select.c @@ -185,7 +185,7 @@ static struct folder* load_folder(struct folder* parent, char *folder) if (len >= sizeof(fullpath)) goto fail; } - strlcpy(&fullpath[len], folder, sizeof(fullpath) - len); + strmemccpy(&fullpath[len], folder, sizeof(fullpath) - len); logf("load_folder: [%s]", fullpath); dir = opendir(fullpath); @@ -518,7 +518,7 @@ static int select_paths(struct folder* root, const char* filenames) lastfnp = fnp; if (len <= 0 || len + 1 >= buflen) continue; - strlcpy(buf, sstr, len + 1); + strmemccpy(buf, sstr, len + 1); struct child *item = find_from_filename(buf, root); if (item) item->state = SELECTED; @@ -563,7 +563,7 @@ static void save_folders_r(struct folder *root, char* dst, size_t maxlen, size_t int dlen = strlen(dst); if (dlen + len >= maxlen) continue; - strlcpy(&dst[dlen], buffer_front, maxlen - dlen); + strmemccpy(&dst[dlen], buffer_front, maxlen - dlen); } else { diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index e154467428..4687367fba 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c @@ -68,8 +68,8 @@ const char *option_get_valuestring(const struct settings_list *setting, if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) { bool val = (bool)temp_var; - strlcpy(buffer, str(val? setting->bool_setting->lang_yes : - setting->bool_setting->lang_no), buf_len); + strmemccpy(buffer, str(val? setting->bool_setting->lang_yes : + setting->bool_setting->lang_no), buf_len); } #if 0 /* probably dont need this one */ else if ((setting->flags & F_FILENAME) == F_FILENAME) @@ -121,7 +121,7 @@ const char *option_get_valuestring(const struct settings_list *setting, const struct choice_setting *info = setting->choice_setting; if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY) { - strlcpy(buffer, str(info->talks[(int)temp_var]), buf_len); + strmemccpy(buffer, str(info->talks[(int)temp_var]), buf_len); } else { @@ -133,7 +133,7 @@ const char *option_get_valuestring(const struct settings_list *setting, { int value = (int)temp_var; char *val = P2STR(setting->choice_setting->desc[value]); - strlcpy(buffer, val, buf_len); + strmemccpy(buffer, val, buf_len); } } return str; diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c index 215667d585..8be40d1ce2 100644 --- a/apps/gui/skin_engine/skin_backdrops.c +++ b/apps/gui/skin_engine/skin_backdrops.c @@ -137,7 +137,7 @@ int skin_backdrop_assign(char* backdrop, char *bmpdir, } if (free >= 0) { - strlcpy(backdrops[free].name, filename, MAX_PATH); + strmemccpy(backdrops[free].name, filename, MAX_PATH); backdrops[free].buffer = NULL; backdrops[free].screen = screen; backdrops[free].ref_count = 1; diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 419e49810d..4e3b7e4d12 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -2548,7 +2548,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, { /* get the bitmap dir */ char *dot = strrchr(buf, '.'); - strlcpy(bmpdir, buf, dot - buf + 1); + strmemccpy(bmpdir, buf, dot - buf + 1); } else { diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index a1d0a4b840..6d9d489a17 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -114,7 +114,7 @@ char* get_dir(char* buf, int buf_size, const char* path, int level) return NULL; len = MIN(last_sep - sep, buf_size - 1); - strlcpy(buf, sep + 1, len + 1); + strmemccpy(buf, sep + 1, len + 1); return buf; } diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index 5d2b65846d..d6dddf5cd2 100644 --- a/apps/gui/statusbar-skinned.c +++ b/apps/gui/statusbar-skinned.c @@ -27,7 +27,6 @@ #include "appevents.h" #include "screens.h" #include "screen_access.h" -#include "strlcpy.h" #include "skin_parser.h" #include "skin_buffer.h" #include "skin_engine/skin_engine.h" diff --git a/apps/hosted/android/keyboard.c b/apps/hosted/android/keyboard.c index eda951a7c9..b74f67e782 100644 --- a/apps/hosted/android/keyboard.c +++ b/apps/hosted/android/keyboard.c @@ -100,7 +100,7 @@ int kbd_input(char* text, int buflen, unsigned short *kbd) if (accepted) { utf8_string = e->GetStringUTFChars(env_ptr, new_string, 0); - strlcpy(text, utf8_string, buflen); + strmemccpy(text, utf8_string, buflen); e->ReleaseStringUTFChars(env_ptr, new_string, utf8_string); e->DeleteGlobalRef(env_ptr, new_string); } diff --git a/apps/iap/iap-lingo4.c b/apps/iap/iap-lingo4.c index abb13eac02..77ddeabcb3 100644 --- a/apps/iap/iap-lingo4.c +++ b/apps/iap/iap-lingo4.c @@ -87,7 +87,7 @@ static void get_playlist_name(unsigned char *dest, } } if (playlist_file != NULL) { - strlcpy(dest, playlist_file->d_name, max_length); + strmemccpy(dest, playlist_file->d_name, max_length); } closedir(dp); } @@ -1465,22 +1465,21 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf) switch(buf[3]) { case 0x05: - len = strlcpy((char *)&data[7], id3.title,64); + strmemccpy((char *)&data[7], id3.title,64); break; case 0x02: - len = strlcpy((char *)&data[7], id3.artist,64); + strmemccpy((char *)&data[7], id3.artist,64); break; case 0x03: - len = strlcpy((char *)&data[7], id3.album,64); + strmemccpy((char *)&data[7], id3.album,64); break; case 0x04: case 0x06: - len = strlcpy((char *)&data[7], "Not Supported",14); + strmemccpy((char *)&data[7], "Not Supported",14); break; } break; } - (void)len; /* Shut up, compiler */ put_u32(&data[3], start_index+counter); iap_send_pkt(data, 7 + strlen(data+7) + 1); yield(); diff --git a/apps/menus/eq_menu.c b/apps/menus/eq_menu.c index 2bf26e2b5a..a0b00644ec 100644 --- a/apps/menus/eq_menu.c +++ b/apps/menus/eq_menu.c @@ -287,7 +287,7 @@ static char *advancedmenu_item_get_name(int selected_item, void *data, char *buf buffer[0] = 0; else { buffer[0] = '\t'; - strlcpy(&buffer[1], str(lang), len - 1); + strmemccpy(&buffer[1], str(lang), len - 1); } return buffer; diff --git a/apps/misc.c b/apps/misc.c index 0ad1e62902..338ef9be19 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -896,7 +896,7 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename) /* no match on filename beginning with '.' or beyond buffer_size */ if(dotpos > 1 && dotpos < buffer_size) buffer_size = dotpos; - strlcpy(buffer, filename, buffer_size); + strmemccpy(buffer, filename, buffer_size); return buffer; } @@ -1335,12 +1335,12 @@ const char *format_time_auto(char *buffer, int buf_len, long value, if (!supress_unit) { - strlcpy(buffer, unit_strings_core[units[max_idx]], buf_len); + strmemccpy(buffer, unit_strings_core[units[max_idx]], buf_len); left_offset += strlcat(buffer, " ", buf_len); strlcat(buffer, &timebuf[offsets[base_idx]], buf_len); } else - strlcpy(buffer, &timebuf[offsets[base_idx]], buf_len); + strmemccpy(buffer, &timebuf[offsets[base_idx]], buf_len); strlcat(buffer, sign, buf_len); } diff --git a/apps/onplay.c b/apps/onplay.c index bb93d204e0..8d53e26fc5 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -1587,7 +1587,7 @@ MENUITEM_FUNCTION(add_to_faves_item, 0, ID2P(LANG_ADD_TO_FAVES), #if LCD_DEPTH > 1 static bool set_backdrop(void) { - strlcpy(global_settings.backdrop_file, selected_file, + strmemccpy(global_settings.backdrop_file, selected_file, sizeof(global_settings.backdrop_file)); settings_save(); skin_backdrop_load_setting(); @@ -1600,7 +1600,7 @@ MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP), #ifdef HAVE_RECORDING static bool set_recdir(void) { - strlcpy(global_settings.rec_directory, selected_file, + strmemccpy(global_settings.rec_directory, selected_file, sizeof(global_settings.rec_directory)); settings_save(); return false; @@ -1937,7 +1937,7 @@ int onplay(char* file, int attr, int from, bool hotkey) selected_file = NULL; else { - strlcpy(selected_file_path, file, MAX_PATH); + strmemccpy(selected_file_path, file, MAX_PATH); selected_file = selected_file_path; } selected_file_attr = attr; diff --git a/apps/open_plugin.c b/apps/open_plugin.c index fad528e215..67b6f6d318 100644 --- a/apps/open_plugin.c +++ b/apps/open_plugin.c @@ -270,11 +270,11 @@ uint32_t open_plugin_add_path(const char *key, const char *plugin, const char *p if (len > ROCK_LEN && strcasecmp(&(pos[len-ROCK_LEN]), "." ROCK_EXT) == 0) { /* path */ - strlcpy(open_plugin_entry.path, plugin, OPEN_PLUGIN_BUFSZ); + strmemccpy(open_plugin_entry.path, plugin, OPEN_PLUGIN_BUFSZ); if(!parameter) parameter = ""; - strlcpy(open_plugin_entry.param, parameter, OPEN_PLUGIN_BUFSZ); + strmemccpy(open_plugin_entry.param, parameter, OPEN_PLUGIN_BUFSZ); goto retnhash; } else if (len > OP_LEN && strcasecmp(&(pos[len-OP_LEN]), "." OP_EXT) == 0) diff --git a/apps/playlist.c b/apps/playlist.c index 888b53d282..ab5c59328a 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -1457,7 +1457,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, } } - strlcpy(dir_buf, playlist->filename, playlist->dirlen); + strmemccpy(dir_buf, playlist->filename, playlist->dirlen); return format_track_path(buf, tmp_buf, buf_length, dir_buf); @@ -1551,7 +1551,7 @@ static int get_next_dir(char *dir, bool is_forward) /* if the current file is within our base dir, use its dir instead */ if (base_len == 0 || !strncmp(playlist->filename, dir, base_len)) - strlcpy(dir, playlist->filename, playlist->dirlen); + strmemccpy(dir, playlist->filename, playlist->dirlen); /* use the tree browser dircache to load files */ *(tc->dirfilter) = SHOW_ALL; @@ -2034,7 +2034,7 @@ void playlist_init(void) mutex_init(&created_playlist_mutex); playlist->current = true; - strlcpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, + strmemccpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, sizeof(playlist->control_filename)); playlist->fd = -1; playlist->control_fd = -1; @@ -2955,7 +2955,7 @@ int playlist_set_current(struct playlist_info* playlist) empty_playlist(¤t_playlist, false); - strlcpy(current_playlist.filename, playlist->filename, + strmemccpy(current_playlist.filename, playlist->filename, sizeof(current_playlist.filename)); current_playlist.utf8 = playlist->utf8; @@ -3517,7 +3517,7 @@ char *playlist_name(const struct playlist_info* playlist, char *buf, if (!playlist) playlist = ¤t_playlist; - strlcpy(buf, playlist->filename+playlist->dirlen, buf_size); + strmemccpy(buf, playlist->filename+playlist->dirlen, buf_size); if (!buf[0]) return NULL; @@ -3537,7 +3537,7 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf, if (!playlist) playlist = ¤t_playlist; - strlcpy(buf, playlist->filename, buf_size); + strmemccpy(buf, playlist->filename, buf_size); if (!buf[0]) return NULL; diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c index 98a2bb4cdb..0813db11c6 100644 --- a/apps/playlist_catalog.c +++ b/apps/playlist_catalog.c @@ -128,8 +128,8 @@ void catalog_set_directory(const char* directory) } else { - strlcpy(global_settings.playlist_catalog_dir, - directory, sizeof(global_settings.playlist_catalog_dir)); + strmemccpy(global_settings.playlist_catalog_dir, + directory, sizeof(global_settings.playlist_catalog_dir)); } initialized = false; initialize_catalog(); @@ -164,8 +164,8 @@ restart: if (browse.flags & BROWSE_SELECTED) { - strlcpy(most_recent_playlist, selected_playlist+playlist_dir_length+1, - sizeof(most_recent_playlist)); + strmemccpy(most_recent_playlist, selected_playlist+playlist_dir_length+1, + sizeof(most_recent_playlist)); if (view) { @@ -180,7 +180,7 @@ restart: else { result = 0; - strlcpy(playlist, selected_playlist, MAX_PATH); + strmemccpy(playlist, selected_playlist, MAX_PATH); } } @@ -360,7 +360,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr, (name!=NULL && (sel_attr & ATTR_DIRECTORY))?name+1:""); } else - strlcpy(playlist, m3u8name, MAX_PATH); + strmemccpy(playlist, m3u8name, MAX_PATH); if (kbd_input(playlist, MAX_PATH, NULL)) return false; diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index f1f8954113..6c80b373a9 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c @@ -517,8 +517,7 @@ static enum pv_onplay_result open_with(const struct playlist_entry *current_trac char selected_track[MAX_PATH]; close_playlist_viewer(); - if (!memccpy (selected_track, current_track->name, '\0', sizeof(selected_track))) - selected_track[sizeof(selected_track) - 1] = '\0'; + strmemccpy(selected_track, current_track->name, sizeof(selected_track)); return (filetype_list_viewers(selected_track) == @@ -532,8 +531,7 @@ static enum pv_onplay_result open_pictureflow(const struct playlist_entry *curre char selected_track[MAX_PATH]; close_playlist_viewer(); - if (!memccpy (selected_track, current_track->name, '\0', sizeof(selected_track))) - selected_track[sizeof(selected_track) - 1] = '\0'; + strmemccpy(selected_track, current_track->name, sizeof(selected_track)); return (filetype_load_plugin((void *)"pictureflow", selected_track) == PLUGIN_USB_CONNECTED ? PV_ONPLAY_USB_CLOSED : PV_ONPLAY_CLOSED); diff --git a/apps/radio/presets.c b/apps/radio/presets.c index 6966f7e591..1cd85637e8 100644 --- a/apps/radio/presets.c +++ b/apps/radio/presets.c @@ -225,7 +225,7 @@ void radio_load_presets(char *filename) } /* Temporary preset, loaded until player shuts down. */ else if(filename[0] == '/') - strlcpy(filepreset, filename, sizeof(filepreset)); + strmemccpy(filepreset, filename, sizeof(filepreset)); /* Preset from default directory. */ else snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", @@ -246,7 +246,7 @@ void radio_load_presets(char *filename) { struct fmstation * const fms = &presets[num_presets]; fms->frequency = f; - strlcpy(fms->name, name, MAX_FMPRESET_LEN+1); + strmemccpy(fms->name, name, MAX_FMPRESET_LEN+1); num_presets++; } } diff --git a/apps/radio/radioart.c b/apps/radio/radioart.c index 34efdea0da..230948c051 100644 --- a/apps/radio/radioart.c +++ b/apps/radio/radioart.c @@ -82,7 +82,7 @@ static int load_radioart_image(struct radioart *ra, const char* preset_name, #endif return -1; } - strlcpy(ra->name, preset_name, MAX_FMPRESET_LEN+1); + strmemccpy(ra->name, preset_name, MAX_FMPRESET_LEN+1); ra->dim.height = dim->height; ra->dim.width = dim->width; ra->last_tick = current_tick; diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c index e94ffcfb80..8991a81848 100644 --- a/apps/recorder/albumart.c +++ b/apps/recorder/albumart.c @@ -67,7 +67,7 @@ static char* strip_filename(char* buf, int buf_size, const char* fullpath) } len = MIN(sep - fullpath + 1, buf_size - 1); - strlcpy(buf, fullpath, len + 1); + strmemccpy(buf, fullpath, len + 1); return (sep + 1); } @@ -266,7 +266,7 @@ bool search_albumart_files(const struct mp3entry *id3, const char *size_string, if (!found) return false; - strlcpy(buf, path, buflen); + strmemccpy(buf, path, buflen); logf("Album art found: %s", path); return true; } diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c index 45cccdcf8b..f64061d303 100644 --- a/apps/recorder/keyboard.c +++ b/apps/recorder/keyboard.c @@ -1063,7 +1063,7 @@ static void kbd_draw_edit_line(struct keyboard_parameters *pm, while (*utf8 && i < pm->max_chars_text) { j = utf8seek(utf8, 1); - strlcpy(outline, utf8, j+1); + strmemccpy(outline, utf8, j+1); sc->getstringsize(outline, &w, NULL); sc->putsxy(text_margin + i*pm->text_w + (pm->text_w-w)/2, y, outline); diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index d3d45d3e1c..f7f4c77928 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c @@ -1352,7 +1352,7 @@ static void mark_stream(const char *path, enum mark_stream_action action) file->hdr.type = CHUNK_T_STREAM_START; file->hdr.size = count; - strlcpy(file->path, path, MAX_PATH); + strmemccpy(file->path, path, MAX_PATH); } } @@ -1582,7 +1582,7 @@ static void on_record(const char *filename) /* Copy path and let caller go */ char path[MAX_PATH]; - strlcpy(path, filename, MAX_PATH); + strmemccpy(path, filename, MAX_PATH); queue_reply(&audio_queue, 0); diff --git a/apps/root_menu.c b/apps/root_menu.c index 227ed75ee3..ae3d1b39b0 100644 --- a/apps/root_menu.c +++ b/apps/root_menu.c @@ -107,7 +107,7 @@ static void rootmenu_track_changed_callback(unsigned short id, void* param) { (void)id; struct mp3entry *id3 = ((struct track_event *)param)->id3; - strlcpy(current_track_path, id3->path, MAX_PATH); + strmemccpy(current_track_path, id3->path, MAX_PATH); } static int browser(void* param) { diff --git a/apps/screens.c b/apps/screens.c index 9191922c31..db24e534c1 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -20,7 +20,7 @@ ****************************************************************************/ #include -#include +#include #include #include #include "backlight.h" @@ -562,8 +562,7 @@ static const char * id3_get_or_speak_info(int selected_item, void* data, if (!id3->comment) return NULL; - if (!memccpy (buffer, id3->comment, '\0', buffer_len)) - buffer[buffer_len - 1] = '\0'; + strmemccpy(buffer, id3->comment, buffer_len); val=buffer; if(say_it && val) @@ -612,8 +611,7 @@ static const char * id3_get_or_speak_info(int selected_item, void* data, if (id3->codectype >= AFMT_NUM_CODECS) return NULL; - if (!memccpy (buffer, audio_formats[id3->codectype].label, '\0', buffer_len)) - buffer[buffer_len - 1] = '\0'; + strmemccpy(buffer, audio_formats[id3->codectype].label, buffer_len); val=buffer; if(say_it) diff --git a/apps/settings.c b/apps/settings.c index edf4d2b13f..7c4dc4d124 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -35,8 +35,7 @@ #include "backlight.h" #include "audio.h" #include "talk.h" -#include "strlcpy.h" -#include "strcasestr.h" +#include "string-extra.h" #include "rtc.h" #include "power.h" #include "ata_idle_notify.h" @@ -251,7 +250,7 @@ bool cfg_string_to_int(int setting_id, int* out, const char* str) } else return false; } - strlcpy(temp, start, end-start+1); + strmemccpy(temp, start, end-start+1); if (!strcmp(str, temp)) { *out = count; @@ -343,18 +342,22 @@ bool settings_load_config(const char* file, bool apply) size_t len = strlen(dir); if (!strncasecmp(value, dir, len)) { - strlcpy(storage, &value[len], MAX_PATH); + strmemccpy(storage, &value[len], MAX_PATH); } - else strlcpy(storage, value, MAX_PATH); + else + strmemccpy(storage, value, MAX_PATH); + } - else strlcpy(storage, value, MAX_PATH); + else + strmemccpy(storage, value, MAX_PATH); + if (settings[i].filename_setting->suffix) { char *s = strcasestr(storage,settings[i].filename_setting->suffix); if (s) *s = '\0'; } - strlcpy((char*)settings[i].setting, storage, - settings[i].filename_setting->max_len); + strmemccpy((char*)settings[i].setting, storage, + settings[i].filename_setting->max_len); break; } } @@ -393,11 +396,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len) if (value[count] == val) { if (end == NULL) - strlcpy(buf, start, buf_len); + strmemccpy(buf, start, buf_len); else { int len = MIN(buf_len, (end-start) + 1); - strlcpy(buf, start, len); + strmemccpy(buf, start, len); } return true; } @@ -421,11 +424,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len) } end = strchr(start,','); if (end == NULL) - strlcpy(buf, start, buf_len); + strmemccpy(buf, start, buf_len); else { int len = MIN(buf_len, (end-start) + 1); - strlcpy(buf, start, len); + strmemccpy(buf, start, len); } return true; } @@ -491,7 +494,7 @@ bool cfg_to_string(int i/*setting_id*/, char* buf, int buf_len) else { int len = MIN(buf_len, settings[i].filename_setting->max_len); - strlcpy(buf,(char*)settings[i].setting,len); + strmemccpy(buf,(char*)settings[i].setting,len); } break; } /* switch () */ @@ -1071,8 +1074,8 @@ void reset_setting(const struct settings_list *setting, void *var) break; case F_T_CHARPTR: case F_T_UCHARPTR: - strlcpy((char*)var, setting->default_val.charptr, - setting->filename_setting->max_len); + strmemccpy((char*)var, setting->default_val.charptr, + setting->filename_setting->max_len); break; } } @@ -1265,6 +1268,6 @@ void set_file(const char* filename, char* setting, const int maxlen) if (len > maxlen) return; - strlcpy(setting, fptr, len); + strmemccpy(setting, fptr, len); settings_save(); } diff --git a/apps/settings_list.c b/apps/settings_list.c index f54738163a..f733ee4f69 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -624,11 +624,11 @@ static char* qs_write_to_cfg(void* setting, char*buf, int buf_len) int index = *(int*)setting; if (index < 0 || index >= nb_settings) { - strlcpy(buf, "-", buf_len); + strmemccpy(buf, "-", buf_len); return buf; } const struct settings_list *var = &settings[index]; - strlcpy(buf, var->cfg_name, buf_len); + strmemccpy(buf, var->cfg_name, buf_len); return buf; } static bool qs_is_changed(void* setting, void* defaultval) diff --git a/apps/shortcuts.c b/apps/shortcuts.c index 1253e77a65..752ca977e6 100644 --- a/apps/shortcuts.c +++ b/apps/shortcuts.c @@ -284,7 +284,7 @@ void shortcuts_add(enum shortcut_type type, const char* value) if (type == SHORTCUT_SETTING) sc->u.setting = (void*)value; else - strlcpy(sc->u.path, value, MAX_PATH); + strmemccpy(sc->u.path, value, MAX_PATH); if (first_idx_to_writeback < 0) first_idx_to_writeback = shortcut_count - 1; @@ -325,7 +325,7 @@ static int readline_cb(int n, char *buf, void *parameters) } else if (nm_op == 1) /*name*/ { - strlcpy(sc->name, value, MAX_SHORTCUT_NAME); + strmemccpy(sc->name, value, MAX_SHORTCUT_NAME); } else if (nm_op == 2) /*data*/ { @@ -339,7 +339,7 @@ static int readline_cb(int n, char *buf, void *parameters) case SHORTCUT_FILE: case SHORTCUT_DEBUGITEM: case SHORTCUT_PLAYLISTMENU: - strlcpy(sc->u.path, value, MAX_PATH); + strmemccpy(sc->u.path, value, MAX_PATH); break; case SHORTCUT_SETTING: sc->u.setting = find_setting_by_cfgname(value, NULL); @@ -374,7 +374,7 @@ static int readline_cb(int n, char *buf, void *parameters) } else if (nm_op == 4) /*talkclip*/ { - strlcpy(sc->talk_clip, value, MAX_PATH); + strmemccpy(sc->talk_clip, value, MAX_PATH); } } return 0; @@ -534,7 +534,7 @@ static int shortcut_menu_speak_item(int selected_item, void * data) if (*filename != '\0') { int dirlen = (filename - sc->u.path); - strlcpy(path, sc->u.path, dirlen + 1); + strmemccpy(path, sc->u.path, dirlen + 1); dir = opendir(path); if (dir) { diff --git a/apps/tagcache.c b/apps/tagcache.c index c5c40b9d50..a6c4c875be 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -853,7 +853,7 @@ static bool retrieve(struct tagcache_search *tcs, IF_DIRCACHE(int idx_id,) { struct tagfile_entry *ep = (struct tagfile_entry *)&tcramcache.hdr->tags[tag][seek]; - strlcpy(buf, ep->tag_data, bufsz); + strmemccpy(buf, ep->tag_data, bufsz); return true; } @@ -3469,7 +3469,7 @@ static bool write_tag(int fd, const char *tagstr, const char *datastr) } str_setlen(buf, bufsz - 1); - strlcpy(&buf[i], "\" ", (bufsz - i - 1)); + strmemccpy(&buf[i], "\" ", (bufsz - i - 1)); write(fd, buf, i + 2); @@ -4737,7 +4737,7 @@ void do_tagcache_build(const char *path[]) /* check_dir might add new roots */ for(this = &roots_ll[0]; this; this = this->next) { - strlcpy(curpath, this->path, sizeof(curpath)); + strmemccpy(curpath, this->path, sizeof(curpath)); ret = ret && check_dir(this->path, true); } free_search_roots(&roots_ll[0]); @@ -4792,7 +4792,7 @@ void tagcache_build(void) { char *vect[MAX_STATIC_ROOTS + 1]; /* +1 to ensure NULL sentinel */ char str[sizeof(global_settings.tagcache_scan_paths)]; - strlcpy(str, global_settings.tagcache_scan_paths, sizeof(str)); + strmemccpy(str, global_settings.tagcache_scan_paths, sizeof(str)); int res = split_string(str, ':', vect, MAX_STATIC_ROOTS); vect[res] = NULL; diff --git a/apps/tagtree.c b/apps/tagtree.c index abb6cf5cb0..fc1ce26f40 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -779,7 +779,7 @@ static bool parse_search(struct menu_entry *entry, const char *str) logf("tagtree failed to allocate %s", "menu"); return false; } - strlcpy(menus[menu_count]->id, buf, MAX_MENU_ID_SIZE); + strmemccpy(menus[menu_count]->id, buf, MAX_MENU_ID_SIZE); entry->link = menu_count; ++menu_count; @@ -1118,7 +1118,7 @@ static int parse_line(int n, char *buf, void *parameters) } menu = menus[menu_count]; ++menu_count; - strlcpy(menu->id, data, MAX_MENU_ID_SIZE); + strmemccpy(menu->id, data, MAX_MENU_ID_SIZE); } if (get_token_str(menu->title, sizeof(menu->title)) < 0) @@ -1898,8 +1898,8 @@ int tagtree_enter(struct tree_context* c, bool is_visible) csi = &menu->items[seek]->si; c->currextra = 0; - strlcpy(current_title[c->currextra], dptr->name, - sizeof(current_title[0])); + strmemccpy(current_title[c->currextra], dptr->name, + sizeof(current_title[0])); /* Read input as necessary. */ for (i = 0; i < csi->tagorder_count; i++) @@ -1928,7 +1928,7 @@ int tagtree_enter(struct tree_context* c, bool is_visible) if (source == source_current_path && id3) { char *e; - strlcpy(searchstring, id3->path, SEARCHSTR_SIZE); + strmemccpy(searchstring, id3->path, SEARCHSTR_SIZE); e = strrchr(searchstring, '/'); if (e) *e = '\0'; @@ -1941,7 +1941,7 @@ int tagtree_enter(struct tree_context* c, bool is_visible) char **src = (char**)((char*)id3 + offset); if (*src) { - strlcpy(searchstring, *src, SEARCHSTR_SIZE); + strmemccpy(searchstring, *src, SEARCHSTR_SIZE); } } else @@ -1994,8 +1994,8 @@ int tagtree_enter(struct tree_context* c, bool is_visible) c->dirlevel--; /* Update the statusbar title */ - strlcpy(current_title[c->currextra], dptr->name, - sizeof(current_title[0])); + strmemccpy(current_title[c->currextra], dptr->name, + sizeof(current_title[0])); break; default: @@ -2251,7 +2251,7 @@ char* tagtree_get_entry_name(struct tree_context *c, int id, struct tagentry *entry = tagtree_get_entry(c, id); if (!entry) return NULL; - strlcpy(buf, entry->name, bufsize); + strmemccpy(buf, entry->name, bufsize); return buf; } diff --git a/apps/talk.c b/apps/talk.c index 65933c6895..777c0f5a01 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -810,8 +810,8 @@ void talk_init(void) talk_force_shutup(); /* In case we have something speaking! */ talk_initialized = true; - strlcpy((char *)last_lang, (char *)global_settings.lang_file, - MAX_FILENAME); + strmemccpy((char *)last_lang, (char *)global_settings.lang_file, + MAX_FILENAME); /* reset some states */ queue_write = queue_read = 0; /* reset the queue */ @@ -1066,14 +1066,21 @@ static int talk_spell_basename(const char *path, } char buf[MAX_PATH]; /* Spell only the path component after the last slash */ - strlcpy(buf, path, sizeof(buf)); - if(strlen(buf) >1 && buf[strlen(buf)-1] == '/') - /* strip trailing slash */ - buf[strlen(buf)-1] = '\0'; + char *end = strmemccpy(buf, path, sizeof(buf)); + + if (!end) + return 0; + + size_t len = end - buf - 1; + if(len >1 && buf[len-1] == '/') + buf[--len] = '\0'; /* strip trailing slash */ + char *ptr = strrchr(buf, '/'); - if(ptr && strlen(buf) >1) + if(ptr && len >1) ++ptr; - else ptr = buf; + else + ptr = buf; + return talk_spell(ptr, enqueue); } @@ -1122,7 +1129,7 @@ int talk_fullpath(const char* path, bool enqueue) return talk_spell(path, true); talk_id(VOICE_CHAR_SLASH, true); char buf[MAX_PATH]; - strlcpy(buf, path, MAX_PATH); + strmemccpy(buf, path, MAX_PATH); char *start = buf+1; /* start of current component */ char *ptr = strchr(start, '/'); /* end of current component */ while(ptr) { /* There are more slashes ahead */ @@ -1636,7 +1643,7 @@ bool talk_get_debug_data(struct talk_debug_data *data) if (global_settings.lang_file[0] && global_settings.lang_file[0] != 0xff) p_lang = (char *)global_settings.lang_file; - strlcpy(data->voicefile, p_lang, sizeof(data->voicefile)); + strmemccpy(data->voicefile, p_lang, sizeof(data->voicefile)); if (!has_voicefile || index_handle <= 0) { diff --git a/apps/tree.c b/apps/tree.c index 1939c7ee05..23a909281d 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -383,7 +383,7 @@ static int update_dir(void) { if (ft_load(&tc, NULL) < 0) return -1; - strlcpy(lastdir, tc.currdir, MAX_PATH); + strmemccpy(lastdir, tc.currdir, MAX_PATH); changed = true; } } @@ -573,7 +573,7 @@ void set_current_file(const char *path) name = strrchr(path+1,'/'); if (name) { - strlcpy(tc.currdir, path, name - path + 1); + strmemccpy(tc.currdir, path, name - path + 1); name++; } else @@ -582,7 +582,7 @@ void set_current_file(const char *path) name = path+1; } - strlcpy(lastfile, name, MAX_PATH); + strmemccpy(lastfile, name, MAX_PATH); /* If we changed dir we must recalculate the dirlevel @@ -1007,7 +1007,7 @@ int rockbox_browse(struct browse_context *browse) tc.selected_item = 0; tc.dirlevel = 0; - strlcpy(tc.currdir, browse->root, sizeof(tc.currdir)); + strmemccpy(tc.currdir, browse->root, sizeof(tc.currdir)); } start_wps = false; @@ -1030,7 +1030,7 @@ int rockbox_browse(struct browse_context *browse) if (dirfilter != SHOW_ID3DB) tc.dirfilter = &global_settings.dirfilter; tc.browse = browse; - strlcpy(current, browse->root, MAX_PATH); + strmemccpy(current, browse->root, MAX_PATH); set_current_file(current); if (browse->flags&BROWSE_RUNFILE) ret_val = ft_enter(&tc); diff --git a/firmware/SOURCES b/firmware/SOURCES index 94a986c9f8..b13a5ac304 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -240,6 +240,7 @@ common/strcasestr.c common/strnatcmp.c common/strlcat.c common/strlcpy.c +common/strmemccpy.c common/structec.c common/timefuncs.c common/unicode.c diff --git a/firmware/buflib.c b/firmware/buflib.c index 3130bc960c..2ce9cc344c 100644 --- a/firmware/buflib.c +++ b/firmware/buflib.c @@ -30,7 +30,7 @@ #include /* for snprintf() */ #include /* for ptrdiff_t */ #include "buflib.h" -#include "string-extra.h" /* strlcpy() */ +#include "string-extra.h" /* strmemccpy() */ #include "debug.h" #include "panic.h" #include "crc32.h" @@ -974,7 +974,7 @@ buflib_alloc_maximum(struct buflib_context* ctx, const char* name, size_t *size, if (*size <= 0) /* OOM */ return -1; - strlcpy(buf, name, sizeof(buf)); + strmemccpy(buf, name, sizeof(buf)); return buflib_alloc_ex(ctx, *size, buf, ops); } diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 1d6371a6b5..5902f8b3fd 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -1707,8 +1707,8 @@ static int sab_process_dir(struct dircache_entry *ce) /* save current paths size */ int pathpos = strlen(sab_path); /* append entry */ - strlcpy(&sab_path[pathpos], "/", sizeof(sab_path) - pathpos); - strlcpy(&sab_path[pathpos+1], entry->d_name, sizeof(sab_path) - pathpos - 1); + strmemccpy(&sab_path[pathpos], "/", sizeof(sab_path) - pathpos); + strmemccpy(&sab_path[pathpos+1], entry->d_name, sizeof(sab_path) - pathpos - 1); int rc = sab_process_dir(ce->down); /* restore path */ @@ -1735,7 +1735,7 @@ static int sab_process_dir(struct dircache_entry *ce) static int sab_process_volume(IF_MV(int volume,) struct dircache_entry *ce) { memset(ce, 0, sizeof(struct dircache_entry)); - strlcpy(sab_path, "/", sizeof sab_path); + strmemccpy(sab_path, "/", sizeof sab_path); return sab_process_dir(ce); } @@ -1755,7 +1755,7 @@ int dircache_readdir_r(struct dircache_dirscan *dir, struct DIRENT *result) dir->scanidx = ce - dircache_root; - strlcpy(result->d_name, ce->d_name, sizeof (result->d_name)); + strmemccpy(result->d_name, ce->d_name, sizeof (result->d_name)); result->info = ce->dirinfo; return 1; diff --git a/firmware/common/strlcpy.c b/firmware/common/strlcpy.c index e320649140..bfdb6482a4 100644 --- a/firmware/common/strlcpy.c +++ b/firmware/common/strlcpy.c @@ -1,51 +1,39 @@ -/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Copyright (C) 2022 William Wilgus * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ #include +#include "strmemccpy.h" /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ -size_t -strlcpy(char *dst, const char *src, size_t siz) +size_t strlcpy(char *dst, const char *src, size_t siz) { - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } + /* Copy as many bytes as will fit */ + char *d = strmemccpy(dst, src, siz); + if (d) + return (d - dst - 1); /* count does not include NUL */ - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ + /* Not enough room in dst, add NUL and traverse rest of src */ + return(siz + strlen(src+siz)); /* count does not include NUL */ } - diff --git a/firmware/common/strmemccpy.c b/firmware/common/strmemccpy.c new file mode 100644 index 0000000000..830907f55e --- /dev/null +++ b/firmware/common/strmemccpy.c @@ -0,0 +1,38 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2022 William Wilgus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +/* (firmware/common/strmemccpy.c) */ +#include "string-extra.h" + +/* copies src to a buffer of len bytes stopping after + * len or the first NULL (\0) in src + * NULL terminates except when len = 0 + * If len was exceeded NULL is returned otherwise returns + * a pointer to the first byte following the NULL in dst. +*/ +char * strmemccpy(char *dst, const char *src, size_t len) +{ + char * ret = (char *)memccpy(dst, src, '\0', len); + if (ret == NULL && len > 0) + { + dst[len - 1] = '\0'; + } + return ret; +} diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 389d30917b..975c494b5a 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c @@ -699,7 +699,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, } /* copy contents to the line buffer */ - strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); + strmemccpy(s->linebuffer, string, sizeof(s->linebuffer)); /* scroll bidirectional or forward only depending on the string width */ if ( LCDFN(scroll_info).bidir_limit ) { s->bidir = w < (vp->width) * diff --git a/firmware/font.c b/firmware/font.c index 97a15221fc..d7473346da 100644 --- a/firmware/font.c +++ b/firmware/font.c @@ -854,7 +854,7 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) static void font_path_to_glyph_path( const char *font_path, char *glyph_path) { /* take full file name, cut extension, and add .glyphcache */ - strlcpy(glyph_path, font_path, MAX_PATH); + strmemccpy(glyph_path, font_path, MAX_PATH); glyph_path[strlen(glyph_path)-4] = '\0'; strcat(glyph_path, ".gc"); } diff --git a/firmware/general.c b/firmware/general.c index 8508b34b88..d421d722a8 100644 --- a/firmware/general.c +++ b/firmware/general.c @@ -107,7 +107,7 @@ char *create_numbered_filename(char *buffer, const char *path, int suffixlen = strlen(suffix); if (buffer != path) - strlcpy(buffer, path, MAX_PATH); + strmemccpy(buffer, path, MAX_PATH); pathlen = strlen(buffer); @@ -181,7 +181,7 @@ char *create_datetime_filename(char *buffer, const char *path, last_tm = *tm; if (buffer != path) - strlcpy(buffer, path, MAX_PATH); + strmemccpy(buffer, path, MAX_PATH); pathlen = strlen(buffer); snprintf(buffer + pathlen, MAX_PATH - pathlen, diff --git a/firmware/include/string-extra.h b/firmware/include/string-extra.h index 549a018dfc..a9b34661a7 100644 --- a/firmware/include/string-extra.h +++ b/firmware/include/string-extra.h @@ -25,6 +25,7 @@ #include "strlcat.h" #include "strcasecmp.h" #include "strcasestr.h" +#include "strmemccpy.h" #include "strtok_r.h" #include "memset16.h" diff --git a/firmware/include/strmemccpy.h b/firmware/include/strmemccpy.h new file mode 100644 index 0000000000..c7004610dd --- /dev/null +++ b/firmware/include/strmemccpy.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2022 William Wilgus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef __STRMEMCCPY_H__ +#define __STRMEMCCPY_H__ +/* copies src to a buffer of len bytes stopping after + * len or the first NULL (\0) in src + * NULL terminates except when len = 0 + * If len was exceeded NULL is returned otherwise returns + * a pointer to the first byte following the NULL in dst. +*/ +char * strmemccpy(char *dst, const char *src, size_t len); +#endif -- cgit v1.2.3