mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Import mntent bug fixes from Musl Libc
f314e133929b6379eccc632bef32eaebb66a7335 Author: Rich Felker <dalias@aerifal.cx> Date: Thu Nov 16 12:55:21 2023 -0500 mntent: fields are delimited only by tabs or spaces, not general whitespace this matters because the kernel-provided mtab only escapes tabs, spaces, newlines, and backslashes. it leaves carriage returns, form feeds, and vertical tabs literal. commit ee1d39bc1573c1ae49ee6b658938b56bbef95a6c Author: q66 <q66@chimera-linux.org> Date: Thu Nov 9 20:48:44 2023 +0100 mntent: unescape octal sequences As entries in mtab are delimited by spaces, whitespace characters are escaped as octal sequences. When reading them out, we have to unescape these sequences to get the proper string.
This commit is contained in:
parent
9e848abad9
commit
1a6b4ab627
1 changed files with 41 additions and 5 deletions
46
third_party/musl/mntent.c
vendored
46
third_party/musl/mntent.c
vendored
|
@ -49,6 +49,42 @@ int endmntent(FILE *f)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static char *unescape_ent(char *beg)
|
||||
{
|
||||
char *dest = beg;
|
||||
const char *src = beg;
|
||||
while (*src) {
|
||||
const char *val;
|
||||
unsigned char cval = 0;
|
||||
if (*src != '\\') {
|
||||
*dest++ = *src++;
|
||||
continue;
|
||||
}
|
||||
if (src[1] == '\\') {
|
||||
++src;
|
||||
*dest++ = *src++;
|
||||
continue;
|
||||
}
|
||||
val = src + 1;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (*val >= '0' && *val <= '7') {
|
||||
cval <<= 3;
|
||||
cval += *val++ - '0';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cval) {
|
||||
*dest++ = cval;
|
||||
src = val;
|
||||
} else {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
*dest = 0;
|
||||
return beg;
|
||||
}
|
||||
|
||||
struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
|
||||
{
|
||||
int n[8], use_internal = (linebuf == SENTINEL);
|
||||
|
@ -74,7 +110,7 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle
|
|||
len = strlen(linebuf);
|
||||
if (len > INT_MAX) continue;
|
||||
for (i = 0; i < sizeof n / sizeof *n; i++) n[i] = len;
|
||||
sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
|
||||
sscanf(linebuf, " %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %d %d",
|
||||
n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
|
||||
&mnt->mnt_freq, &mnt->mnt_passno);
|
||||
} while (linebuf[n[0]] == '#' || n[1]==len);
|
||||
|
@ -84,10 +120,10 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle
|
|||
linebuf[n[5]] = 0;
|
||||
linebuf[n[7]] = 0;
|
||||
|
||||
mnt->mnt_fsname = linebuf+n[0];
|
||||
mnt->mnt_dir = linebuf+n[2];
|
||||
mnt->mnt_type = linebuf+n[4];
|
||||
mnt->mnt_opts = linebuf+n[6];
|
||||
mnt->mnt_fsname = unescape_ent(linebuf+n[0]);
|
||||
mnt->mnt_dir = unescape_ent(linebuf+n[2]);
|
||||
mnt->mnt_type = unescape_ent(linebuf+n[4]);
|
||||
mnt->mnt_opts = unescape_ent(linebuf+n[6]);
|
||||
|
||||
return mnt;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue