commit d8d170aa5ee1498babee095078b3888f1525a2b3 from: Omar Polo date: Fri Apr 08 13:44:49 2022 UTC allow add_mime to fail add_mime nows allocate dinamically copies of the passed strings, so that we can actually free what we parse from the config file. This matters a lot especially with lengthy `types' block: strings that reach the internal mapping are never free'd, so every manual addition is leaked. commit - aa6b8cf8ac4d93444bc2b4076b98621968bfc6ab commit + d8d170aa5ee1498babee095078b3888f1525a2b3 blob - 34132bc47b971063da9312c2a24b86a44adf8d21 blob + 111d5ea0bc22828298c7315cfc3d5e10ada1c086 --- gmid.c +++ gmid.c @@ -251,7 +251,8 @@ static int listener_main(struct imsgbuf *ibuf) { drop_priv(); - load_default_mime(&conf.mime); + if (load_default_mime(&conf.mime) == -1) + fatal("load_default_mime: %s", strerror(errno)); load_vhosts(); loop(ctx, sock4, sock6, ibuf); return 0; @@ -286,6 +287,7 @@ free_config(void) v = conf.verbose; + free_mime(&conf.mime); free(conf.chroot); free(conf.user); memset(&conf, 0, sizeof(conf)); blob - 4572db319c860f88e12c05d9f742776a999b0407 blob + 4acbf715fa474db6c4559bdaaef5630d7de8182a --- gmid.h +++ gmid.h @@ -176,8 +176,8 @@ struct vhost { }; struct etm { /* extension to mime */ - const char *mime; - const char *ext; + char *mime; + char *ext; }; struct mime { @@ -353,9 +353,10 @@ int logger_main(int, struct imsgbuf*); /* mime.c */ void init_mime(struct mime*); -void add_mime(struct mime*, const char*, const char*); -void load_default_mime(struct mime*); +int add_mime(struct mime*, const char*, const char*); +int load_default_mime(struct mime*); const char *mime(struct vhost*, const char*); +void free_mime(struct mime *); /* server.c */ extern int shutting_down; blob - 398d5614e7328c9281fd1392b678192a18dba4b9 blob + 715bec5ecae060903c30e03a29d54158caa8ce6c --- mime.c +++ mime.c @@ -32,30 +32,44 @@ init_mime(struct mime *mime) } /* register mime for the given extension */ -void +int add_mime(struct mime *mime, const char *mt, const char *ext) { - size_t oldcap; + char *mimetype, *extension; + struct etm *t; + size_t newcap; if (mime->len == mime->cap) { - oldcap = mime->cap; - mime->cap *= 1.5; - mime->t = recallocarray(mime->t, oldcap, mime->cap, + newcap = mime->cap * 1.5; + t = recallocarray(mime->t, mime->cap, newcap, sizeof(struct etm)); - if (mime->t == NULL) - err(1, "recallocarray"); + if (t == NULL) + return -1; + mime->t = t; + mime->cap = newcap; } - mime->t[mime->len].mime = mt; - mime->t[mime->len].ext = ext; + if ((mimetype = strdup(mt)) == NULL) + return -1; + if ((extension = strdup(ext)) == NULL) { + free(mimetype); + return -1; + } + + mime->t[mime->len].mime = mimetype; + mime->t[mime->len].ext = extension; mime->len++; + return 0; } /* load a default set of common mime-extension associations */ -void +int load_default_mime(struct mime *mime) { - const struct etm *i, m[] = { + const struct mapping { + const char *mime; + const char *ext; + } m[] = { {"application/pdf", "pdf"}, {"image/gif", "gif"}, {"image/jpeg", "jpg"}, @@ -71,10 +85,14 @@ load_default_mime(struct mime *mime) {"text/x-patch", "patch"}, {"text/xml", "xml"}, {NULL, NULL} - }; + }, *i; - for (i = m; i->mime != NULL; ++i) - add_mime(mime, i->mime, i->ext); + for (i = m; i->mime != NULL; ++i) { + if (add_mime(mime, i->mime, i->ext) == -1) + return -1; + } + + return 0; } static const char * @@ -110,3 +128,16 @@ mime(struct vhost *host, const char *path) return def; } + +void +free_mime(struct mime *m) +{ + struct etm *t; + + for (t = m->t; t->mime != NULL; ++t) { + free(t->mime); + free(t->ext); + } + + free(m->t); +} blob - d28195aacaffa58b1addadf877df5bb787210fbd blob + ed1481005769d7bfa3eafb5f51022517d9c285a1 --- parse.y +++ parse.y @@ -219,13 +219,15 @@ option : CHROOT string { conf.chroot = $2; } yywarn("`mime MIME EXT' is deprecated and will be " "removed in a future version, please use the new " "`types' block."); - add_mime(&conf.mime, $2, $3); + if (add_mime(&conf.mime, $2, $3) == -1) + err(1, "add_mime"); } | MAP string TOEXT string { yywarn("`map mime to-ext' is deprecated and will be " "removed in a future version, please use the new " "`types' block."); - add_mime(&conf.mime, $2, $4); + if (add_mime(&conf.mime, $2, $4) == -1) + err(1, "add_mime"); } | PORT NUM { conf.port = check_port_num($2); } | PREFORK NUM { conf.prefork = check_prefork_num($2); } @@ -488,7 +490,10 @@ medianames_l : medianames_l medianamesl | medianamesl ; -medianamesl : numberstring { add_mime(&conf.mime, current_media, $1); } +medianamesl : numberstring { + if (add_mime(&conf.mime, current_media, $1) == -1) + err(1, "add_mime"); + } ; nl : '\n' optnl