X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/1a3dba678a4edf1df3d7de2cc29f8e32d6fea080..40dcd866894885d9d1965be248b7e04af0f853f0:/server/actions.c diff --git a/server/actions.c b/server/actions.c index aca4db0..a504ed5 100644 --- a/server/actions.c +++ b/server/actions.c @@ -166,19 +166,43 @@ static const struct action { { "remove", act_remove }, }; +/** @brief Check that an action name is valid + * @param name Action + * @return 1 if valid, 0 if not + */ +static int dcgi_valid_action(const char *name) { + int c; + + /* First character must be letter or digit (this also requires there to _be_ + * a first character) */ + if(!isalnum((unsigned char)*name)) + return 0; + /* Only letters, digits, '.' and '-' allowed */ + while((c = (unsigned char)*name++)) { + if(!(isalnum(c) + || c == '.' + || c == '_')) + return 0; + } + return 1; +} + /** @brief Expand a template * @param name Base name of template, or NULL to consult CGI args */ void dcgi_expand(const char *name) { - const char *p; - + const char *p, *found; + + /* Parse macros first */ + if((found = mx_find("macros.tmpl"))) + mx_expand_file(found, sink_discard(), 0); /* For unknown actions check that they aren't evil */ - for(p = name; *p && isalnum((unsigned char)*p); ++p) - ; - if(*p) + if(!dcgi_valid_action(name)) fatal(0, "invalid action name '%s'", name); byte_xasprintf((char **)&p, "%s.tmpl", name); - if(mx_expand_file(p, sink_stdio("stdout", stdout), 0) == -1 + if(!(found = mx_find(p))) + fatal(errno, "cannot find %s", p); + if(mx_expand_file(found, sink_stdio("stdout", stdout), 0) == -1 || fflush(stdout) < 0) fatal(errno, "error writing to stdout"); } @@ -220,12 +244,8 @@ void dcgi_action(const char *action) { } /** @brief Generate an error page */ -void dcgi_error(const char *msg, ...) { - va_list ap; - - va_start(ap, msg); - byte_xvasprintf(&dcgi_error_string, msg, ap); - va_end(ap); +void dcgi_error(const char *key) { + dcgi_error_string = xstrdup(key); dcgi_expand("error"); }