diff options
author | Leah Neukirchen <leah@vuxu.org> | 2021-08-10 22:17:19 +0200 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2021-08-10 22:21:42 +0200 |
commit | 69a1701438fa91a23b452255e870542dfd250255 (patch) | |
tree | d7c9f172ec132e4e21d45660ed4a688312947606 | |
parent | e894a26cf538f8341b93acf6ececc3df88125bc7 (diff) | |
download | hittpd-69a1701438fa91a23b452255e870542dfd250255.tar.gz hittpd-69a1701438fa91a23b452255e870542dfd250255.tar.xz hittpd-69a1701438fa91a23b452255e870542dfd250255.zip |
fix mimetype lookup
Fix overflow on long mime types, found by Érico Nogueira. Allow maximum length of mime types, as per spec, then truncate. Fix mime type lookup when extensions match some mime type.
-rw-r--r-- | hittpd.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/hittpd.c b/hittpd.c index 554ed0d..77fcda3 100644 --- a/hittpd.c +++ b/hittpd.c @@ -453,27 +453,41 @@ send_ok(http_parser *p, time_t modified, const char *mimetype, off_t filesize) } } +static const char * +getmime(const char *mime, char *ext) +{ + size_t extlen = strlen(ext); + const char *c = mime; + + do { + c++; + if (strncmp(c, ext, extlen) == 0 && c[extlen] == '=') + return c + extlen + 1; + } while ((c = strchr(c, ':'))); + + return 0; +} + const char * mimetype(char *ext) { - static char type[16]; + static char type[256]; // RFC 6838 if (!ext) return default_mimetype; - char *x = strstr(custom_mimetypes, ext); + const char *x = getmime(custom_mimetypes, ext); if (!x) - x = strstr(mimetypes, ext); - - if (x && x[-1] == ':' && x[strlen(ext)] == '=') { - char *t = type; - for (char *c = x + strlen(ext) + 1; *c && *c != ':'; ) - *t++ = *c++; - *t = 0; - return type; - } + x = getmime(mimetypes, ext); + if (!x) + return default_mimetype; - return default_mimetype; + char *t = type; + char *e = type + sizeof type - 1; + for (const char *c = x; t < e && *c && *c != ':'; ) + *t++ = *c++; + *t = 0; + return type; } static inline int |