From 1a6b4ab62713e0d1ff87db448ed052dcfb35d9a5 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 23 Apr 2024 09:29:56 -0700 Subject: [PATCH] Import mntent bug fixes from Musl Libc f314e133929b6379eccc632bef32eaebb66a7335 Author: Rich Felker 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 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. --- third_party/musl/mntent.c | 46 ++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/third_party/musl/mntent.c b/third_party/musl/mntent.c index 275ba586d..0062076be 100644 --- a/third_party/musl/mntent.c +++ b/third_party/musl/mntent.c @@ -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; }