Commit 00c1eff2 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add attribute parsing


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2169 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 5a8a6b7d
......@@ -41,6 +41,7 @@
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
......@@ -75,10 +76,63 @@ struct esi_work {
};
/*--------------------------------------------------------------------
* Add ESI bit to object
* Report a parsing error
*/
static void
esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
{
int ellipsis = 0;
char buf[256], *q;
txt t;
if (i == 0)
i = p - ((char *)ew->st->ptr + ew->st->len);
if (i > 20) {
i = 20;
ellipsis = 1;
}
q = buf;
q += sprintf(buf, "at %zd: %s \"",
ew->off + (p - (char*)ew->st->ptr), err);
while (i > 0) {
if (*p >= ' ' && *p <= '~') {
*q++ = *p;
} else if (*p == '\n') {
*q++ = '\\';
*q++ = 'n';
} else if (*p == '\r') {
*q++ = '\\';
*q++ = 'r';
} else if (*p == '\t') {
*q++ = '\\';
*q++ = 't';
} else {
/* XXX: use %%%02x instead ? */
q += sprintf(q, "\\x%02x", *p);
}
p++;
i--;
}
if (ellipsis) {
*q++ = '[';
*q++ = '.';
*q++ = '.';
*q++ = '.';
*q++ = ']';
}
*q++ = '"';
*q++ = '\0';
t.b = buf;
t.e = q;
WSPR(ew->sp, SLT_ESI_xmlerror, t);
}
/*--------------------------------------------------------------------
* Add ESI bit to object
*/
static struct esi_bit *
esi_addbit(struct esi_work *ew)
{
......@@ -99,6 +153,7 @@ printf("ADD %p->%p\n", ew->sp->obj, ew->eb);
ew->eb->verbatim = ew->dst;
sprintf(ew->eb->chunk_length, "%x\r\n", Tlen(ew->dst));
VSL(SLT_Debug, ew->sp->fd, "AddBit: %.*s", Tlen(ew->dst), ew->dst.b);
return(ew->eb);
}
......@@ -116,69 +171,101 @@ esi_addverbatim(struct esi_work *ew, txt t)
}
/*--------------------------------------------------------------------
* Add one piece to the output, either verbatim or include
* Tease the next attribute and value out of an XML element.
*
* XXX: is the syntax correct ?
*/
static void
esi_addinclude(struct esi_work *ew, txt t)
static int
esi_attrib(const struct esi_work *ew, txt *in, txt *attrib, txt *val)
{
VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
esi_addbit(ew);
ew->eb->include = t;
/* Skip leading blanks */
while(in->b < in->e && isspace(*in->b))
in->b++;
/* Nothing found */
if (in->b >= in->e)
return (0);
if (!isalpha(*in->b)) {
/* XXX error */
esi_error(ew, in->b, 1, "XML 1.0 Illegal attribute character");
return (-1);
}
/* Attribute name until '=' or space */
*attrib = *in;
while(in->b < in->e && *in->b != '=' && !isspace(*in->b)) {
if (!isalnum(*in->b)) {
esi_error(ew, attrib->b, 1 + (in->b - attrib->b),
"XML 1.0 Illegal attribute character");
return (-1);
}
in->b++;
}
attrib->e = in->b;
if (in->b >= in->e || isspace(*in->b)) {
/* Attribute without value */
val->b = val->e = in->b;
return (1);
}
/* skip '=' */
in->b++;
/* Value, if any ? */
*val = *in;
if (in->b >= in->e)
return (1);
if (*in->b == '"') {
/* Skip quote */
in->b++;
val->b++;
/* Anything goes, until next quote */
while(in->b < in->e && *in->b != '"')
in->b++;
val->e = in->b;
if (in->b >= in->e) {
esi_error(ew, val->b, in->e - val->b,
"XML 1.0 missing ending quote");
return (-1);
}
/* Skip quote */
in->b++;
} else {
/* Anything until whitespace */
while(in->b < in->e && !isspace(*in->b))
in->b++;
val->e = in->b;
}
return (1);
}
/*--------------------------------------------------------------------
* Report a parsing error
* Add one piece to the output, either verbatim or include
*/
static void
esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
esi_addinclude(struct esi_work *ew, txt t)
{
int ellipsis = 0;
char buf[256], *q;
txt t;
if (i == 0)
i = p - ((char *)ew->st->ptr + ew->st->len);
if (i > 20) {
i = 20;
ellipsis = 1;
}
q = buf;
q += sprintf(buf, "at %zd: %s \"",
ew->off + (p - (char*)ew->st->ptr), err);
while (i > 0) {
if (*p >= ' ' && *p <= '~') {
*q++ = *p;
} else if (*p == '\n') {
*q++ = '\\';
*q++ = 'n';
} else if (*p == '\r') {
*q++ = '\\';
*q++ = 'r';
} else if (*p == '\t') {
*q++ = '\\';
*q++ = 't';
} else {
/* XXX: use %%%02x instead ? */
q += sprintf(q, "\\x%02x", *p);
}
p++;
i--;
}
if (ellipsis) {
*q++ = '[';
*q++ = '.';
*q++ = '.';
*q++ = '.';
*q++ = ']';
struct esi_bit *eb;
txt tag;
txt cont;
eb = esi_addbit(ew);
while (esi_attrib(ew, &t, &tag, &cont) == 1) {
VSL(SLT_Debug, 0, "<%.*s> -> <%.*s>",
tag.e - tag.b, tag.b,
cont.e - cont.b, cont.b);
}
*q++ = '"';
*q++ = '\0';
t.b = buf;
t.e = q;
WSPR(ew->sp, SLT_ESI_xmlerror, t);
eb->include = t;
VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
}
/*--------------------------------------------------------------------
......@@ -366,12 +453,14 @@ esi_parse(struct esi_work *ew)
if (celem == 0) {
o.b = r + 11;
o.e = q;
esi_addinclude(ew, o);
if (q[-1] != '/') {
esi_error(ew, p, 1 + q - p,
"ESI 1.0 wants emtpy esi:include");
o.e = q;
} else {
o.e = q - 1;
}
esi_addinclude(ew, o);
ew->dst.b = q + 1;
ew->dst.e = q + 1;
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment