X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fweb%2Fsrc%2Ftemplate_parser.c;h=a0a400bdf72558c8b5bfd06b8ca5426de678b79a;hp=58de5bb77471292c3122862f408cf40c676f5c55;hb=9fcdf0fe81f3c5142b8abd3f701dc3964549742a;hpb=80a2dd2cc27e2fc0c55f03f01a1d460a91954ab6 diff --git a/libs/web/src/template_parser.c b/libs/web/src/template_parser.c index 58de5bb77..a0a400bdf 100644 --- a/libs/web/src/template_parser.c +++ b/libs/web/src/template_parser.c @@ -20,13 +20,14 @@ /* leading and trailing code for different types */ -const char * gen_code[6][2] = { - { "write(\"", "\")" }, - { NULL, NULL }, - { "write(tostring(", "))" }, - { "include(\"", "\")" }, - { "write(translate(\"", "\"))" }, - { NULL, " " } +const char * gen_code[7][2] = { + { "write(\"", "\")" }, + { NULL, NULL }, + { "write(tostring(", " or \"\"))" }, + { "include(\"", "\")" }, + { "write(pcdata(translate(\"", "\")))" }, + { "write(translate(\"", "\"))" }, + { NULL, " " } }; /* Simple strstr() like function that takes len arguments for both haystack and needle. */ @@ -58,12 +59,12 @@ static char *strfind(char *haystack, int hslen, const char *needle, int ndlen) return NULL; } -/* - * Inspect current read buffer and find the number of "vague" characters at the end +/* + * Inspect current read buffer and find the number of "vague" characters at the end * which could indicate an opening token. Returns the number of "vague" chars. * The last continuous sequence of whitespace, optionally followed by a "<" is * treated as "vague" because whitespace may be discarded if the upcoming opening - * token indicates pre-whitespace-removal ("<%-"). A single remaining "<" char + * token indicates pre-whitespace-removal ("<%-"). A single remaining "<" char * can't be differentiated from an opening token ("<%"), so it's kept to be processed * in the next cycle. */ @@ -127,7 +128,7 @@ static const char * generate_expression(struct template_parser *data, size_t *sz int i; int size = 0; int start = 0; - int i18n_hasdef = 0; + int whitespace = 0; memset(tmp, 0, T_OUTBUFSZ); @@ -142,31 +143,35 @@ static const char * generate_expression(struct template_parser *data, size_t *sz for( i = 0; i < data->outsize; i++ ) { /* Skip leading whitespace for non-raw and non-expr chunks */ - if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) ) + if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || + data->type == T_TYPE_I18N_RAW || data->type == T_TYPE_INCLUDE) ) continue; else if( !start ) start = 1; /* Found whitespace after i18n key */ - if( (data->type == T_TYPE_I18N) && (i18n_hasdef == 1) ) + if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW ) { - /* At non-whitespace char, inject seperator token */ - if( !isspace(data->out[i]) ) + /* Is initial whitespace, insert space */ + if( !whitespace && isspace(data->out[i]) ) { - memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP)); - size += strlen(T_TOK_I18NSEP); - i18n_hasdef = 2; + tmp[size++] = ' '; + whitespace = 1; } - /* At further whitespace, skip */ - else + /* Suppress subsequent whitespace, escape special chars */ + else if( !isspace(data->out[i]) ) { - continue; + if( data->out[i] == '\\' || data->out[i] == '"' ) + tmp[size++] = '\\'; + + tmp[size++] = data->out[i]; + whitespace = 0; } } - /* Escape quotes, backslashes and newlines for plain, i18n and include expressions */ - if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) && + /* Escape quotes, backslashes and newlines for plain and include expressions */ + else if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_INCLUDE) && (data->out[i] == '\\' || data->out[i] == '"' || data->out[i] == '\n' || data->out[i] == '\t') ) { tmp[size++] = '\\'; @@ -186,12 +191,6 @@ static const char * generate_expression(struct template_parser *data, size_t *sz } } - /* Found whitespace in i18n expression, raise flag */ - else if( isspace(data->out[i]) && (data->type == T_TYPE_I18N) ) - { - i18n_hasdef = 1; - } - /* Normal char */ else { @@ -199,16 +198,14 @@ static const char * generate_expression(struct template_parser *data, size_t *sz } } - /* Processed i18n expression without default text, inject separator */ - if( (data->type == T_TYPE_I18N) && (i18n_hasdef < 2) ) - { - memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP)); - size += strlen(T_TOK_I18NSEP); - } - /* Inject trailing expression code (if any) */ if( (what & T_GEN_END) && (gen_code[data->type][1] != NULL) ) { + /* Strip trailing space for i18n expressions */ + if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW ) + if( (size > 0) && (tmp[size-1] == ' ') ) + size--; + memcpy(&tmp[size], gen_code[data->type][1], strlen(gen_code[data->type][1])); size += strlen(gen_code[data->type][1]); } @@ -403,6 +400,11 @@ const char *template_reader(lua_State *L, void *ud, size_t *sz) data->type = T_TYPE_I18N; break; + case '_': + off++; + data->type = T_TYPE_I18N_RAW; + break; + default: data->type = T_TYPE_CODE; break;