Allow trailing '@' to be left out of CGI expansions in specific
[disorder] / server / cgi.c
index 5abf145..23d1020 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006, 2008 Richard Kettlewell
+ * Copyright (C) 2004-2008 Richard Kettlewell
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -152,13 +152,14 @@ static void cgi_parse_multipart(const char *boundary) {
 }
 
 static void cgi_parse_post(void) {
-  const char *ct;
-  char *q, *type, *pname, *pvalue;
+  const char *ct, *boundary;
+  char *q, *type;
   size_t n;
+  struct kvp *k;
 
   if(!(ct = getenv("CONTENT_TYPE")))
     ct = "application/x-www-form-urlencoded";
-  if(mime_content_type(ct, &type, &pname, &pvalue))
+  if(mime_content_type(ct, &type, &k))
     fatal(0, "invalid content type '%s'", ct);
   if(!strcmp(type, "application/x-www-form-urlencoded")) {
     cgi_input(&q, &n);
@@ -166,10 +167,9 @@ static void cgi_parse_post(void) {
     return;
   }
   if(!strcmp(type, "multipart/form-data")) {
-    if(!pname || strcmp(pname, "boundary"))
-      fatal(0, "expected a boundary parameter, found %s",
-           pname ? pname : "nothing");
-    cgi_parse_multipart(pvalue);
+    if(!(boundary = kvp_get(k, "boundary")))
+      fatal(0, "no boundary parameter found");
+    cgi_parse_multipart(boundary);
     return;
   }
   fatal(0, "unrecognized content type '%s'", type);
@@ -389,6 +389,9 @@ void cgi_expand_string(const char *name,
     ++template;
     sline = line;
     while(*template != '@') {
+      /* Skip whitespace */
+      while(isspace((unsigned char)*template))
+       ++template;
       dynstr_init(&d);
       if(*template == '{') {
        /* bracketed arg */
@@ -403,14 +406,18 @@ void cgi_expand_string(const char *name,
        }
        if(!*template) fatal(0, "%s:%d: unterminated expansion", name, sline);
        ++template;
-       /* skip whitespace after closing bracket */
-       while(isspace((unsigned char)*template))
-         ++template;
+       if(isspace((unsigned char)*template)) {
+         /* We have @{...}<WHITESPACE><SOMETHING> */
+         for(p = template; isspace((unsigned char)*p); ++p)
+           ;
+         /* Now we are looking at <SOMETHING>.  If it's "{" then that
+          * must be the next argument.  Otherwise we infer that this
+          * is really the end of the expansion. */
+         if(*p != '{')
+           goto finished_expansion;
+       }
       } else {
        /* unbracketed arg */
-       /* leading whitespace is not significant in unquoted args */
-       while(isspace((unsigned char)*template))
-         ++template;
        while(*template
              && *template != '@' && *template != '{' && *template != ':') {
          if(*template == '\n') ++line;
@@ -427,6 +434,7 @@ void cgi_expand_string(const char *name,
       vector_append(&v, d.vec);
     }
     ++template;
+finished_expansion:
     vector_terminate(&v);
     /* @@ terminates this file */
     if(v.nvec == 0)