Dir cache: Fix resume of relative path playlists.

Slightly modified from original patch by Fabrice Bellard.

Change-Id: I9ae04fa460f0f1b9c616e6f99505d4c5d4358f68
This commit is contained in:
James D. Smith 2021-09-18 21:09:24 -06:00 committed by Solomon Peachy
parent 67716c6b46
commit 760277e096
3 changed files with 57 additions and 4 deletions

View file

@ -1762,9 +1762,8 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length,
* to "/<0>/bar" (aka "/bar" at this time). *fingers crossed*
*
* If any stripped drive spec was absolute, prepend the playlist
* directory's volume spec, or root if none. Relative paths remain
* relative and the playlist's directory fully qualifies them. Absolute
* UNIX-style paths remain unaltered.
* directory's volume spec, or root if none. Absolute UNIX-style paths
* remain unaltered.
*/
if (path_strip_drive(src, (const char **)&src, true) >= 0 &&
src[-1] == PATH_SEPCH)
@ -1782,7 +1781,9 @@ static ssize_t format_track_path(char *dest, char *src, int buf_length,
if (len >= (size_t)buf_length)
return -1; /* buffer too small */
return len;
path_remove_dot_segments (dest, dest);
return strlen (dest);
}
/*

View file

@ -340,6 +340,57 @@ void path_correct_separators(char *dstpath, const char *path)
strcpy(dstp, p);
}
/* Remove dot segments from the path
*
* 'path' and 'dstpath' may either be the same buffer or non-overlapping
*/
void path_remove_dot_segments (char *dstpath, const char *path)
{
char *dstp = dstpath;
char *odstp = dstpath;
const char *p = path;
while (*p)
{
if (p[0] == '.' && p[1] == PATH_SEPCH)
p += 2;
else if (p[0] == '.' && p[1] == '.' && p[2] == PATH_SEPCH)
p += 3;
else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == PATH_SEPCH)
p += 2;
else if (p[0] == PATH_SEPCH && p[1] == '.' && !p[2])
{
*dstp++ = PATH_SEPCH;
break;
}
else if (p[0] == PATH_SEPCH && p[1] == '.' &&
p[2] == '.' && p[3] == PATH_SEPCH)
{
dstp = odstp;
p += 3;
}
else if (p[0] == PATH_SEPCH && p[1] == '.' && p[2] == '.' && !p[3])
{
dstp = odstp;
*dstp++ = PATH_SEPCH;
break;
}
else if (p[0] == '.' && !p[1])
break;
else if (p[0] == '.' && p[1] == '.' && !p[2])
break;
else
{
odstp = dstp;
if (p[0] == PATH_SEPCH)
*dstp++ = *p++;
while (p[0] && p[0] != PATH_SEPCH)
*dstp++ = *p++;
}
}
*dstp = 0;
}
/* Appends one path to another, adding separators between components if needed.
* Return value and behavior is otherwise as strlcpy so that truncation may be
* detected.

View file

@ -82,6 +82,7 @@ size_t path_basename(const char *name, const char **nameptr);
size_t path_dirname(const char *name, const char **nameptr);
size_t path_strip_trailing_separators(const char *name, const char **nameptr);
void path_correct_separators(char *dstpath, const char *path);
void path_remove_dot_segments(char *dstpath, const char *path);
/* constants useable in basepath and component */
#define PA_SEP_HARD NULL /* separate even if base is empty */