mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-10-27 19:34:33 +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…
Add table
Add a link
Reference in a new issue