typedef enum StringSafeFlags {
STRING_ASCII = 1 << 0, /* Verify string is 7-Bit ASCII (rather than just UTF-8) */
STRING_ALLOW_EMPTY = 1 << 1, /* Allow empty strings */
- STRING_ALLOW_BACKSLASHES = 1 << 2, /* Allow backslashes (\) */
- STRING_ALLOW_QUOTES = 1 << 3, /* Allow quotes (" or ') */
- STRING_ALLOW_GLOBS = 1 << 4, /* Allow globs (?, * or [) */
- STRING_FILENAME = 1 << 5, /* Verify the string is valid as regular filename */
+ STRING_ALLOW_NEWLINES = 1 << 2, /* Allow newlines (\n) */
+ STRING_ALLOW_BACKSLASHES = 1 << 3, /* Allow backslashes (\) */
+ STRING_ALLOW_QUOTES = 1 << 4, /* Allow quotes (" or ') */
+ STRING_ALLOW_GLOBS = 1 << 5, /* Allow globs (?, * or [) */
+ STRING_FILENAME = 1 << 6, /* Verify the string is valid as regular filename */
} StringSafeFlags;
bool string_is_safe(const char *p, StringSafeFlags flags) _pure_;
ASSERT_FALSE(string_is_safe("a\"b", STRING_ASCII));
ASSERT_FALSE(string_is_safe("a*b", STRING_ASCII));
+ /* STRING_ALLOW_NEWLINES: newlines allowed, quotes/globs still rejected. */
+ ASSERT_TRUE(string_is_safe("hello", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("hello world", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("\n", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("a\nb", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("foo\n", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("\nfoo", STRING_ALLOW_NEWLINES));
+ ASSERT_TRUE(string_is_safe("foo\nbar", STRING_ALLOW_NEWLINES));
+ ASSERT_FALSE(string_is_safe("foo\\nbar", STRING_ALLOW_NEWLINES)); /* literal backslash, not newline, rejected */
+ ASSERT_FALSE(string_is_safe("\"", STRING_ALLOW_NEWLINES)); /* quotes still rejected */
+ ASSERT_FALSE(string_is_safe("*", STRING_ALLOW_NEWLINES)); /* globs still rejected */
+
/* STRING_ALLOW_BACKSLASHES: backslashes allowed, quotes/globs still rejected. */
ASSERT_TRUE(string_is_safe("hello", STRING_ALLOW_BACKSLASHES));
ASSERT_TRUE(string_is_safe("hello world", STRING_ALLOW_BACKSLASHES));
ASSERT_TRUE(string_is_safe("foo\\", STRING_ALLOW_BACKSLASHES));
ASSERT_TRUE(string_is_safe("\\foo", STRING_ALLOW_BACKSLASHES));
ASSERT_TRUE(string_is_safe("foo\\nbar", STRING_ALLOW_BACKSLASHES)); /* literal backslash, not newline */
+ ASSERT_FALSE(string_is_safe("foo\nbar", STRING_ALLOW_BACKSLASHES)); /* newline still rejected */
ASSERT_FALSE(string_is_safe("\"", STRING_ALLOW_BACKSLASHES)); /* quotes still rejected */
ASSERT_FALSE(string_is_safe("*", STRING_ALLOW_BACKSLASHES)); /* globs still rejected */
ASSERT_TRUE(string_is_safe("'", STRING_ALLOW_QUOTES));
ASSERT_TRUE(string_is_safe("hello\"world", STRING_ALLOW_QUOTES));
ASSERT_TRUE(string_is_safe("it's", STRING_ALLOW_QUOTES));
+ ASSERT_FALSE(string_is_safe("a\nb", STRING_ALLOW_QUOTES)); /* newline still rejected */
ASSERT_FALSE(string_is_safe("a\\b", STRING_ALLOW_QUOTES)); /* backslashes still rejected */
ASSERT_FALSE(string_is_safe("*", STRING_ALLOW_QUOTES)); /* globs still rejected */
ASSERT_TRUE(string_is_safe("foo*bar", STRING_ALLOW_GLOBS));
ASSERT_TRUE(string_is_safe("foo?bar", STRING_ALLOW_GLOBS));
ASSERT_TRUE(string_is_safe("foo[bar", STRING_ALLOW_GLOBS));
+ ASSERT_FALSE(string_is_safe("foo\nbar", STRING_ALLOW_GLOBS)); /* newline still rejected */
ASSERT_FALSE(string_is_safe("\"", STRING_ALLOW_GLOBS)); /* quotes still rejected */
ASSERT_FALSE(string_is_safe("a\\b", STRING_ALLOW_GLOBS)); /* backslashes still rejected */
ASSERT_TRUE(string_is_safe("foo\"bar", STRING_ALLOW_BACKSLASHES | STRING_ALLOW_QUOTES));
/* All allow flags combined: only baseline (control chars, invalid UTF-8) and STRING_FILENAME apply. */
- StringSafeFlags all = STRING_ALLOW_EMPTY | STRING_ASCII | STRING_ALLOW_BACKSLASHES | STRING_ALLOW_QUOTES | STRING_ALLOW_GLOBS | STRING_FILENAME;
+ StringSafeFlags all =
+ STRING_ASCII |
+ STRING_ALLOW_EMPTY |
+ STRING_ALLOW_NEWLINES |
+ STRING_ALLOW_BACKSLASHES |
+ STRING_ALLOW_QUOTES |
+ STRING_ALLOW_GLOBS |
+ STRING_FILENAME;
ASSERT_TRUE(string_is_safe("hello.txt", all));
ASSERT_TRUE(string_is_safe("foo-bar_baz.conf", all));
ASSERT_TRUE(string_is_safe("a", all));
+ ASSERT_TRUE(string_is_safe("foo\nbar", all)); /* newline allowed */
ASSERT_TRUE(string_is_safe("foo\\bar", all)); /* backslash allowed */
ASSERT_TRUE(string_is_safe("foo\"bar", all)); /* quote allowed */
ASSERT_TRUE(string_is_safe("foo'bar", all)); /* quote allowed */