From bd380777d68816b55da85a42d4cdf7fb262b4ba2 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 23 Feb 2022 12:35:04 -0800 Subject: Make the output of 'fscrypt status' unambiguous Following the example of /proc/self/mountinfo, replace the space, newline, tab, and backslash characters with octal escape sequences so that the output can be parsed unambiguously. --- filesystem/mountpoint.go | 15 +++++++++++++++ filesystem/mountpoint_test.go | 15 +++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'filesystem') diff --git a/filesystem/mountpoint.go b/filesystem/mountpoint.go index 182cafa..0b0693b 100644 --- a/filesystem/mountpoint.go +++ b/filesystem/mountpoint.go @@ -77,6 +77,21 @@ func unescapeString(str string) string { return sb.String() } +// EscapeString is the reverse of unescapeString. Use this to avoid injecting +// spaces or newlines into output that uses these characters as separators. +func EscapeString(str string) string { + var sb strings.Builder + for _, b := range []byte(str) { + switch b { + case ' ', '\t', '\n', '\\': + sb.WriteString(fmt.Sprintf("\\%03o", b)) + default: + sb.WriteByte(b) + } + } + return sb.String() +} + // We get the device name via the device number rather than use the mount source // field directly. This is necessary to handle a rootfs that was mounted via // the kernel command line, since mountinfo always shows /dev/root for that. diff --git a/filesystem/mountpoint_test.go b/filesystem/mountpoint_test.go index 749e5e3..99d4b55 100644 --- a/filesystem/mountpoint_test.go +++ b/filesystem/mountpoint_test.go @@ -179,6 +179,21 @@ func TestLoadMountWithSpecialCharacters(t *testing.T) { } } +// Tests the EscapeString() and unescapeString() functions. +func TestStringEscaping(t *testing.T) { + charsNeedEscaping := " \t\n\\" + charsDontNeedEscaping := "ABCDEF\u2603\xff\xff\v" + + orig := charsNeedEscaping + charsDontNeedEscaping + escaped := `\040\011\012\134` + charsDontNeedEscaping + if EscapeString(orig) != escaped { + t.Fatal("EscapeString gave wrong result") + } + if unescapeString(escaped) != orig { + t.Fatal("unescapeString gave wrong result") + } +} + // Test parsing some invalid mountinfo lines. func TestLoadBadMountInfo(t *testing.T) { mountinfos := []string{"a", -- cgit v1.2.3