From 69a1701438fa91a23b452255e870542dfd250255 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Tue, 10 Aug 2021 22:17:19 +0200 Subject: fix mimetype lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- hittpd.c | 38 ++++++++++++++++++++++++++------------ 1 file 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 -- cgit 1.4.1