summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2023-11-23 08:10:46 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2023-11-23 21:26:13 -0500
commitcb3b5397b34eb6ad181b2c9d32996152f28d3974 (patch)
tree377d19a5c9a9af88bfb3b77271d0aa2fa75f09d9
parent53a47970e30bbe518442aa59e4ff5b126c66c581 (diff)
downloadrockbox-cb3b5397b34eb6ad181b2c9d32996152f28d3974.tar.gz
rockbox-cb3b5397b34eb6ad181b2c9d32996152f28d3974.zip
Revert "Extend path_append_ex to truncate compname, remove some strmemdupa"
This reverts commit dbe20d453d5e93bd0f1188a8851c6cf4fd230b26. Reason for revert: Crashes ipod Classic Change-Id: I9ea329ce73383535353832d17c7c5e494e5ad516
-rw-r--r--apps/playlist.c2
-rw-r--r--firmware/common/dircache.c89
-rw-r--r--firmware/common/file.c5
-rw-r--r--firmware/common/file_internal.c9
-rw-r--r--firmware/common/pathfuncs.c69
-rw-r--r--firmware/export/pathfuncs.h2
6 files changed, 55 insertions, 121 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index f4e8ddb104..67d59d1aac 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -589,7 +589,7 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length,
589 dlen = -1u; 589 dlen = -1u;
590 } 590 }
591 591
592 len = path_append_ex(dest, dir, dlen, src, -1u, buf_length); 592 len = path_append_ex(dest, dir, dlen, src, buf_length);
593 if (len >= (size_t)buf_length) 593 if (len >= (size_t)buf_length)
594 return -1; /* buffer too small */ 594 return -1; /* buffer too small */
595 595
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index c5062d47ed..41564194d0 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -2488,81 +2488,44 @@ struct get_path_sub_data
2488 2488
2489static ssize_t get_path_sub(int idx, struct get_path_sub_data *data) 2489static ssize_t get_path_sub(int idx, struct get_path_sub_data *data)
2490{ 2490{
2491
2492#ifdef HAVE_MULTIVOLUME
2493#define NAMEBUFLEN (MAX(VOL_MAX_LEN+1, MAX_TINYNAME+1))
2494#else
2495#define NAMEBUFLEN (MAX_TINYNAME+1)
2496#endif
2497 char namebuf[NAMEBUFLEN];
2498#undef NAMEBUFLEN
2499
2500 if (idx == 0) 2491 if (idx == 0)
2501 return -1; /* entry is an orphan split from any root */ 2492 return -1; /* entry is an orphan split from any root */
2502 2493
2503 char *cename = ""; 2494 ssize_t len;
2504 size_t cename_len = (-1u); 2495 char *cename;
2505 ssize_t len = 0;
2506 int next_idx = idx;
2507 int count = 1; /* +1 for the idx incoming */
2508 int remain;
2509 2496
2510 do /* go all the way up to the root */ 2497 if (idx > 0)
2511 { 2498 {
2512 count++; 2499 struct dircache_entry *ce = get_entry(idx);
2513 if (next_idx > (int)dircache.numentries)
2514 return -1; /* ERROR! */
2515 next_idx = dircache_runinfo.pentry[next_idx].up;
2516 } while (next_idx > 0);
2517 2500
2518 if (next_idx < 0) /* root */ 2501 data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash);
2519 {
2520 data->serialhash = dc_hash_serialnum(get_idx_dcvolp(next_idx)->serialnum,
2521 data->serialhash);
2522#ifdef HAVE_MULTIVOLUME
2523 /* prepend the volume specifier */
2524 cename = namebuf;
2525 get_volume_name(IF_MV_VOL(-next_idx - 1), cename);
2526#endif /* HAVE_MULTIVOLUME */
2527 }
2528 2502
2529 /* we have the volume name write it to the buffer */ 2503 /* go all the way up then move back down from the root */
2530 goto write_path_component; 2504 len = get_path_sub(ce->up, data) - 1;
2531 /* if not MULTIVOLUME it will just be adding '/' */ 2505 if (len < 0)
2506 return -2;
2532 2507
2533 while (next_idx > 0 && count > 0) 2508 cename = alloca(DC_MAX_NAME + 1);
2509 entry_name_copy(cename, ce);
2510 }
2511 else /* idx < 0 */
2534 { 2512 {
2535 struct dircache_entry *ce = &dircache_runinfo.pentry[next_idx]; 2513 len = 0;
2536 if (remain <= 0) 2514 cename = "";
2537 {
2538 data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash);
2539 if (LIKELY(!ce->tinyname))
2540 {
2541 cename = get_name(ce->name);
2542 cename_len = CE_NAMESIZE(ce->namelen);
2543 }
2544 else
2545 {
2546 cename = namebuf;
2547 entry_name_copy(cename, ce);
2548 cename_len = -1u;
2549 }
2550write_path_component:
2551 len += path_append_ex(data->buf + len, PA_SEP_HARD, -1u, cename, cename_len,
2552 data->size > (size_t)len ? data->size - len : 0);
2553 2515
2554 count--; 2516 #ifdef HAVE_MULTIVOLUME
2555 remain = count - 1; 2517 /* prepend the volume specifier */
2556 next_idx = idx; 2518 int volume = IF_MV_VOL(-idx - 1);
2557 } 2519 cename = alloca(VOL_MAX_LEN+1);
2558 else 2520 get_volume_name(volume, cename);
2559 { 2521 #endif /* HAVE_MULTIVOLUME */
2560 remain--;
2561 next_idx = ce->up;
2562 }
2563 2522
2523 data->serialhash = dc_hash_serialnum(get_idx_dcvolp(idx)->serialnum,
2524 data->serialhash);
2564 } 2525 }
2565 return len; 2526
2527 return len + path_append(data->buf + len, PA_SEP_HARD, cename,
2528 data->size > (size_t)len ? data->size - len : 0);
2566} 2529}
2567 2530
2568/** 2531/**
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 2012e2ff80..202410db81 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -1056,7 +1056,7 @@ int rename(const char *old, const char *new)
1056 FILE_ERROR(EINVAL, -4); 1056 FILE_ERROR(EINVAL, -4);
1057 } 1057 }
1058 1058
1059 //const char * const oldname = strmemdupa(oldinfo.name, oldinfo.length); 1059 const char * const oldname = strmemdupa(oldinfo.name, oldinfo.length);
1060 const char * const newname = strmemdupa(newinfo.name, newinfo.length); 1060 const char * const newname = strmemdupa(newinfo.name, newinfo.length);
1061 bool is_overwrite = false; 1061 bool is_overwrite = false;
1062 1062
@@ -1076,8 +1076,7 @@ int rename(const char *old, const char *new)
1076 FILE_ERROR(ERRNO, rc * 10 - 5); 1076 FILE_ERROR(ERRNO, rc * 10 - 5);
1077 } 1077 }
1078 } 1078 }
1079 else if (!strncmp(newname, oldinfo.name, oldinfo.length) && /* case-only is ok */ 1079 else if (!strcmp(newname, oldname)) /* case-only is ok */
1080 newname[oldinfo.length] == '\0') /* make sure of actual match */
1081 { 1080 {
1082 DEBUGF("No name change (success)\n"); 1081 DEBUGF("No name change (success)\n");
1083 rc = 0; 1082 rc = 0;
diff --git a/firmware/common/file_internal.c b/firmware/common/file_internal.c
index 8e0df576bf..a73d9beaa2 100644
--- a/firmware/common/file_internal.c
+++ b/firmware/common/file_internal.c
@@ -433,7 +433,7 @@ static NO_INLINE int open_path_component(struct pathwalk *walkp,
433 int rc; 433 int rc;
434 434
435 /* create a null-terminated copy of the component name */ 435 /* create a null-terminated copy of the component name */
436 //char *compname = strmemdupa(compp->name, compp->length); 436 char *compname = strmemdupa(compp->name, compp->length);
437 437
438 unsigned int callflags = walkp->callflags; 438 unsigned int callflags = walkp->callflags;
439 struct pathwalk_component *parentp = compp->nextp; 439 struct pathwalk_component *parentp = compp->nextp;
@@ -455,8 +455,7 @@ static NO_INLINE int open_path_component(struct pathwalk *walkp,
455 if (rc > 1 && !(callflags & FF_NOISO)) 455 if (rc > 1 && !(callflags & FF_NOISO))
456 iso_decode_d_name(dir_fatent.name); 456 iso_decode_d_name(dir_fatent.name);
457 457
458 if (!strncasecmp(compp->name, dir_fatent.name, compp->length) && 458 if (!strcasecmp(compname, dir_fatent.name))
459 dir_fatent.name[compp->length] == '\0') /* make sure of actual match */
460 break; 459 break;
461 } 460 }
462 461
@@ -475,8 +474,8 @@ static NO_INLINE int open_path_component(struct pathwalk *walkp,
475 &compp->info.fatfile); 474 &compp->info.fatfile);
476 if (rc < 0) 475 if (rc < 0)
477 { 476 {
478 DEBUGF("I/O error opening file/directory %.*s (%d)\n", 477 DEBUGF("I/O error opening file/directory %s (%d)\n",
479 compp->length, compp->name, rc); 478 compname, rc);
480 return -EIO; 479 return -EIO;
481 } 480 }
482 481
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c
index b95cbab354..fa296cc2ed 100644
--- a/firmware/common/pathfuncs.c
+++ b/firmware/common/pathfuncs.c
@@ -447,22 +447,10 @@ void path_remove_dot_segments (char *dstpath, const char *path)
447 *dstp = 0; 447 *dstp = 0;
448} 448}
449 449
450/* helper function copy n chars of a string to a dst buffer of dst_sz
451 * returns the length of the string it created or attempted to create
452 */
453static inline size_t copynchars(char *dst, size_t dst_sz, const char *src, size_t src_max)
454{
455 int cpychrs = -1;
456 if (src_max < -1u) /* we could be dealing with unterminated strings */
457 cpychrs = src_max;
458 /* testing shows this to be on par with using discreet functions and safer ;) */
459 int ret = snprintf(dst, dst_sz, "%.*s", cpychrs, src);
460 if (ret >= 0)
461 return ret;
462
463 return 0; /* Error */
464}
465/* Appends one path to another, adding separators between components if needed. 450/* Appends one path to another, adding separators between components if needed.
451 * basepath_max can be used to truncate the basepath if desired
452 * NOTE: basepath is truncated after copying to the buffer so there must be enough
453 * free space for the entirety of the basepath even if the resulting string would fit
466 * 454 *
467 * Return value and behavior is otherwise as strlcpy so that truncation may be 455 * Return value and behavior is otherwise as strlcpy so that truncation may be
468 * detected. 456 * detected.
@@ -470,52 +458,45 @@ static inline size_t copynchars(char *dst, size_t dst_sz, const char *src, size_
470 * For basepath and component: 458 * For basepath and component:
471 * PA_SEP_HARD adds a separator even if the base path is empty 459 * PA_SEP_HARD adds a separator even if the base path is empty
472 * PA_SEP_SOFT adds a separator only if the base path is not empty 460 * PA_SEP_SOFT adds a separator only if the base path is not empty
473 *
474 * basepath_max can be used to truncate the basepath if desired
475 * component_max can be used to truncate the component if desired
476 *
477 * (Supply -1u to disable truncation)
478 */ 461 */
479size_t path_append_ex(char *buf, const char *basepath, size_t basepath_max, 462size_t path_append_ex(char *buf, const char *basepath, size_t basepath_max,
480 const char *component, size_t component_max, size_t bufsize) 463 const char *component, size_t bufsize)
481{ 464{
482 size_t len; 465 size_t len;
483 bool check_base = (basepath_max == 0);
484 bool separate = false; 466 bool separate = false;
485 const char *base = basepath && !check_base && basepath[0] ? basepath : buf; 467 const char *base = basepath && basepath[0] ? basepath : buf;
486
487 if (!base) 468 if (!base)
488 return bufsize; /* won't work to get lengths from buf */ 469 return bufsize; /* won't work to get lengths from buf */
489 470
490 if (!buf) 471 if (!buf)
491 {
492 static char fbuf; /* fake buffer to elide later null checks */
493 buf = &fbuf;
494 bufsize = 0; 472 bufsize = 0;
495 } 473
496 if (!component)
497 {
498 check_base = true;
499 component = "";
500 }
501 if (path_is_absolute(component)) 474 if (path_is_absolute(component))
502 { 475 {
503 /* 'component' is absolute; replace all */ 476 /* 'component' is absolute; replace all */
504 basepath = component; 477 basepath = component;
505 basepath_max = component_max;
506 component = ""; 478 component = "";
479 basepath_max = -1u;
507 } 480 }
508 481
509 /* if basepath is not null or empty, buffer contents are replaced, 482 /* if basepath is not null or empty, buffer contents are replaced,
510 otherwise buf contains the base path */ 483 otherwise buf contains the base path */
484
511 if (base == buf) 485 if (base == buf)
512 len = strlen(buf); 486 len = strlen(buf);
513 else 487 else
514 len = copynchars(buf, bufsize, basepath, basepath_max); 488 {
489 len = strlcpy(buf, basepath, bufsize);
490 if (basepath_max < len)
491 {
492 len = basepath_max;
493 buf[basepath_max] = '\0';
494 }
495 }
515 496
516 if (!basepath || basepath_max == 0 || check_base) 497 if (!basepath || !component || basepath_max == 0)
517 separate = !len || base[len-1] != PATH_SEPCH; 498 separate = !len || base[len-1] != PATH_SEPCH;
518 else if (component[0] && component_max > 0) 499 else if (component[0])
519 separate = len && base[len-1] != PATH_SEPCH; 500 separate = len && base[len-1] != PATH_SEPCH;
520 501
521 /* caller might lie about size of buf yet use buf as the base */ 502 /* caller might lie about size of buf yet use buf as the base */
@@ -528,22 +509,14 @@ size_t path_append_ex(char *buf, const char *basepath, size_t basepath_max,
528 if (separate && (len++, bufsize > 0) && --bufsize > 0) 509 if (separate && (len++, bufsize > 0) && --bufsize > 0)
529 *buf++ = PATH_SEPCH; 510 *buf++ = PATH_SEPCH;
530 511
531 return len + copynchars(buf, bufsize, component, component_max); 512 return len + strlcpy(buf, component ?: "", bufsize);
532} 513}
533 514
534/* Appends one path to another, adding separators between components if needed. 515
535 *
536 * Return value and behavior is otherwise as strlcpy so that truncation may be
537 * detected.
538 *
539 * For basepath and component:
540 * PA_SEP_HARD adds a separator even if the base path is empty
541 * PA_SEP_SOFT adds a separator only if the base path is not empty
542 */
543size_t path_append(char *buf, const char *basepath, 516size_t path_append(char *buf, const char *basepath,
544 const char *component, size_t bufsize) 517 const char *component, size_t bufsize)
545{ 518{
546 return path_append_ex(buf, basepath, -1u, component, -1u, bufsize); 519 return path_append_ex(buf, basepath, -1u, component, bufsize);
547} 520}
548/* Returns the location and length of the next path component, consuming the 521/* Returns the location and length of the next path component, consuming the
549 * input in the process. 522 * input in the process.
diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h
index 022a631654..1b18f22d06 100644
--- a/firmware/export/pathfuncs.h
+++ b/firmware/export/pathfuncs.h
@@ -95,7 +95,7 @@ void path_remove_dot_segments(char *dstpath, const char *path);
95#define PA_SEP_HARD NULL /* separate even if base is empty */ 95#define PA_SEP_HARD NULL /* separate even if base is empty */
96#define PA_SEP_SOFT "" /* separate only if base is nonempty */ 96#define PA_SEP_SOFT "" /* separate only if base is nonempty */
97size_t path_append_ex(char *buf, const char *basepath, size_t basepath_max, 97size_t path_append_ex(char *buf, const char *basepath, size_t basepath_max,
98 const char *component, size_t component_max, size_t bufsize); 98 const char *component, size_t bufsize);
99size_t path_append(char *buffer, const char *basepath, const char *component, 99size_t path_append(char *buffer, const char *basepath, const char *component,
100 size_t bufsize); 100 size_t bufsize);
101ssize_t parse_path_component(const char **pathp, const char **namep); 101ssize_t parse_path_component(const char **pathp, const char **namep);