Skip to content
Snippets Groups Projects
Unverified Commit 43e70f35 authored by Matthias Schiffer's avatar Matthias Schiffer
Browse files

gluon-web: handle translation and escaping in generated Lua code

By emitting Lua code to call translate() and pcdata(), we are more
flexible than when doing this internally in the parser. The performance
penalty should be negligible.
parent 933cc3d7
No related branches found
No related tags found
No related merge requests found
...@@ -72,15 +72,15 @@ struct template_parser { ...@@ -72,15 +72,15 @@ struct template_parser {
/* leading and trailing code for different types */ /* leading and trailing code for different types */
static const char *const gen_code[][2] = { static const char *const gen_code[][2] = {
[T_TYPE_INIT] = {NULL, NULL}, [T_TYPE_INIT] = {NULL, NULL},
[T_TYPE_TEXT] = {"write('", "')"}, [T_TYPE_TEXT] = {"write('", "')"},
[T_TYPE_COMMENT] = {NULL, NULL}, [T_TYPE_COMMENT] = {NULL, NULL},
[T_TYPE_EXPR] = {"write(tostring(", " or ''))"}, [T_TYPE_EXPR] = {"write(tostring(", " or ''))"},
[T_TYPE_INCLUDE] = {"include('", "')"}, [T_TYPE_INCLUDE] = {"include('", "')"},
[T_TYPE_I18N] = {"write('", "')"}, [T_TYPE_I18N] = {"write(pcdata(translate('", "')))"},
[T_TYPE_I18N_RAW] = {"write('", "')"}, [T_TYPE_I18N_RAW] = {"write(translate('", "'))"},
[T_TYPE_CODE] = {NULL, " "}, [T_TYPE_CODE] = {NULL, " "},
[T_TYPE_EOF] = {NULL, NULL}, [T_TYPE_EOF] = {NULL, NULL},
}; };
static struct template_parser * template_init(struct template_parser *parser) static struct template_parser * template_init(struct template_parser *parser)
...@@ -241,6 +241,28 @@ static void template_code(struct template_parser *parser, const char *e) ...@@ -241,6 +241,28 @@ static void template_code(struct template_parser *parser, const char *e)
parser->cur_chunk.e = e; parser->cur_chunk.e = e;
} }
static void luastr_escape(struct template_buffer *out, const char *s, const char *e)
{
for (const char *ptr = s; ptr < e; ptr++) {
switch (*ptr) {
case '\\':
buf_append(out, "\\\\", 2);
break;
case '\'':
buf_append(out, "\\\'", 2);
break;
case '\n':
buf_append(out, "\\n", 2);
break;
default:
buf_putchar(out, *ptr);
}
}
}
static struct template_buffer * template_format_chunk(struct template_parser *parser) static struct template_buffer * template_format_chunk(struct template_parser *parser)
{ {
const char *p; const char *p;
...@@ -266,7 +288,10 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa ...@@ -266,7 +288,10 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa
switch (c->type) { switch (c->type) {
case T_TYPE_TEXT: case T_TYPE_TEXT:
luastr_escape(buf, c->s, c->e - c->s, false); case T_TYPE_INCLUDE:
case T_TYPE_I18N:
case T_TYPE_I18N_RAW:
luastr_escape(buf, c->s, c->e);
break; break;
case T_TYPE_EXPR: case T_TYPE_EXPR:
...@@ -275,18 +300,6 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa ...@@ -275,18 +300,6 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa
parser->line += (*p == '\n'); parser->line += (*p == '\n');
break; break;
case T_TYPE_INCLUDE:
luastr_escape(buf, c->s, c->e - c->s, false);
break;
case T_TYPE_I18N:
luastr_translate(buf, c->s, c->e - c->s, true);
break;
case T_TYPE_I18N_RAW:
luastr_translate(buf, c->s, c->e - c->s, false);
break;
case T_TYPE_CODE: case T_TYPE_CODE:
buf_append(buf, c->s, c->e - c->s); buf_append(buf, c->s, c->e - c->s);
for (p = c->s; p < c->e; p++) for (p = c->s; p < c->e; p++)
......
...@@ -66,7 +66,7 @@ static bool buf_grow(struct template_buffer *buf, size_t len) ...@@ -66,7 +66,7 @@ static bool buf_grow(struct template_buffer *buf, size_t len)
} }
/* put one char into buffer object */ /* put one char into buffer object */
static bool buf_putchar(struct template_buffer *buf, char c) bool buf_putchar(struct template_buffer *buf, char c)
{ {
if (!buf_grow(buf, 1)) if (!buf_grow(buf, 1))
return false; return false;
...@@ -311,53 +311,3 @@ char * pcdata(const char *s, size_t l, size_t *outl) ...@@ -311,53 +311,3 @@ char * pcdata(const char *s, size_t l, size_t *outl)
*outl = buf_length(buf); *outl = buf_length(buf);
return buf_destroy(buf); return buf_destroy(buf);
} }
void luastr_escape(struct template_buffer *out, const char *s, size_t l, bool escape_xml)
{
int esl;
char esq[8];
const char *ptr;
for (ptr = s; ptr < (s + l); ptr++) {
switch (*ptr) {
case '\\':
buf_append(out, "\\\\", 2);
break;
case '\'':
if (escape_xml)
buf_append(out, "&#39;", 5);
else
buf_append(out, "\\\'", 2);
break;
case '\n':
buf_append(out, "\\n", 2);
break;
case '"':
case '&':
case '<':
case '>':
if (escape_xml) {
esl = snprintf(esq, sizeof(esq), "&#%i;", *ptr);
buf_append(out, esq, esl);
break;
}
default:
buf_putchar(out, *ptr);
}
}
}
void luastr_translate(struct template_buffer *out, const char *s, size_t l, bool escape_xml)
{
char *tr;
size_t trlen;
if (lmo_translate(s, l, &tr, &trlen))
luastr_escape(out, tr, trlen, escape_xml);
else
luastr_escape(out, s, l, escape_xml);
}
...@@ -32,6 +32,7 @@ struct template_buffer { ...@@ -32,6 +32,7 @@ struct template_buffer {
}; };
struct template_buffer * buf_init(size_t size); struct template_buffer * buf_init(size_t size);
bool buf_putchar(struct template_buffer *buf, char c);
bool buf_append(struct template_buffer *buf, const char *s, size_t len); bool buf_append(struct template_buffer *buf, const char *s, size_t len);
char * buf_destroy(struct template_buffer *buf); char * buf_destroy(struct template_buffer *buf);
...@@ -44,7 +45,4 @@ static inline size_t buf_length(struct template_buffer *buf) ...@@ -44,7 +45,4 @@ static inline size_t buf_length(struct template_buffer *buf)
char * pcdata(const char *s, size_t l, size_t *outl); char * pcdata(const char *s, size_t l, size_t *outl);
void luastr_escape(struct template_buffer *out, const char *s, size_t l, bool escape_xml);
void luastr_translate(struct template_buffer *out, const char *s, size_t l, bool escape_xml);
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment