about summary refs log tree commit diff
path: root/src/misc/mntent.c
diff options
context:
space:
mode:
authorq66 <q66@chimera-linux.org>2023-11-09 20:48:44 +0100
committerRich Felker <dalias@aerifal.cx>2023-11-16 12:06:17 -0500
commitee1d39bc1573c1ae49ee6b658938b56bbef95a6c (patch)
treed73045b73c45efd8e3ca595f0f30a3e66b39ef69 /src/misc/mntent.c
parente17b9d74740df413fae2502c0010591c7998c40d (diff)
downloadmusl-ee1d39bc1573c1ae49ee6b658938b56bbef95a6c.tar.gz
musl-ee1d39bc1573c1ae49ee6b658938b56bbef95a6c.tar.xz
musl-ee1d39bc1573c1ae49ee6b658938b56bbef95a6c.zip
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.
Diffstat (limited to 'src/misc/mntent.c')
-rw-r--r--src/misc/mntent.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/misc/mntent.c b/src/misc/mntent.c
index d404fbe3..e9393883 100644
--- a/src/misc/mntent.c
+++ b/src/misc/mntent.c
@@ -20,6 +20,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);
@@ -55,10 +91,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;
 }