From f6b388d05bcded62082eb4e97f3e97f1b638ba1f Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sun, 27 Apr 2008 20:43:35 +0100 Subject: [PATCH] Allow trailing '@' to be left out of CGI expansions in specific circumstances. This is such a common typo it seems better to accept the result of user testing than cling to the original syntax. Organization: Straylight/Edgeware From: Richard Kettlewell --- doc/disorder_config.5.in | 12 +++++++++--- server/cgi.c | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/doc/disorder_config.5.in b/doc/disorder_config.5.in index e714a22..c9b2061 100644 --- a/doc/disorder_config.5.in +++ b/doc/disorder_config.5.in @@ -907,14 +907,20 @@ character reference, e.g. \fBý\fR. Use \fB@\fR to insert a literal \fB@\fR without falling foul of the expansion syntax. .SS "Expansion Syntax" -Expansions are surrounded by at ("@") symbols take the form of a keyword -followed by zero or more arguments. -Arguments may either be quoted by curly brackets ("{" and "}") or separated +An expansion starts with an at ("@") symbol and takes the form of an expansion +name followed by zero or more arguments. +.PP +Arguments can be quoted by curly brackets ("{" and "}") or separated by colons (":"). Both kinds may be mixed in a single expansion, though doing so seems likely to cause confusion. The descriptions below contain suggested forms for each expansion. .PP +An expansion is terminated by another "@" symbol, but this is optional in the +specific case that the last argument is quoted by curly brackets and it is +followed by whitespace and then some character that is not "{" (since that +could be interpreted as a further argument). +.PP Leading and trailing whitespace in unquoted arguments is ignored, as is whitespace (including newlines) following a close bracket ("}"). .PP diff --git a/server/cgi.c b/server/cgi.c index 2017d1b..23d1020 100644 --- a/server/cgi.c +++ b/server/cgi.c @@ -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 @{...} */ + for(p = template; isspace((unsigned char)*p); ++p) + ; + /* Now we are looking at . 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) -- [mdw]