diff --git a/apps/bookmark.c b/apps/bookmark.c index 8c3cc48391..892a3d35b2 100644 --- a/apps/bookmark.c +++ b/apps/bookmark.c @@ -1002,17 +1002,14 @@ static bool parse_bookmark(const char *bookmark, if (resume_file != NULL) { size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s); - len = MIN(resume_file_size - 1, len); - strncpy(resume_file, s, len); - resume_file[len] = 0; + strlcpy(resume_file, s, len + 1); } if (end != NULL && file_name != NULL) { end++; - strncpy(file_name, end, MAX_PATH - 1); - file_name[MAX_PATH - 1] = 0; + strlcpy(file_name, end, MAX_PATH); } return true; diff --git a/apps/buffering.c b/apps/buffering.c index afc444a456..08590c9fdf 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -919,7 +919,7 @@ int bufopen(const char *file, size_t offset, enum data_type type) h->widx = buf_widx; h->available = 0; h->type = type; - strncpy(h->path, file, MAX_PATH); + strlcpy(h->path, file, MAX_PATH); buf_widx += sizeof(struct mp3entry); /* safe because the handle can't wrap */ @@ -952,7 +952,7 @@ int bufopen(const char *file, size_t offset, enum data_type type) return ERR_BUFFER_FULL; } - strncpy(h->path, file, MAX_PATH); + strlcpy(h->path, file, MAX_PATH); h->offset = adjusted_offset; h->ridx = buf_widx; h->widx = buf_widx; diff --git a/apps/codecs.c b/apps/codecs.c index c86aeda422..0a3dde64be 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -122,7 +122,6 @@ struct codec_api ci = { /* strings and memory */ strcpy, - strncpy, strlen, strcmp, strcat, diff --git a/apps/codecs.h b/apps/codecs.h index 631cf58a77..b61c3c0c94 100644 --- a/apps/codecs.h +++ b/apps/codecs.h @@ -75,12 +75,12 @@ #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ /* increase this every time the api struct changes */ -#define CODEC_API_VERSION 32 +#define CODEC_API_VERSION 33 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define CODEC_MIN_API_VERSION 32 +#define CODEC_MIN_API_VERSION 33 /* codec return codes */ enum codec_status { @@ -180,7 +180,6 @@ struct codec_api { /* strings and memory */ char* (*strcpy)(char *dst, const char *src); - char* (*strncpy)(char *dst, const char *src, size_t length); size_t (*strlen)(const char *str); int (*strcmp)(const char *, const char *); char *(*strcat)(char *s1, const char *s2); diff --git a/apps/cuesheet.c b/apps/cuesheet.c index aace64a8fc..fa1d93f334 100644 --- a/apps/cuesheet.c +++ b/apps/cuesheet.c @@ -84,7 +84,7 @@ bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path) return false; } - strncpy(cuepath, trackpath, MAX_PATH); + strlcpy(cuepath, trackpath, MAX_PATH); dot = strrchr(cuepath, '.'); strcpy(dot, ".cue"); @@ -103,7 +103,7 @@ bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path) } if (found_cue_path) - strncpy(found_cue_path, cuepath, MAX_PATH); + strlcpy(found_cue_path, cuepath, MAX_PATH); return true; } @@ -205,8 +205,7 @@ bool parse_cuesheet(char *file, struct cuesheet *cue) } else { - strncpy(dest, string, MAX_NAME*3); - dest[MAX_NAME*3] = '\0'; + strlcpy(dest, string, MAX_NAME*3 + 1); } } } @@ -218,10 +217,10 @@ bool parse_cuesheet(char *file, struct cuesheet *cue) for (i = 0; i < cue->track_count; i++) { if (*(cue->tracks[i].performer) == '\0') - strncpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3); + strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3); if (*(cue->tracks[i].songwriter) == '\0') - strncpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3); + strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3); } return true; @@ -271,7 +270,7 @@ static char *list_get_name_cb(int selected_item, struct cuesheet *cue = (struct cuesheet *)data; if (selected_item & 1) - strncpy(buffer, cue->tracks[selected_item/2].title, buffer_len); + strlcpy(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); diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 60594b677c..648a7e6cae 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -1910,8 +1910,7 @@ static int disk_callback(int btn, struct gui_synclist *lists) if (card->initialized > 0) { - card_name[6] = '\0'; - strncpy(card_name, ((unsigned char*)card->cid) + 3, 6); + strlcpy(card_name, ((unsigned char*)card->cid) + 3, sizeof(card_name)); simplelist_addline(SIMPLELIST_ADD_LINE, "%s Rev %d.%d", card_name, (int) card_extract_bits(card->cid, 55, 4), diff --git a/apps/gui/buttonbar.c b/apps/gui/buttonbar.c index abf1800bb2..3c343f09ac 100644 --- a/apps/gui/buttonbar.c +++ b/apps/gui/buttonbar.c @@ -86,18 +86,15 @@ void gui_buttonbar_set(struct gui_buttonbar * buttonbar, gui_buttonbar_unset(buttonbar); if(caption1) { - strncpy(buttonbar->caption[0], caption1, 7); - buttonbar->caption[0][7] = 0; + strlcpy(buttonbar->caption[0], caption1, BUTTONBAR_CAPTION_LENGTH); } if(caption2) { - strncpy(buttonbar->caption[1], caption2, 7); - buttonbar->caption[1][7] = 0; + strlcpy(buttonbar->caption[1], caption2, BUTTONBAR_CAPTION_LENGTH); } if(caption3) { - strncpy(buttonbar->caption[2], caption3, 7); - buttonbar->caption[2][7] = 0; + strlcpy(buttonbar->caption[2], caption3, BUTTONBAR_CAPTION_LENGTH); } } diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index f480f616a2..c0923a9ab5 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -659,8 +659,7 @@ static char* get_dir(char* buf, int buf_size, const char* path, int level) return NULL; len = MIN(last_sep - sep, buf_size - 1); - strncpy(buf, sep + 1, len); - buf[len] = 0; + strlcpy(buf, sep + 1, len + 1); return buf; } @@ -1183,12 +1182,12 @@ static const char *get_token_value(struct gui_wps *gwps, { /* we need 11 characters (full line) for progress-bar */ - strncpy(buf, " ", buf_size); + strlcpy(buf, " ", buf_size); } else { /* Tell the user if we have an OldPlayer */ - strncpy(buf, " ", buf_size); + strlcpy(buf, " ", buf_size); } return buf; #endif @@ -1254,11 +1253,11 @@ static const char *get_token_value(struct gui_wps *gwps, break; case 2: case 4: - strncpy(buf, id3->track_gain_string, buf_size); + strlcpy(buf, id3->track_gain_string, buf_size); break; case 3: case 5: - strncpy(buf, id3->album_gain_string, buf_size); + strlcpy(buf, id3->album_gain_string, buf_size); break; } return buf; diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index 7b6c489bf3..01259c4136 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c @@ -76,7 +76,7 @@ char *option_get_valuestring(const struct settings_list *setting, if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) { bool val = (bool)temp_var; - strncpy(buffer, str(val? setting->bool_setting->lang_yes : + strlcpy(buffer, str(val? setting->bool_setting->lang_yes : setting->bool_setting->lang_no), buf_len); } #if 0 /* probably dont need this one */ @@ -137,7 +137,7 @@ 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) { - strncpy(buffer, str(info->talks[(int)temp_var]), buf_len); + strlcpy(buffer, str(info->talks[(int)temp_var]), buf_len); } else { @@ -149,7 +149,7 @@ char *option_get_valuestring(const struct settings_list *setting, { int value= (int)temp_var; char *val = P2STR(setting->choice_setting->desc[value]); - strncpy(buffer, val, buf_len); + strlcpy(buffer, val, buf_len); } } return buffer; diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index 47dcb4ead1..5e215090f5 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c @@ -617,7 +617,7 @@ static void gui_statusbar_time(struct screen * display, struct tm *time) snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute); } else { - strncpy(buffer, "--:--", sizeof buffer); + strlcpy(buffer, "--:--", sizeof(buffer)); } display->setfont(FONT_SYSFIXED); display->getstringsize(buffer, &width, &height); @@ -626,7 +626,6 @@ static void gui_statusbar_time(struct screen * display, struct tm *time) STATUSBAR_Y_POS, buffer); } display->setfont(FONT_UI); - } #endif @@ -758,14 +757,14 @@ static void gui_statusbar_icon_recording_info(struct screen * display) if (global_settings.rec_source == AUDIO_SRC_SPDIF) { /* Can't measure S/PDIF sample rate on Archos/Sim yet */ - strncpy(buffer, "--", sizeof(buffer)); + strlcpy(buffer, "--", sizeof(buffer)); } else #endif /* HAVE_SPDIF_IN */ { static char const * const freq_strings[12] = { "44", "48", "32", "22", "24", "16" }; - strncpy(buffer, freq_strings[global_settings.rec_frequency], + strlcpy(buffer, freq_strings[global_settings.rec_frequency], sizeof(buffer)); } diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 09bcab8443..8ae83924c2 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -1489,8 +1489,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) break; } - strncpy(stringbuf, string_start, len); - *(stringbuf + len) = '\0'; + strlcpy(stringbuf, string_start, len+1); data->strings[data->num_strings] = stringbuf; stringbuf += len + 1; @@ -1781,11 +1780,9 @@ bool wps_data_load(struct wps_data *wps_data, #ifdef HAVE_LCD_BITMAP /* get the bitmap dir */ char bmpdir[MAX_PATH]; - size_t bmpdirlen; char *dot = strrchr(buf, '.'); - bmpdirlen = dot - buf; - strncpy(bmpdir, buf, dot - buf); - bmpdir[bmpdirlen] = 0; + + strlcpy(bmpdir, buf, dot - buf + 1); /* load the bitmaps that were found by the parsing */ if (!load_wps_bitmaps(wps_data, bmpdir)) { diff --git a/apps/iap.c b/apps/iap.c index 51f5e5900b..592bbdbbf8 100644 --- a/apps/iap.c +++ b/apps/iap.c @@ -495,6 +495,7 @@ void iap_handlepkt(void) unsigned char data[70] = {0x04, 0x00, 0xFF}; struct mp3entry id3; int fd; + size_t len; long tracknum = (signed long)serbuf[4] << 24 | (signed long)serbuf[5] << 16 | (signed long)serbuf[6] << 8 | serbuf[7]; @@ -520,16 +521,16 @@ void iap_handlepkt(void) switch(serbuf[3]) { case 0x20: - strncpy((char *)&data[3], id3.title, 64); - iap_send_pkt(data, 4+strlen(id3.title)); + len = strlcpy((char *)&data[3], id3.title, 64); + iap_send_pkt(data, 4+len); break; case 0x22: - strncpy((char *)&data[3], id3.artist, 64); - iap_send_pkt(data, 4+strlen(id3.artist)); + len = strlcpy((char *)&data[3], id3.artist, 64); + iap_send_pkt(data, 4+len); break; case 0x24: - strncpy((char *)&data[3], id3.album, 64); - iap_send_pkt(data, 4+strlen(id3.album)); + len = strlcpy((char *)&data[3], id3.album, 64); + iap_send_pkt(data, 4+len); break; } break; diff --git a/apps/menu.c b/apps/menu.c index aff84c72e3..f6d0ef967d 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -321,7 +321,7 @@ void do_setting_from_menu(const struct menu_item_ex *temp, while (i < MAX_PATH-1) { int padlen = MIN(len, MAX_PATH-1-i); - strncpy(&padded_title[i], title, padlen); + strlcpy(&padded_title[i], title, padlen); i += padlen; if (ipath, trackname, sizeof(id3->path)); + strlcpy(id3->path, trackname, sizeof(id3->path)); return true; } diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c index 38761e3dae..5947098f12 100644 --- a/apps/metadata/metadata_common.c +++ b/apps/metadata/metadata_common.c @@ -320,10 +320,9 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3, if (len > 0) { - strncpy(buf, value, len); - buf[len] = 0; - *p = buf; len++; + strlcpy(buf, value, len); + *p = buf; } else { diff --git a/apps/metadata/mp3.c b/apps/metadata/mp3.c index d3adc5d6ae..f02700055a 100644 --- a/apps/metadata/mp3.c +++ b/apps/metadata/mp3.c @@ -309,8 +309,7 @@ static int parseuser( struct mp3entry* entry, char* tag, int bufferpos ) value_len = bufferpos - (tag - entry->id3v2buf); if (!strcasecmp(tag, "ALBUM ARTIST")) { - strncpy(tag, value, value_len); - tag[value_len - 1] = 0; + strlcpy(tag, value, value_len); entry->albumartist = tag; #if CONFIG_CODEC == SWCODEC } else { @@ -1114,7 +1113,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry, const char *filename) memset(entry, 0, sizeof(struct mp3entry)); #endif - strncpy(entry->path, filename, sizeof(entry->path)); + strlcpy(entry->path, filename, sizeof(entry->path)); entry->title = NULL; entry->filesize = filesize(fd); diff --git a/apps/misc.c b/apps/misc.c index cf356a37f9..e6f8ca840b 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -814,15 +814,13 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename) { len = dot - filename; len = MIN(len, buffer_size); - strncpy(buffer, filename, len); } else { len = buffer_size; - strncpy(buffer, filename, buffer_size); } - buffer[len] = 0; + strlcpy(buffer, filename, len + 1); return buffer; } diff --git a/apps/mpeg.c b/apps/mpeg.c index 8518ab68e6..0e1217b5c8 100644 --- a/apps/mpeg.c +++ b/apps/mpeg.c @@ -2203,8 +2203,7 @@ void audio_record(const char *filename) { mpeg_errno = 0; - strncpy(recording_filename, filename, MAX_PATH - 1); - recording_filename[MAX_PATH - 1] = 0; + strlcpy(recording_filename, filename, MAX_PATH); queue_post(&mpeg_queue, MPEG_RECORD, 0); } @@ -2509,8 +2508,7 @@ void audio_new_file(const char *filename) { mpeg_errno = 0; - strncpy(recording_filename, filename, MAX_PATH - 1); - recording_filename[MAX_PATH - 1] = 0; + strlcpy(recording_filename, filename, MAX_PATH); queue_post(&mpeg_queue, MPEG_NEW_FILE, 0); } diff --git a/apps/onplay.c b/apps/onplay.c index 621bf82607..9f38b32fb4 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -532,7 +532,7 @@ static bool delete_handler(bool is_dir) { char pathname[MAX_PATH]; /* space to go deep */ cpu_boost(true); - strncpy(pathname, file_to_delete, sizeof pathname); + strlcpy(pathname, file_to_delete, sizeof(pathname)); res = remove_dir(pathname, sizeof(pathname)); cpu_boost(false); } @@ -578,7 +578,7 @@ static bool rename_file(void) char newname[MAX_PATH]; char* ptr = strrchr(selected_file, '/') + 1; int pathlen = (ptr - selected_file); - strncpy(newname, selected_file, sizeof newname); + strlcpy(newname, selected_file, sizeof(newname)); if (!kbd_input(newname + pathlen, (sizeof newname)-pathlen)) { if (!strlen(newname + pathlen) || (rename(selected_file, newname) < 0)) { @@ -638,7 +638,7 @@ static bool properties(void) static bool clipboard_clip(bool copy) { clipboard_selection[0] = 0; - strncpy(clipboard_selection, selected_file, sizeof(clipboard_selection)); + strlcpy(clipboard_selection, selected_file, sizeof(clipboard_selection)); clipboard_selection_attr = selected_file_attr; clipboard_is_copy = copy; @@ -895,15 +895,15 @@ static bool clipboard_paste(void) } else { - strncpy(srcpath, clipboard_selection, sizeof(srcpath)); - strncpy(targetpath, target, sizeof(targetpath)); + strlcpy(srcpath, clipboard_selection, sizeof(srcpath)); + strlcpy(targetpath, target, sizeof(targetpath)); success = clipboard_pastedirectory(srcpath, sizeof(srcpath), target, sizeof(targetpath), clipboard_is_copy); if (success && !clipboard_is_copy) { - strncpy(srcpath, clipboard_selection, sizeof(srcpath)); + strlcpy(srcpath, clipboard_selection, sizeof(srcpath)); remove_dir(srcpath, sizeof(srcpath)); } } @@ -1026,7 +1026,7 @@ MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP), #ifdef HAVE_RECORDING static bool set_recdir(void) { - strncpy(global_settings.rec_directory, + strlcpy(global_settings.rec_directory, selected_file, MAX_FILENAME+1); settings_save(); return false; diff --git a/apps/playback.c b/apps/playback.c index 4af457cd44..cee89d3bbb 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -617,7 +617,7 @@ struct mp3entry* audio_current_track(void) return write_id3; #endif - strncpy(write_id3->path, filename, sizeof(write_id3->path)-1); + strlcpy(write_id3->path, filename, sizeof(write_id3->path)); write_id3->title = strrchr(write_id3->path, '/'); if (!write_id3->title) write_id3->title = &write_id3->path[0]; diff --git a/apps/playlist.c b/apps/playlist.c index 1d291cf6d0..b70fdc8a1f 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -1349,8 +1349,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, if (playlist->in_ram && !control_file && max < 0) { - strncpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf)); - tmp_buf[MAX_PATH] = '\0'; + strlcpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf)); max = strlen(tmp_buf) + 1; } else if (max < 0) @@ -1402,8 +1401,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, } } - strncpy(dir_buf, playlist->filename, playlist->dirlen-1); - dir_buf[playlist->dirlen-1] = 0; + strlcpy(dir_buf, playlist->filename, playlist->dirlen); return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf)); } @@ -1471,8 +1469,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) else { /* start with current directory */ - strncpy(dir, playlist->filename, playlist->dirlen-1); - dir[playlist->dirlen-1] = '\0'; + strlcpy(dir, playlist->filename, playlist->dirlen); } /* use the tree browser dircache to load files */ @@ -1671,13 +1668,13 @@ static int format_track_path(char *dest, char *src, int buf_length, int max, if('/' == src[0]) { - strncpy(dest, src, buf_length); + strlcpy(dest, src, buf_length); } else { /* handle dos style drive letter */ if (':' == src[1]) - strncpy(dest, &src[2], buf_length); + strlcpy(dest, &src[2], buf_length); else if (!strncmp(src, "../", 3)) { /* handle relative paths */ @@ -1904,7 +1901,7 @@ void playlist_init(void) struct playlist_info* playlist = ¤t_playlist; playlist->current = true; - strncpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, + strlcpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, sizeof(playlist->control_filename)); playlist->fd = -1; playlist->control_fd = -1; @@ -2721,7 +2718,7 @@ int playlist_set_current(struct playlist_info* playlist) empty_playlist(¤t_playlist, false); - strncpy(current_playlist.filename, playlist->filename, + strlcpy(current_playlist.filename, playlist->filename, sizeof(current_playlist.filename)); current_playlist.utf8 = playlist->utf8; @@ -3240,7 +3237,7 @@ char *playlist_name(const struct playlist_info* playlist, char *buf, if (!playlist) playlist = ¤t_playlist; - strncpy(buf, playlist->filename+playlist->dirlen, buf_size); + strlcpy(buf, playlist->filename+playlist->dirlen, buf_size); if (!buf[0]) return NULL; @@ -3260,7 +3257,7 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf, if (!playlist) playlist = ¤t_playlist; - strncpy(buf, playlist->filename, buf_size); + strlcpy(buf, playlist->filename, buf_size); if (!buf[0]) return NULL; diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c index 84a62e3474..a4950e22e8 100644 --- a/apps/playlist_catalog.c +++ b/apps/playlist_catalog.c @@ -78,7 +78,7 @@ static int initialize_catalog(void) /* fall back to default directory if no or invalid config */ if (default_dir) - strncpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR, + strlcpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR, sizeof(playlist_dir)); playlist_dir_length = strlen(playlist_dir); @@ -189,7 +189,7 @@ static char* playlist_callback_name(int selected_item, void* data, { char** playlists = (char**) data; - strncpy(buffer, playlists[selected_item], buffer_len); + strlcpy(buffer, playlists[selected_item], buffer_len); if (buffer[0] != '.' && !(global_settings.show_filename_ext == 1 || (global_settings.show_filename_ext == 3 @@ -478,7 +478,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr, if (add_to_playlist(playlist, new_playlist, sel, sel_attr) == 0) { - strncpy(most_recent_playlist, playlist+playlist_dir_length+1, + strlcpy(most_recent_playlist, playlist+playlist_dir_length+1, sizeof(most_recent_playlist)); return true; } diff --git a/apps/plugin.c b/apps/plugin.c index f08a98753a..b8c4efdc41 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -381,7 +381,7 @@ static const struct plugin_api rockbox_api = { snprintf, vsnprintf, strcpy, - strncpy, + strlcpy, strlen, strrchr, strcmp, diff --git a/apps/plugin.h b/apps/plugin.h index bb74d73334..35b2105c17 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -38,6 +38,7 @@ #include #include +char* strncpy(char *, const char *, size_t); void* plugin_get_buffer(size_t *buffer_size); #ifndef __PCTOOL__ @@ -128,12 +129,12 @@ void* plugin_get_buffer(size_t *buffer_size); #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 160 +#define PLUGIN_API_VERSION 161 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 160 +#define PLUGIN_MIN_API_VERSION 161 /* plugin return codes */ enum plugin_status { @@ -505,7 +506,7 @@ struct plugin_api { ATTRIBUTE_PRINTF(3, 4); int (*vsnprintf)(char *buf, int size, const char *fmt, va_list ap); char* (*strcpy)(char *dst, const char *src); - char* (*strncpy)(char *dst, const char *src, size_t length); + size_t (*strlcpy)(char *dst, const char *src, size_t length); size_t (*strlen)(const char *str); char * (*strrchr)(const char *s, int c); int (*strcmp)(const char *, const char *); diff --git a/apps/plugins/chessbox/chessbox_pgn.c b/apps/plugins/chessbox/chessbox_pgn.c index a8be179fac..cd163a5e1c 100644 --- a/apps/plugins/chessbox/chessbox_pgn.c +++ b/apps/plugins/chessbox/chessbox_pgn.c @@ -543,7 +543,7 @@ char * get_game_text(int selected_item, void *data, rb->snprintf(text_buffer, 50,"%s vs. %s (%s)", temp_node->white_player, temp_node->black_player, temp_node->game_date); - rb->strncpy(buffer, text_buffer, buffer_len); + rb->strlcpy(buffer, text_buffer, buffer_len); return buffer; } diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c index 0c1ddf33a9..fcc55faef1 100644 --- a/apps/plugins/dict.c +++ b/apps/plugins/dict.c @@ -283,8 +283,7 @@ enum plugin_status plugin_start(const void* parameter) while (1) { /* copy one lcd line */ - rb->strncpy(output, ptr, display_columns); - output[display_columns] = '\0'; + rb->strlcpy(output, ptr, display_columns + 1); /* typecast to kill a warning... */ if((int)rb->strlen(ptr) < display_columns) diff --git a/apps/plugins/doom/rockmacros.h b/apps/plugins/doom/rockmacros.h index 73cd902277..1ead411b85 100644 --- a/apps/plugins/doom/rockmacros.h +++ b/apps/plugins/doom/rockmacros.h @@ -59,7 +59,6 @@ int my_close(int id); #define memcmp(a,b,c) rb->memcmp((a),(b),(c)) #define memchr(a,b,c) rb->memchr((a),(b),(c)) #define strcpy(a,b) rb->strcpy((a),(b)) -#define strncpy(a,b,c) rb->strncpy((a),(b),(c)) #define strlen(a) rb->strlen((a)) #define strcmp(a,b) rb->strcmp((a),(b)) #define strncmp(a,b,c) rb->strncmp((a),(b),(c)) diff --git a/apps/plugins/goban/sgf_output.c b/apps/plugins/goban/sgf_output.c index c1ac052be7..6a52789f7a 100644 --- a/apps/plugins/goban/sgf_output.c +++ b/apps/plugins/goban/sgf_output.c @@ -130,7 +130,7 @@ output_header_props (void) { char buffer[128]; - rb->strncpy (buffer, "GM[1]FF[4]CA[UTF-8]AP[Rockbox Goban:1.0]ST[2]\n\n", + rb->strlcpy (buffer, "GM[1]FF[4]CA[UTF-8]AP[Rockbox Goban:1.0]ST[2]\n\n", sizeof (buffer)); write_file (sgf_fd, buffer, rb->strlen (buffer)); diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c index c7d5696d19..fa7cb81e02 100644 --- a/apps/plugins/invadrox.c +++ b/apps/plugins/invadrox.c @@ -1511,7 +1511,7 @@ void init_invadrox(void) if (highscore_load(HISCOREFILE, &hiscore, 1) < 0) { /* Init hiscore to 0 */ - rb->strncpy(hiscore.name, "Invader", sizeof(hiscore.name)); + rb->strlcpy(hiscore.name, "Invader", sizeof(hiscore.name)); hiscore.score = 0; hiscore.level = 1; } diff --git a/apps/plugins/keybox.c b/apps/plugins/keybox.c index 08d5131eff..73fd138f09 100644 --- a/apps/plugins/keybox.c +++ b/apps/plugins/keybox.c @@ -330,11 +330,11 @@ static void hash_pw(union hash *out) static void make_key(void) { int i; - char buf[sizeof(master_pw) + sizeof(salt) + 1]; + char buf[sizeof(master_pw) + sizeof(salt) + 1] = {0}; struct md5_s key_md5; size_t len = rb->strlen(master_pw); - rb->strncpy(buf, master_pw, sizeof(buf)); + rb->strlcpy(buf, master_pw, sizeof(buf)); rb->memcpy(&buf[len], &salt, sizeof(salt)); @@ -418,7 +418,7 @@ static int parse_buffer(void) break; } - rb->strncpy(entry->title, start, FIELD_LEN); + rb->strlcpy(entry->title, start, FIELD_LEN); start = end + 1; end = rb->strchr(start, '\0'); /* find eol */ @@ -428,7 +428,7 @@ static int parse_buffer(void) break; } - rb->strncpy(entry->name, start, FIELD_LEN); + rb->strlcpy(entry->name, start, FIELD_LEN); start = end + 1; end = rb->strchr(start, '\0'); /* find eol */ @@ -437,7 +437,7 @@ static int parse_buffer(void) { break; } - rb->strncpy(entry->password, start, FIELD_LEN); + rb->strlcpy(entry->password, start, FIELD_LEN); start = end + 1; entry->used = true; if (i + 1 < MAX_ENTRIES - 1) @@ -469,13 +469,13 @@ static void write_output(int fd) for (i = 0; i < pw_list.num_entries; i++) { len = rb->strlen(entry->title); - rb->strncpy(p, entry->title, len+1); + rb->strlcpy(p, entry->title, len+1); p += len+1; len = rb->strlen(entry->name); - rb->strncpy(p, entry->name, len+1); + rb->strlcpy(p, entry->name, len+1); p += len+1; len = rb->strlen(entry->password); - rb->strncpy(p, entry->password, len+1); + rb->strlcpy(p, entry->password, len+1); p += len+1; if (entry->next) entry = entry->next; @@ -517,7 +517,7 @@ static int enter_pw(char *pw_buf, size_t buflen, bool new_pw) } else { - rb->strncpy(pw_buf, buf[0], buflen); + rb->strlcpy(pw_buf, buf[0], buflen); hash_pw(&pwhash); return 0; } diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 02adb7089c..72538fc2a0 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -6,6 +6,7 @@ playback_control.c rgb_hsv.c buflib.c display_text.c +strncpy.c #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) grey_core.c grey_draw.c diff --git a/apps/plugins/lib/configfile.c b/apps/plugins/lib/configfile.c index 5e1e776f39..21b66a317b 100644 --- a/apps/plugins/lib/configfile.c +++ b/apps/plugins/lib/configfile.c @@ -139,7 +139,7 @@ int configfile_load(const char *filename, struct configdata *cfg, break; case TYPE_STRING: - rb->strncpy(cfg[i].string, val, cfg[i].max); + rb->strlcpy(cfg[i].string, val, cfg[i].max); break; } } diff --git a/apps/plugins/lib/highscore.c b/apps/plugins/lib/highscore.c index e8e1c883b0..15ebb05f4d 100644 --- a/apps/plugins/lib/highscore.c +++ b/apps/plugins/lib/highscore.c @@ -72,7 +72,7 @@ int highscore_load(char *filename, struct highscore *scores, int num_scores) scores[i].score = rb->atoi(score); scores[i].level = rb->atoi(level); - rb->strncpy(scores[i].name, name, sizeof(scores[i].name)-1); + rb->strlcpy(scores[i].name, name, sizeof(scores[i].name)); i++; } rb->close(fd); @@ -100,8 +100,7 @@ int highscore_update(int score, int level, const char *name, entry = scores + pos; entry->score = score; entry->level = level; - rb->strncpy(entry->name, name, sizeof(entry->name)); - entry->name[sizeof(entry->name)-1] = '\0'; + rb->strlcpy(entry->name, name, sizeof(entry->name)); return pos; } diff --git a/firmware/common/strncpy.c b/apps/plugins/lib/strncpy.c similarity index 100% rename from firmware/common/strncpy.c rename to apps/plugins/lib/strncpy.c diff --git a/apps/plugins/lib/wrappers.h b/apps/plugins/lib/wrappers.h index 5eb45d02c8..b6fbd51a39 100644 --- a/apps/plugins/lib/wrappers.h +++ b/apps/plugins/lib/wrappers.h @@ -51,7 +51,7 @@ #define strcpy rb->strcpy #define strip_extension rb->strip_extension #define strlen rb->strlen -#define strncpy rb->strncpy +#define strlcpy rb->strlcpy #define strrchr rb->strrchr #endif diff --git a/apps/plugins/lua/lobject.c b/apps/plugins/lua/lobject.c index 62ad8e9359..7f73114303 100644 --- a/apps/plugins/lua/lobject.c +++ b/apps/plugins/lua/lobject.c @@ -181,8 +181,7 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { void luaO_chunkid (char *out, const char *source, size_t bufflen) { if (*source == '=') { - strncpy(out, source+1, bufflen); /* remove first char */ - out[bufflen-1] = '\0'; /* ensures null termination */ + strlcpy(out, source+1, bufflen); /* remove first char */ } else { /* out = "source", or "...source" */ if (*source == '@') { diff --git a/apps/plugins/lua/lstrlib.c b/apps/plugins/lua/lstrlib.c index 3d6103692f..4d58280ba8 100644 --- a/apps/plugins/lua/lstrlib.c +++ b/apps/plugins/lua/lstrlib.c @@ -737,9 +737,7 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { if (isdigit(uchar(*p))) luaL_error(L, "invalid format (width or precision too long)"); *(form++) = '%'; - strncpy(form, strfrmt, p - strfrmt + 1); - form += p - strfrmt + 1; - *form = '\0'; + strlcpy(form, strfrmt, p - strfrmt + 1); return p; } diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h index 639f336b5b..02bd0e76d1 100644 --- a/apps/plugins/lua/rockconf.h +++ b/apps/plugins/lua/rockconf.h @@ -63,7 +63,7 @@ long pow(long x, long y); #define strchr rb->strchr #define strcmp rb->strcmp #define strcpy rb->strcpy -#define strncpy rb->strncpy +#define strlcpy rb->strlcpy #define strlen rb->strlen #endif /* _ROCKCONF_H_ */ diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c index 6849daf2f3..9da0d6925f 100644 --- a/apps/plugins/mp3_encoder.c +++ b/apps/plugins/mp3_encoder.c @@ -2399,9 +2399,8 @@ char mp3_name[80]; void get_mp3_filename(const char *wav_name) { - int slen = rb->strlen(wav_name); - rb->strncpy(mp3_name, wav_name, 79); - rb->strncpy(mp3_name + slen - 4, ".mp3", 5); + rb->strlcpy(mp3_name, wav_name, sizeof(mp3_name)); + rb->strlcpy(mp3_name + rb->strlen(mp3_name) - 4, ".mp3", 5); } #if CONFIG_KEYPAD == IRIVER_H100_PAD || CONFIG_KEYPAD == IRIVER_H300_PAD diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c index 7ec1157615..a9b66fc22f 100644 --- a/apps/plugins/mpegplayer/mpeg_settings.c +++ b/apps/plugins/mpegplayer/mpeg_settings.c @@ -344,7 +344,7 @@ static void backlight_brightness_formatter(char *buf, size_t length, int value, const char *input) { if (value < 0) - rb->strncpy(buf, BACKLIGHT_OPTION_DEFAULT, length); + rb->strlcpy(buf, BACKLIGHT_OPTION_DEFAULT, length); else rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 496e9c94df..34d1db5d5c 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c @@ -913,7 +913,7 @@ bool get_albumart_for_index_from_db(const int slide_index, char *buf, { if ( slide_index == -1 ) { - rb->strncpy( buf, EMPTY_SLIDE, buflen ); + rb->strlcpy( buf, EMPTY_SLIDE, buflen ); } if (!rb->tagcache_search(&tcs, tag_filename)) @@ -930,8 +930,7 @@ bool get_albumart_for_index_from_db(const int slide_index, char *buf, #ifdef HAVE_TC_RAMCACHE if (rb->tagcache_fill_tags(&id3, tcs.result)) { - rb->strncpy(id3.path, tcs.result, sizeof(id3.path)); - id3.path[sizeof(id3.path) - 1] = 0; + rb->strlcpy(id3.path, tcs.result, sizeof(id3.path)); } else #endif diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c index 18beec2da6..b57150b817 100644 --- a/apps/plugins/properties.c +++ b/apps/plugins/properties.c @@ -70,8 +70,7 @@ static bool file_properties(char* selected_file) char* ptr = rb->strrchr(selected_file, '/') + 1; int dirlen = (ptr - selected_file); - rb->strncpy(tstr, selected_file, dirlen); - tstr[dirlen] = 0; + rb->strlcpy(tstr, selected_file, dirlen + 1); dir = rb->opendir(tstr); if (dir) @@ -212,7 +211,7 @@ static bool dir_properties(char* selected_file) { DPS dps; char tstr[64]; - rb->strncpy(dps.dirname, selected_file, MAX_PATH); + rb->strlcpy(dps.dirname, selected_file, MAX_PATH); dps.len = MAX_PATH; dps.dc = 0; dps.fc = 0; @@ -220,7 +219,7 @@ static bool dir_properties(char* selected_file) if(false == _dir_properties(&dps)) return false; - rb->strncpy(str_dirname, selected_file, MAX_PATH); + rb->strlcpy(str_dirname, selected_file, MAX_PATH); rb->snprintf(str_dircount, sizeof str_dircount, "Subdirs: %d", dps.dc); rb->snprintf(str_filecount, sizeof str_filecount, "Files: %d", dps.fc); rb->snprintf(str_size, sizeof str_size, "Size: %s", @@ -236,35 +235,35 @@ char * get_props(int selected_item, void* data, char *buffer, size_t buffer_len) switch(selected_item) { case 0: - rb->strncpy(buffer, str_dirname, buffer_len); + rb->strlcpy(buffer, str_dirname, buffer_len); break; case 1: - rb->strncpy(buffer, its_a_dir ? str_dircount : str_filename, + rb->strlcpy(buffer, its_a_dir ? str_dircount : str_filename, buffer_len); break; case 2: - rb->strncpy(buffer, its_a_dir ? str_filecount : str_size, buffer_len); + rb->strlcpy(buffer, its_a_dir ? str_filecount : str_size, buffer_len); break; case 3: - rb->strncpy(buffer, its_a_dir ? str_size : str_date, buffer_len); + rb->strlcpy(buffer, its_a_dir ? str_size : str_date, buffer_len); break; case 4: - rb->strncpy(buffer, its_a_dir ? "" : str_time, buffer_len); + rb->strlcpy(buffer, its_a_dir ? "" : str_time, buffer_len); break; case 5: - rb->strncpy(buffer, its_a_dir ? "" : str_artist, buffer_len); + rb->strlcpy(buffer, its_a_dir ? "" : str_artist, buffer_len); break; case 6: - rb->strncpy(buffer, its_a_dir ? "" : str_title, buffer_len); + rb->strlcpy(buffer, its_a_dir ? "" : str_title, buffer_len); break; case 7: - rb->strncpy(buffer, its_a_dir ? "" : str_album, buffer_len); + rb->strlcpy(buffer, its_a_dir ? "" : str_album, buffer_len); break; case 8: - rb->strncpy(buffer, its_a_dir ? "" : str_duration, buffer_len); + rb->strlcpy(buffer, its_a_dir ? "" : str_duration, buffer_len); break; default: - rb->strncpy(buffer, "ERROR", buffer_len); + rb->strlcpy(buffer, "ERROR", buffer_len); break; } return buffer; @@ -284,8 +283,7 @@ enum plugin_status plugin_start(const void* parameter) struct dirent* entry; char* ptr = rb->strrchr(file, '/') + 1; int dirlen = (ptr - file); - rb->strncpy(str_dirname, file, dirlen); - str_dirname[dirlen] = 0; + rb->strlcpy(str_dirname, file, dirlen + 1); dir = rb->opendir(str_dirname); if (dir) diff --git a/apps/plugins/random_folder_advance_config.c b/apps/plugins/random_folder_advance_config.c index 28546a340c..c9ffaed319 100644 --- a/apps/plugins/random_folder_advance_config.c +++ b/apps/plugins/random_folder_advance_config.c @@ -86,7 +86,7 @@ void traversedir(char* location, char* name) /* check if path is removed directory, if so dont enter it */ rb->snprintf(path, MAX_PATH, "%s/%s", fullpath, entry->d_name); while(path[0] == '/') - rb->strncpy(path, path + 1, rb->strlen(path)); + rb->strlcpy(path, path + 1, sizeof(path)); for(i = 0; i < num_replaced_dirs; i++) { if(!rb->strcmp(path, removed_dirs[i])) @@ -141,8 +141,8 @@ bool custom_dir(void) (num_replaced_dirs < MAX_REMOVED_DIRS)) { num_replaced_dirs ++; - rb->strncpy(removed_dirs[num_replaced_dirs - 1], line + 2, - rb->strlen(line)); + rb->strlcpy(removed_dirs[num_replaced_dirs - 1], line + 2, + sizeof(line)); } } rb->close(fd2); @@ -157,7 +157,7 @@ bool custom_dir(void) { /* remove preceeding '/'s from the line */ while(line[0] == '/') - rb->strncpy(line, line + 1, rb->strlen(line)); + rb->strlcpy(line, line + 1, sizeof(line)); rb->snprintf(formatted_line, MAX_PATH, "/%s", line); @@ -237,7 +237,7 @@ void generate(void) char *list_get_name_cb(int selected_item, void* data, char* buf, size_t buf_len) { (void)data; - rb->strncpy(buf, list->folder[selected_item], buf_len); + rb->strlcpy(buf, list->folder[selected_item], buf_len); return buf; } diff --git a/apps/plugins/rockboy/menu.c b/apps/plugins/rockboy/menu.c index 9821ce9ba2..76de224294 100644 --- a/apps/plugins/rockboy/menu.c +++ b/apps/plugins/rockboy/menu.c @@ -162,11 +162,10 @@ static void munge_name(char *buf, const size_t bufsiz) { * checksum or something like that? */ static void build_slot_path(char *buf, size_t bufsiz, size_t slot_id) { - char name_buf[40]; + char name_buf[17]; /* munge state file name */ - strncpy(name_buf, rom.name, 40); - name_buf[16] = '\0'; + strlcpy(name_buf, rom.name, sizeof(name_buf)); munge_name(name_buf, strlen(name_buf)); /* glom the whole mess together */ @@ -211,7 +210,7 @@ static bool do_file(char *path, char *desc, bool is_load) { /* build description buffer */ memset(desc_buf, 0, 20); if (desc) - strncpy(desc_buf, desc, 20); + strlcpy(desc_buf, desc, 20); /* save state */ write(fd, desc_buf, 20); @@ -241,8 +240,7 @@ static bool do_slot(size_t slot_id, bool is_load) { if (!is_load) if (rb->kbd_input(desc_buf, 20) || !strlen(desc_buf)) { - memset(desc_buf, 0, 20); - strncpy(desc_buf, "Untitled", 20); + strlcpy(desc_buf, "Untitled", 20); } /* load/save file */ diff --git a/apps/plugins/rockboy/rockmacros.h b/apps/plugins/rockboy/rockmacros.h index 414b889003..0fd13f6ef9 100644 --- a/apps/plugins/rockboy/rockmacros.h +++ b/apps/plugins/rockboy/rockmacros.h @@ -67,7 +67,7 @@ void dynamic_recompile (struct dynarec_block *newblock); #define strcat(a,b) rb->strcat((a),(b)) #define memset(a,b,c) rb->memset((a),(b),(c)) #define strcpy(a,b) rb->strcpy((a),(b)) -#define strncpy(a,b,c) rb->strncpy((a),(b),(c)) +#define strlcpy(a,b,c) rb->strlcpy((a),(b),(c)) #define strlen(a) rb->strlen((a)) #define strcmp(a,b) rb->strcmp((a),(b)) #define strchr(a,b) rb->strchr((a),(b)) diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 20bebdd11f..5de6c14a6b 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c @@ -686,7 +686,7 @@ static bool browse( char *dst, int dst_size, const char *start ) if( selected < 0 || selected >= item_count ) break; struct entry* e = &dc[indexes[selected]]; - rb->strncpy( bbuf_s, e->name, sizeof( bbuf_s ) ); + rb->strlcpy( bbuf_s, e->name, sizeof( bbuf_s ) ); if( !( e->attr & ATTR_DIRECTORY ) ) { *tree = backup; diff --git a/apps/plugins/shortcuts/shortcuts_common.c b/apps/plugins/shortcuts/shortcuts_common.c index a06abd3f7f..1a781b23eb 100644 --- a/apps/plugins/shortcuts/shortcuts_common.c +++ b/apps/plugins/shortcuts/shortcuts_common.c @@ -213,8 +213,7 @@ bool parse_entry_content(char *line, sc_entry_t *entry, int last_segm) DEBUGF("Bad entry: pathlen=%d, displen=%d\n", path_len, disp_len); return false; } - rb->strncpy(entry->path, path, path_len); - entry->path[path_len] = '\0'; + rb->strlcpy(entry->path, path, path_len + 1); rb->strcpy(entry->disp, disp); /* Safe since we've checked the length */ entry->explicit_disp = expl; return true; @@ -295,15 +294,14 @@ bool parse_name_value(char *line, char *name, int namesize, /* Too long name */ return false; } - rb->strncpy(name, line, name_len); - name[name_len] = '\0'; + rb->strlcpy(name, line, name_len + 1); val_len = rb->strlen(line) - name_len - NAME_VALUE_SEPARATOR_LEN; if (val_len >= valuesize) { /* Too long value */ return false; } - rb->strncpy(value, sep+NAME_VALUE_SEPARATOR_LEN, val_len+1); + rb->strlcpy(value, sep+NAME_VALUE_SEPARATOR_LEN, val_len+1); return true; } diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c index 8672249bdc..bfd400b408 100644 --- a/apps/plugins/sokoban.c +++ b/apps/plugins/sokoban.c @@ -689,7 +689,8 @@ static bool redo(void) static void init_boards(void) { - rb->strncpy(buffered_boards.filename, SOKOBAN_LEVELS_FILE, MAX_PATH); + rb->strlcpy(buffered_boards.filename, SOKOBAN_LEVELS_FILE, + sizeof(buffered_boards.filename)); current_info.level.index = 0; current_info.player.row = 0; @@ -1026,8 +1027,8 @@ static bool save(char *filename, bool solution) /* Create dir if it doesn't exist */ if ((loc = rb->strrchr(filename, '/')) != NULL) { - rb->strncpy(dirname, filename, loc - filename); - dirname[loc - filename] = '\0'; + rb->strlcpy(dirname, filename, loc - filename + 1); + if(!(dir = rb->opendir(dirname))) rb->mkdir(dirname); else @@ -1082,7 +1083,9 @@ static bool load(char *filename, bool silent) if (rb->strncmp(buf, "Sokoban", 7) != 0) { rb->close(fd); - rb->strncpy(buffered_boards.filename, filename, MAX_PATH); + rb->strlcpy(buffered_boards.filename, filename, + sizeof(buffered_boards.filename)); + if (!read_levels(true)) return false; diff --git a/apps/plugins/splitedit.c b/apps/plugins/splitedit.c index 9f62b7a346..a169a61a47 100644 --- a/apps/plugins/splitedit.c +++ b/apps/plugins/splitedit.c @@ -780,11 +780,11 @@ static void save_editor(struct mp3entry *mp3, int splittime) bool part2_save = true; /* file name for left part */ - rb->strncpy(part1_name, mp3->path, MAX_PATH); + rb->strlcpy(part1_name, mp3->path, MAX_PATH); generateFileName(part1_name, 1); /* file name for right part */ - rb->strncpy(part2_name, mp3->path, MAX_PATH); + rb->strlcpy(part2_name, mp3->path, MAX_PATH); generateFileName(part2_name, 2); while (!exit_request) diff --git a/apps/plugins/sudoku/sudoku.c b/apps/plugins/sudoku/sudoku.c index f8a438592d..77f6ca7899 100644 --- a/apps/plugins/sudoku/sudoku.c +++ b/apps/plugins/sudoku/sudoku.c @@ -603,7 +603,7 @@ void default_state(struct sudoku_state_t* state) { int r,c; - rb->strncpy(state->filename,GAME_FILE,MAX_PATH); + rb->strlcpy(state->filename,GAME_FILE,MAX_PATH); for (r=0;r<9;r++) { for (c=0;c<9;c++) { state->startboard[r][c]=default_game[r][c]; @@ -626,7 +626,7 @@ void clear_state(struct sudoku_state_t* state) { int r,c; - rb->strncpy(state->filename,GAME_FILE,MAX_PATH); + rb->strlcpy(state->filename,GAME_FILE,MAX_PATH); for (r=0;r<9;r++) { for (c=0;c<9;c++) { state->startboard[r][c]='0'; @@ -719,7 +719,7 @@ bool load_sudoku(struct sudoku_state_t* state, char* filename) return(false); } - rb->strncpy(state->filename,filename,MAX_PATH); + rb->strlcpy(state->filename,filename,MAX_PATH); n=rb->read(fd,buf,300); if (n <= 0) { return(false); @@ -1111,7 +1111,7 @@ bool sudoku_generate(struct sudoku_state_t* state) rb->snprintf(str,sizeof(str),"Difficulty: %s",difficulty); display_board(state); rb->splash(HZ*3, str); - rb->strncpy(state->filename,GAME_FILE,MAX_PATH); + rb->strlcpy(state->filename,GAME_FILE,MAX_PATH); } else { display_board(&new_state); rb->splash(HZ*2, "Aborted"); diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index a708ed7b07..c51fc4006f 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -451,7 +451,6 @@ static void init_ci(void) /* strings and memory */ ci.strcpy = rb->strcpy; - ci.strncpy = rb->strncpy; ci.strlen = rb->strlen; ci.strcmp = rb->strcmp; ci.strcat = rb->strcat; @@ -716,7 +715,7 @@ enum plugin_status plugin_start(const void* parameter) /* Test all files in the same directory as the file selected by the user */ - rb->strncpy(dirpath,parameter,sizeof(dirpath)); + rb->strlcpy(dirpath,parameter,sizeof(dirpath)); ch = rb->strrchr(dirpath,'/'); ch[1]=0; diff --git a/apps/plugins/text_editor.c b/apps/plugins/text_editor.c index 703b330d6c..617aeae8b1 100644 --- a/apps/plugins/text_editor.c +++ b/apps/plugins/text_editor.c @@ -133,7 +133,7 @@ char *list_get_name_cb(int selected_item, void* data, rb->snprintf(buf , buf_len, "%s ...", b); b[buf_len-10] = t; } - else rb->strncpy(buf, b, buf_len); + else rb->strlcpy(buf, b, buf_len); return buf; } diff --git a/apps/plugins/zxbox/snapshot.c b/apps/plugins/zxbox/snapshot.c index d078ec78b1..9a68540a04 100644 --- a/apps/plugins/zxbox/snapshot.c +++ b/apps/plugins/zxbox/snapshot.c @@ -603,8 +603,7 @@ void save_snapshot_file(char *name) { int type; - rb->strncpy(filenamebuf, name, MAXFILENAME-10); - filenamebuf[MAXFILENAME-10] = '\0'; + rb->strlcpy(filenamebuf, name, MAXFILENAME-10 + 1); type = SN_Z80; if(check_ext(filenamebuf, "z80")) type = SN_Z80; @@ -642,8 +641,7 @@ void load_snapshot_file_type(char *name, int type) int snsh; SNFILE snfil; - rb->strncpy(filenamebuf, name, MAXFILENAME-10); - filenamebuf[MAXFILENAME-10] = '\0'; + rb->strlcpy(filenamebuf, name, MAXFILENAME-10 + 1); spcf_find_file_type(filenamebuf, &filetype, &type); if(type < 0) type = SN_Z80; diff --git a/apps/plugins/zxbox/spconf.c b/apps/plugins/zxbox/spconf.c index 5a14959adc..728f78638c 100644 --- a/apps/plugins/zxbox/spconf.c +++ b/apps/plugins/zxbox/spconf.c @@ -111,8 +111,7 @@ void spcf_read_command_line(const void* parameter) file_type = extensions[ix].type; file_subtype = extensions[ix].subtype; - rb->strncpy(filenamebuf, parameter, MAXFILENAME - 10); - filenamebuf[MAXFILENAME-10] = '\0'; + rb->strlcpy(filenamebuf, parameter, MAXFILENAME - 10 + 1); if(file_type < 0) file_subtype = -1; if(!spcf_find_file_type(filenamebuf, &file_type, &file_subtype)) return; diff --git a/apps/plugins/zxbox/sptape.c b/apps/plugins/zxbox/sptape.c index f0e04de2fb..21f962ea28 100644 --- a/apps/plugins/zxbox/sptape.c +++ b/apps/plugins/zxbox/sptape.c @@ -594,8 +594,7 @@ void start_play_file_type(char *name, int seg, int type) { int filetype = FT_TAPEFILE; - rb->strncpy(tapename, name, MAXFILENAME-10); - tapename[MAXFILENAME-10] = '\0'; + rb->strlcpy(tapename, name, MAXFILENAME-10 + 1); currseg = seg; tapetype = type; diff --git a/apps/plugins/zxbox/tapefile.c b/apps/plugins/zxbox/tapefile.c index 19f6aba980..0e262aa0f7 100644 --- a/apps/plugins/zxbox/tapefile.c +++ b/apps/plugins/zxbox/tapefile.c @@ -510,8 +510,7 @@ static int interpret_tzx_header(byte *hb, struct seginfo *csp) int blen; rb->snprintf(seg_desc,DESC_LEN, "Begin Group: "); blen = (int) rb->strlen(seg_desc); - rb->strncpy(seg_desc+blen, (char *) rbuf, (unsigned) csp->len); - seg_desc[csp->len + blen] = '\0'; + rb->strlcpy(seg_desc+blen, (char *) rbuf, (unsigned) csp->len + 1); } break; @@ -618,8 +617,7 @@ static int interpret_tzx_header(byte *hb, struct seginfo *csp) return 0; } csp->ptr += csp->len; - rb->strncpy(seg_desc, (char *) rbuf, (unsigned) csp->len); - seg_desc[csp->len] = '\0'; + rb->strlcpy(seg_desc, (char *) rbuf, (unsigned) csp->len + 1); break; case 0x32: diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c index 6bd2adade3..a378c332b3 100644 --- a/apps/recorder/albumart.c +++ b/apps/recorder/albumart.c @@ -66,8 +66,7 @@ static char* strip_filename(char* buf, int buf_size, const char* fullpath) } len = MIN(sep - fullpath + 1, buf_size - 1); - strncpy(buf, fullpath, len); - buf[len] = 0; + strlcpy(buf, fullpath, len + 1); return (sep + 1); } @@ -266,7 +265,7 @@ bool search_albumart_files(const struct mp3entry *id3, const char *size_string, if (!found) return false; - strncpy(buf, path, buflen); + strlcpy(buf, path, buflen); logf("Album art found: %s", path); return true; } diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index 8657aee1ba..d1dc03113d 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c @@ -529,7 +529,7 @@ static bool pcmrec_fnq_is_full(void) /* queue another filename - will overwrite oldest one if full */ static bool pcmrec_fnq_add_filename(const char *filename) { - strncpy(fn_queue + fnq_wr_pos, filename, MAX_PATH); + strlcpy(fn_queue + fnq_wr_pos, filename, MAX_PATH); fnq_wr_pos = FNQ_NEXT(fnq_wr_pos); if (fnq_rd_pos != fnq_wr_pos) @@ -550,7 +550,7 @@ static bool pcmrec_fnq_replace_tail(const char *filename) pos = FNQ_PREV(fnq_wr_pos); - strncpy(fn_queue + pos, filename, MAX_PATH); + strlcpy(fn_queue + pos, filename, MAX_PATH); return true; } /* pcmrec_fnq_replace_tail */ @@ -562,7 +562,7 @@ static bool pcmrec_fnq_get_filename(char *filename) return false; if (filename) - strncpy(filename, fn_queue + fnq_rd_pos, MAX_PATH); + strlcpy(filename, fn_queue + fnq_rd_pos, MAX_PATH); fnq_rd_pos = FNQ_NEXT(fnq_rd_pos); return true; @@ -976,7 +976,7 @@ static void pcmrec_new_stream(const char *filename, /* next file name */ bool did_flush = false; /* did a flush occurr? */ if (filename) - strncpy(path, filename, MAX_PATH); + strlcpy(path, filename, MAX_PATH); queue_reply(&pcmrec_queue, 0); /* We have all we need */ data.pre_chunk = NULL; diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 68c45c4f01..c5729ba8b2 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -1138,7 +1138,7 @@ void radio_load_presets(char *filename) } /* Temporary preset, loaded until player shuts down. */ else if(filename[0] == '/') - strncpy(filepreset, filename, sizeof(filepreset)); + strlcpy(filepreset, filename, sizeof(filepreset)); /* Preset from default directory. */ else snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", @@ -1159,8 +1159,7 @@ void radio_load_presets(char *filename) { struct fmstation * const fms = &presets[num_presets]; fms->frequency = f; - strncpy(fms->name, name, MAX_FMPRESET_LEN); - fms->name[MAX_FMPRESET_LEN] = '\0'; + strlcpy(fms->name, name, MAX_FMPRESET_LEN+1); num_presets++; } } diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index d7ab9c795c..0a890d03da 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c @@ -964,7 +964,7 @@ static char * reclist_get_name(int selected_item, void * data, } else { - strncpy(buffer, str(LANG_RECORDING_FILENAME), buffer_len); + strlcpy(buffer, str(LANG_RECORDING_FILENAME), buffer_len); } break; } diff --git a/apps/replaygain.c b/apps/replaygain.c index b398afc294..bcdbffec5c 100644 --- a/apps/replaygain.c +++ b/apps/replaygain.c @@ -218,8 +218,7 @@ long parse_replaygain(const char* key, const char* value, /* A few characters just isn't interesting... */ if (len > 1) { - strncpy(buffer, value, len); - buffer[len] = 0; + strlcpy(buffer, value, len + 1); *p = buffer; return len + 1; } diff --git a/apps/root_menu.c b/apps/root_menu.c index 39d3fbe7ab..15bc524cce 100644 --- a/apps/root_menu.c +++ b/apps/root_menu.c @@ -77,7 +77,7 @@ static char current_track_path[MAX_PATH]; static void rootmenu_track_changed_callback(void* param) { struct mp3entry *id3 = (struct mp3entry *)param; - strncpy(current_track_path, id3->path, MAX_PATH); + strlcpy(current_track_path, id3->path, MAX_PATH); } static int browser(void* param) { @@ -202,7 +202,7 @@ static int browser(void* param) #endif case GO_TO_BROWSEPLUGINS: filter = SHOW_PLUGINS; - strncpy(folder, PLUGIN_DIR, MAX_PATH); + strlcpy(folder, PLUGIN_DIR, MAX_PATH); break; } ret_val = rockbox_browse(folder, filter); diff --git a/apps/settings.c b/apps/settings.c index e2f40a1f44..29360f14d3 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -246,8 +246,7 @@ static bool cfg_string_to_int(int setting_id, int* out, const char* str) } else return false; } - strncpy(temp, start, end-start); - temp[end-start] = '\0'; + strlcpy(temp, start, end-start+1); if (!strcmp(str, temp)) { *out = count; @@ -331,20 +330,18 @@ bool settings_load_config(const char* file, bool apply) settings[i].filename_setting->prefix, len)) { - strncpy(storage,&value[len],MAX_PATH); + strlcpy(storage, &value[len], MAX_PATH); } - else strncpy(storage,value,MAX_PATH); + else strlcpy(storage, value, MAX_PATH); } - else strncpy(storage,value,MAX_PATH); + else strlcpy(storage, value, MAX_PATH); if (settings[i].filename_setting->suffix) { char *s = strcasestr(storage,settings[i].filename_setting->suffix); if (s) *s = '\0'; } - strncpy((char*)settings[i].setting,storage, + strlcpy((char*)settings[i].setting, storage, settings[i].filename_setting->max_len); - ((char*)settings[i].setting) - [settings[i].filename_setting->max_len-1] = '\0'; break; } } @@ -379,12 +376,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len) if (value[count] == val) { if (end == NULL) - strncpy(buf, start, buf_len); + strlcpy(buf, start, buf_len); else { int len = (buf_len > (end-start))? end-start: buf_len; - strncpy(buf, start, len); - buf[len] = '\0'; + strlcpy(buf, start, len+1); } return true; } @@ -408,12 +404,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len) } end = strchr(start,','); if (end == NULL) - strncpy(buf, start, buf_len); + strlcpy(buf, start, buf_len); else { int len = (buf_len > (end-start))? end-start: buf_len; - strncpy(buf, start, len); - buf[len] = '\0'; + strlcpy(buf, start, len+1); } return true; } @@ -468,7 +463,7 @@ bool cfg_to_string(int i/*setting_id*/, char* buf, int buf_len) (char*)settings[i].setting, settings[i].filename_setting->suffix); } - else strncpy(buf,(char*)settings[i].setting, + else strlcpy(buf,(char*)settings[i].setting, settings[i].filename_setting->max_len); break; } /* switch () */ @@ -1011,7 +1006,7 @@ void reset_setting(const struct settings_list *setting, void *var) break; case F_T_CHARPTR: case F_T_UCHARPTR: - strncpy((char*)var, setting->default_val.charptr, + strlcpy((char*)var, setting->default_val.charptr, setting->filename_setting->max_len); break; } @@ -1114,7 +1109,7 @@ static void set_option_formatter(char* buf, size_t size, int item, const char* u { (void)unit; const unsigned char *text = set_option_options[item].string; - strncpy(buf, P2STR(text), size); + strlcpy(buf, P2STR(text), size); } static int32_t set_option_get_talk_id(int value, int unit) { @@ -1173,12 +1168,11 @@ void set_file(const char* filename, char* setting, int maxlen) } if(ptr == fptr) extlen = 0; - if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) || + if (strncasecmp(ROCKBOX_DIR, filename, strlen(ROCKBOX_DIR)) || (len-extlen > maxlen)) return; - strncpy(setting, fptr, len-extlen); - setting[len-extlen]=0; + strlcpy(setting, fptr, len-extlen+1); settings_save(); } diff --git a/apps/settings_list.c b/apps/settings_list.c index 61874787b9..c39ab580fc 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -439,7 +439,7 @@ static void qs_load_from_cfg(void* var, char*value) static char* qs_write_to_cfg(void* setting, char*buf, int buf_len) { const struct settings_list *var = &settings[*(int*)setting]; - strncpy(buf, var->cfg_name, buf_len); + strlcpy(buf, var->cfg_name, buf_len); return buf; } static bool qs_is_changed(void* setting, void* defaultval) diff --git a/apps/tagcache.c b/apps/tagcache.c index 07af9bf833..4d4935a6b6 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -706,7 +706,7 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx, if (tag != tag_filename) { ep = (struct tagfile_entry *)&hdr->tags[tag][seek]; - strncpy(buf, ep->tag_data, size-1); + strlcpy(buf, ep->tag_data, size); return true; } diff --git a/apps/tagtree.c b/apps/tagtree.c index 691b2273de..5d61589eab 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -593,7 +593,7 @@ static bool parse_search(struct menu_entry *entry, const char *str) menus[menu_count] = buffer_alloc(sizeof(struct menu_root)); new_menu = menus[menu_count]; memset(new_menu, 0, sizeof(struct menu_root)); - strncpy(new_menu->id, buf, MAX_MENU_ID_SIZE-1); + strlcpy(new_menu->id, buf, MAX_MENU_ID_SIZE); entry->link = menu_count; ++menu_count; @@ -839,7 +839,7 @@ static int parse_line(int n, const char *buf, void *parameters) menu = menus[menu_count]; ++menu_count; memset(menu, 0, sizeof(struct menu_root)); - strncpy(menu->id, data, MAX_MENU_ID_SIZE-1); + strlcpy(menu->id, data, MAX_MENU_ID_SIZE); } if (get_token_str(menu->title, sizeof(menu->title)) < 0) @@ -1442,8 +1442,8 @@ int tagtree_enter(struct tree_context* c) csi = menu->items[seek]->si; c->currextra = 0; - strncpy(current_title[c->currextra], dptr->name, - sizeof(current_title[0]) - 1); + strlcpy(current_title[c->currextra], dptr->name, + sizeof(current_title[0])); /* Read input as necessary. */ for (i = 0; i < csi->tagorder_count; i++) @@ -1464,7 +1464,7 @@ int tagtree_enter(struct tree_context* c) if (source == source_current_path && id3) { char *e; - strncpy(searchstring, id3->path, SEARCHSTR_SIZE); + strlcpy(searchstring, id3->path, SEARCHSTR_SIZE); e = strrchr(searchstring, '/'); if (e) *e = '\0'; @@ -1477,8 +1477,7 @@ int tagtree_enter(struct tree_context* c) char **src = (char**)((char*)id3 + offset); if (*src) { - strncpy(searchstring, *src, SEARCHSTR_SIZE); - searchstring[SEARCHSTR_SIZE-1] = '\0'; + strlcpy(searchstring, *src, SEARCHSTR_SIZE); } } else @@ -1528,8 +1527,8 @@ int tagtree_enter(struct tree_context* c) c->dirlevel--; /* Update the statusbar title */ - strncpy(current_title[c->currextra], dptr->name, - sizeof(current_title[0]) - 1); + strlcpy(current_title[c->currextra], dptr->name, + sizeof(current_title[0])); break; default: diff --git a/apps/talk.c b/apps/talk.c index 73c26073b7..b2e25e1f8f 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -533,7 +533,7 @@ void talk_init(void) #endif /* CONFIG_CODEC == SWCODEC */ talk_initialized = true; - strncpy((char *) last_lang, (char *)global_settings.lang_file, + strlcpy((char *)last_lang, (char *)global_settings.lang_file, MAX_FILENAME); #if CONFIG_CODEC == SWCODEC @@ -755,7 +755,7 @@ static int talk_spell_basename(const char *path, } char buf[MAX_PATH]; /* Spell only the path component after the last slash */ - strncpy(buf, path, MAX_PATH); + strlcpy(buf, path, sizeof(buf)); if(strlen(buf) >1 && buf[strlen(buf)-1] == '/') /* strip trailing slash */ buf[strlen(buf)-1] = '\0'; diff --git a/apps/tree.c b/apps/tree.c index ef65c6d86c..576453a3ad 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -505,7 +505,7 @@ char *getcwd(char *buf, int size) return tc.currdir; else if (size > 0) { - strncpy(buf, tc.currdir, size); + strlcpy(buf, tc.currdir, size); return buf; } else @@ -924,7 +924,7 @@ int rockbox_browse(const char *root, int dirfilter) } else { - strncpy(current, LANG_DIR "/english.lng", sizeof(current)); + strlcpy(current, LANG_DIR "/english.lng", sizeof(current)); } } /* Center on currently loaded WPS */ diff --git a/firmware/SOURCES b/firmware/SOURCES index 50c57e3323..8e1cef31e0 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -52,7 +52,7 @@ common/strcmp.c common/strnatcmp.c common/strcpy.c common/strncmp.c -common/strncpy.c +common/strlcpy.c common/strrchr.c common/strtok.c common/strstr.c diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c index c6af145930..25677a0903 100644 --- a/firmware/common/dir_uncached.c +++ b/firmware/common/dir_uncached.c @@ -58,8 +58,7 @@ int strip_volume(const char* name, char* namecopy) name = "/"; /* else this must be the root dir */ } - strncpy(namecopy, name, MAX_PATH); - namecopy[MAX_PATH-1] = '\0'; + strlcpy(namecopy, name, MAX_PATH); return volume; } @@ -120,8 +119,7 @@ DIR_UNCACHED* opendir_uncached(const char* name) volume = strip_volume(name, namecopy); pdir->volumecounter = 0; #else - strncpy(namecopy,name,sizeof(namecopy)); /* just copy */ - namecopy[sizeof(namecopy)-1] = '\0'; + strlcpy(namecopy, name, sizeof(namecopy)); /* just copy */ #endif if ( fat_opendir(IF_MV2(volume,) &pdir->fatdir, 0, NULL) < 0 ) { @@ -204,7 +202,7 @@ struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir) if ( !entry.name[0] ) return NULL; - strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); + strlcpy(theent->d_name, entry.name, sizeof(theent->d_name)); theent->attribute = entry.attr; theent->size = entry.filesize; theent->startcluster = entry.firstcluster; @@ -230,8 +228,7 @@ int mkdir_uncached(const char *name) return -1; } - strncpy(namecopy,name,sizeof(namecopy)); - namecopy[sizeof(namecopy)-1] = 0; + strlcpy(namecopy, name, sizeof(namecopy)); /* Split the base name and the path */ end = strrchr(namecopy, '/'); diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 01ed72adc1..e846d55452 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -232,11 +232,11 @@ static int dircache_scan(IF_MV2(int volume,) struct travel_data *td) return -2; td->pathpos = strlen(dircache_cur_path); - strncpy(&dircache_cur_path[td->pathpos], "/", - sizeof(dircache_cur_path) - td->pathpos - 1); + strlcpy(&dircache_cur_path[td->pathpos], "/", + sizeof(dircache_cur_path) - td->pathpos); #ifdef SIMULATOR - strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, - sizeof(dircache_cur_path) - td->pathpos - 2); + strlcpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, + sizeof(dircache_cur_path) - td->pathpos - 1); td->newdir = opendir_uncached(dircache_cur_path); if (td->newdir == NULL) @@ -245,8 +245,8 @@ static int dircache_scan(IF_MV2(int volume,) struct travel_data *td) return -3; } #else - strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, - sizeof(dircache_cur_path) - td->pathpos - 2); + strlcpy(&dircache_cur_path[td->pathpos+1], td->entry.name, + sizeof(dircache_cur_path) - td->pathpos - 1); td->newdir = *td->dir; if (fat_opendir(IF_MV2(volume,) &td->newdir, @@ -399,7 +399,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, char* part; char* end; - strncpy(namecopy, path, sizeof(namecopy) - 1); + strlcpy(namecopy, path, sizeof(namecopy)); cache_entry = dircache_root; before = NULL; @@ -926,7 +926,7 @@ static struct dircache_entry* dircache_new_entry(const char *path, int attribute char *new; long last_cache_size = dircache_size; - strncpy(basedir, path, sizeof(basedir)-1); + strlcpy(basedir, path, sizeof(basedir)); new = strrchr(basedir, '/'); if (new == NULL) { @@ -997,8 +997,8 @@ void dircache_bind(int fd, const char *path) { if (fdbind_idx >= MAX_PENDING_BINDINGS) return ; - strncpy(fdbind_cache[fdbind_idx].path, path, - sizeof(fdbind_cache[fdbind_idx].path)-1); + strlcpy(fdbind_cache[fdbind_idx].path, path, + sizeof(fdbind_cache[fdbind_idx].path)); fdbind_cache[fdbind_idx].fd = fd; fdbind_idx++; return ; @@ -1141,7 +1141,7 @@ void dircache_rename(const char *oldpath, const char *newpath) /* Generate the absolute path for destination if necessary. */ if (newpath[0] != '/') { - strncpy(absolute_path, oldpath, sizeof(absolute_path)-1); + strlcpy(absolute_path, oldpath, sizeof(absolute_path)); p = strrchr(absolute_path, '/'); if (!p) { @@ -1151,7 +1151,7 @@ void dircache_rename(const char *oldpath, const char *newpath) } *p = '\0'; - strncpy(p, absolute_path, sizeof(absolute_path)-1-strlen(p)); + strlcpy(p, absolute_path, sizeof(absolute_path)-strlen(p)); newpath = absolute_path; } @@ -1246,7 +1246,7 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir) if (regentry == NULL) return NULL; - strncpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH-1); + strlcpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH); dir->secondary_entry.size = regentry->size; dir->secondary_entry.startcluster = regentry->startcluster; dir->secondary_entry.attribute = regentry->attribute; @@ -1268,7 +1268,7 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir) dir->entry = ce->next; - strncpy(dir->secondary_entry.d_name, ce->d_name, MAX_PATH-1); + strlcpy(dir->secondary_entry.d_name, ce->d_name, MAX_PATH); /* Can't do `dir->secondary_entry = *ce` because that modifies the d_name pointer. */ dir->secondary_entry.size = ce->size; diff --git a/firmware/common/file.c b/firmware/common/file.c index 7c01f03817..3d7722f687 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -132,8 +132,7 @@ static int open_internal(const char* pathname, int flags, bool use_cache) } #endif - strncpy(pathnamecopy,pathname,sizeof(pathnamecopy)); - pathnamecopy[sizeof(pathnamecopy)-1] = 0; + strlcpy(pathnamecopy, pathname, sizeof(pathnamecopy)); /* locate filename */ name=strrchr(pathnamecopy+1,'/'); diff --git a/firmware/common/strlcpy.c b/firmware/common/strlcpy.c new file mode 100644 index 0000000000..ac30ef01fe --- /dev/null +++ b/firmware/common/strlcpy.c @@ -0,0 +1,52 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * 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. + * + * 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. + */ + +#include +#include + +/* + * 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) +{ + 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; + } + } + + /* 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 */ +} + diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 2ff4c61ac4..a710593a69 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -1183,7 +1183,7 @@ static int write_long_name(struct fat_file* file, /* shortname entry */ unsigned short date=0, time=0, tenth=0; LDEBUGF("Shortname entry: %s\n", shortname); - strncpy(entry + FATDIR_NAME, shortname, 11); + memcpy(entry + FATDIR_NAME, shortname, 11); entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0; entry[FATDIR_NTRES] = 0; @@ -1271,7 +1271,7 @@ static int add_dir_entry(struct fat_dir* dir, /* The "." and ".." directory entries must not be long names */ if(dotdir) { int i; - strncpy(shortname, name, 12); + strlcpy(shortname, name, 12); for(i = strlen(shortname); i < 12; i++) shortname[i] = ' '; diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index ef0865fc8c..882bfa0854 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c @@ -1152,7 +1152,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, } end = strchr(s->line, '\0'); - strncpy(end, string, current_vp->width/2); + strlcpy(end, string, current_vp->width/2); s->vp = current_vp; s->y = y; diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 5fb652431c..f11fd6fdf9 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c @@ -845,7 +845,7 @@ void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string, } end = strchr(s->line, '\0'); - strncpy(end, string, current_vp->width/2); + strlcpy(end, string, current_vp->width/2); s->vp = current_vp; s->y = y; diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index 801927eb37..57d27d2ead 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c @@ -1154,7 +1154,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, } end = strchr(s->line, '\0'); - strncpy(end, (char *)string, current_vp->width/2); + strlcpy(end, (char *)string, current_vp->width/2); s->vp = current_vp; s->y = y; diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c index 1c0a717d13..0a73f0dd25 100644 --- a/firmware/drivers/lcd-2bit-vi.c +++ b/firmware/drivers/lcd-2bit-vi.c @@ -1167,7 +1167,7 @@ void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string, } end = strchr(s->line, '\0'); - strncpy(end, (char *)string, current_vp->width/2); + strlcpy(end, (char *)string, current_vp->width/2); s->vp = current_vp; s->y = y; diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c index ca5809899f..33337daf19 100644 --- a/firmware/drivers/lcd-charcell.c +++ b/firmware/drivers/lcd-charcell.c @@ -496,7 +496,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, } end = strchr(s->line, '\0'); - strncpy(end, string, utf8seek(s->line, current_vp->width)); + strlcpy(end, string, utf8seek(s->line, current_vp->width)); s->vp = current_vp; s->y = y; diff --git a/firmware/general.c b/firmware/general.c index 14b2b55bf9..6f7238ead1 100644 --- a/firmware/general.c +++ b/firmware/general.c @@ -110,7 +110,7 @@ char *create_numbered_filename(char *buffer, const char *path, char fmtstring[12]; if (buffer != path) - strncpy(buffer, path, MAX_PATH); + strlcpy(buffer, path, MAX_PATH); pathlen = strlen(buffer); @@ -185,7 +185,7 @@ char *create_datetime_filename(char *buffer, const char *path, last_tm = *tm; if (buffer != path) - strncpy(buffer, path, MAX_PATH); + strlcpy(buffer, path, MAX_PATH); pathlen = strlen(buffer); snprintf(buffer + pathlen, MAX_PATH - pathlen, diff --git a/firmware/include/string.h b/firmware/include/string.h index 32b86cd2b0..6085c10eb6 100644 --- a/firmware/include/string.h +++ b/firmware/include/string.h @@ -35,13 +35,14 @@ char *_EXFUN(strerror,(int)); size_t _EXFUN(strlen,(const char *)); char *_EXFUN(strncat,(char *, const char *, size_t)); int _EXFUN(strncmp,(const char *, const char *, size_t)); -char *_EXFUN(strncpy,(char *, const char *, size_t)); char *_EXFUN(strpbrk,(const char *, const char *)); char *_EXFUN(strrchr,(const char *, int)); size_t _EXFUN(strspn,(const char *, const char *)); char *_EXFUN(strstr,(const char *, const char *)); char *_EXFUN(strcasestr,(const char *, const char *)); +size_t strlcpy(char *dst, const char *src, size_t siz); + #ifndef _REENT_ONLY char *_EXFUN(strtok,(char *, const char *)); #endif diff --git a/firmware/logf.c b/firmware/logf.c index a704ad2d67..6e3e532450 100644 --- a/firmware/logf.c +++ b/firmware/logf.c @@ -145,7 +145,7 @@ void _logf(const char *format, ...) while(len > MAX_LOGF_ENTRY) { ptr = logfbuffer[logfindex]; - strncpy(ptr, buf + tlen, MAX_LOGF_ENTRY-1); + strlcpy(ptr, buf + tlen, MAX_LOGF_ENTRY); ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE; logfindex++; check_logfindex();