mirror of https://github.com/omar-polo/gmid.git
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.
This commit is contained in:
parent
aa6b8cf8ac
commit
d8d170aa5e
4
gmid.c
4
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));
|
||||
|
|
9
gmid.h
9
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;
|
||||
|
|
59
mime.c
59
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);
|
||||
}
|
||||
|
|
11
parse.y
11
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
|
||||
|
|
Loading…
Reference in New Issue