Browse Source

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.
Matthias Schiffer 6 years ago
parent
commit
43e70f351f

+ 35 - 22
package/gluon-web/src/template_parser.c

@@ -72,15 +72,15 @@ struct template_parser {
 
 /* leading and trailing code for different types */
 static const char *const gen_code[][2] = {
-	[T_TYPE_INIT]     = {NULL,              NULL},
-	[T_TYPE_TEXT]     = {"write('",         "')"},
-	[T_TYPE_COMMENT]  = {NULL,              NULL},
-	[T_TYPE_EXPR]     = {"write(tostring(", " or ''))"},
-	[T_TYPE_INCLUDE]  = {"include('",       "')"},
-	[T_TYPE_I18N]     = {"write('",         "')"},
-	[T_TYPE_I18N_RAW] = {"write('",         "')"},
-	[T_TYPE_CODE]     = {NULL,              " "},
-	[T_TYPE_EOF]      = {NULL,              NULL},
+	[T_TYPE_INIT]     = {NULL,                        NULL},
+	[T_TYPE_TEXT]     = {"write('",                   "')"},
+	[T_TYPE_COMMENT]  = {NULL,                        NULL},
+	[T_TYPE_EXPR]     = {"write(tostring(",           " or ''))"},
+	[T_TYPE_INCLUDE]  = {"include('",                 "')"},
+	[T_TYPE_I18N]     = {"write(pcdata(translate('",  "')))"},
+	[T_TYPE_I18N_RAW] = {"write(translate('",         "'))"},
+	[T_TYPE_CODE]     = {NULL,                        " "},
+	[T_TYPE_EOF]      = {NULL,                        NULL},
 };
 
 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)
 	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)
 {
 	const char *p;
@@ -266,7 +288,10 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa
 
 		switch (c->type) {
 		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;
 
 		case T_TYPE_EXPR:
@@ -275,18 +300,6 @@ static struct template_buffer * template_format_chunk(struct template_parser *pa
 				parser->line += (*p == '\n');
 			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:
 			buf_append(buf, c->s, c->e - c->s);
 			for (p = c->s; p < c->e; p++)

+ 1 - 51
package/gluon-web/src/template_utils.c

@@ -66,7 +66,7 @@ static bool buf_grow(struct template_buffer *buf, size_t len)
 }
 
 /* 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))
 		return false;
@@ -311,53 +311,3 @@ char * pcdata(const char *s, size_t l, size_t *outl)
 	*outl = buf_length(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);
-}

+ 1 - 3
package/gluon-web/src/template_utils.h

@@ -32,6 +32,7 @@ struct template_buffer {
 };
 
 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);
 char * buf_destroy(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);
 
-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