From 675e4057bae380395a9198bfbfe4066ae1fa4675 Mon Sep 17 00:00:00 2001 From: Cameron Paul Date: Thu, 27 Mar 2025 09:45:31 -0500 Subject: Handle quoted content dispositions and escape special filesystem characters --- src/misc.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/misc.c b/src/misc.c index 83c43eb4..7a9b73cd 100644 --- a/src/misc.c +++ b/src/misc.c @@ -371,7 +371,7 @@ void a_Misc_parse_content_disposition(const char *disposition, char **type, char if (!(str = disposition)) return; - for (s = str; *s && d_isascii((uchar_t)*s) && !iscntrl((uchar_t)*s) && + for (s = str; *s && d_isascii(*s) && !iscntrl(*s) && !strchr(tspecials_space, *s); s++) ; if (type) *type = dStrndup(str, s - str); @@ -385,15 +385,33 @@ void a_Misc_parse_content_disposition(const char *disposition, char **type, char s += sizeof(key) - 1; for ( ; *s == ' ' || *s == '\t'; ++s); if (*s == '=') { - size_t len; + size_t len = 0; for (++s; *s == ' ' || *s == '\t'; ++s); - if ((len = strcspn(s, terminators))) { - if (*s == '"' && s[len-1] == '"' && len > 1) { - /* quoted string */ - s++; - len -= 2; + if (*s == '"') { + s++; + for ( ; *s == '.'; ++s); + bool_t escaped = FALSE; + const char *c; + unsigned int maxlen = strlen(s); + for (c = s; !(*c == '"' && !escaped); c++) { + if ((len = c - s) == maxlen) { + return; + } + escaped = *c == '\\'; } *filename = dStrndup(s, len); + } else { + for ( ; *s == '.'; ++s); + if ((len = strcspn(s, terminators))) { + *filename = dStrndup(s, len); + } + } + + const char invalid_characters[] = "/\\|"; + for (char *s = *filename; s < *filename + len; s++) { + if (strchr(invalid_characters, *s)) { + *s = '_'; + } } } } -- cgit v1.2.3