summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_string.c61
-rw-r--r--src/core/ngx_string.h2
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c70
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.h18
4 files changed, 144 insertions, 7 deletions
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 6b37e8046..45079b706 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1305,6 +1305,67 @@ done:
}
+uintptr_t
+ngx_escape_html(u_char *dst, u_char *src, size_t size)
+{
+ u_char ch;
+ ngx_uint_t i, len;
+
+ if (dst == NULL) {
+
+ len = 0;
+
+ for (i = 0; i < size; i++) {
+ switch (*src++) {
+
+ case '<':
+ len += sizeof("&lt;") - 2;
+ break;
+
+ case '>':
+ len += sizeof("&gt;") - 2;
+ break;
+
+ case '&':
+ len += sizeof("&amp;") - 2;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return (uintptr_t) len;
+ }
+
+ for (i = 0; i < size; i++) {
+ ch = *src++;
+
+ switch (ch) {
+
+ case '<':
+ *dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';';
+ break;
+
+ case '>':
+ *dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';';
+ break;
+
+ case '&':
+ *dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p';
+ *dst++ = ';';
+ break;
+
+ default:
+ *dst++ = ch;
+ break;
+ }
+ }
+
+ return (uintptr_t) dst;
+}
+
+
/* ngx_sort() is implemented as insertion sort because we need stable sort */
void
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index a1da15f6b..e17fc13fb 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -165,6 +165,8 @@ u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
ngx_uint_t type);
void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
+uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
+
void ngx_sort(void *base, size_t n, size_t size,
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 0de03aae0..c1adbad75 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -212,6 +212,7 @@ static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;
#define NGX_HTTP_SSI_ECHO_VAR 0
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
+#define NGX_HTTP_SSI_ECHO_ENCODING 2
#define NGX_HTTP_SSI_CONFIG_ERRMSG 0
#define NGX_HTTP_SSI_CONFIG_TIMEFMT 1
@@ -237,6 +238,7 @@ static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
{ ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },
+ { ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },
{ ngx_null_string, 0, 0, 0 }
};
@@ -355,6 +357,7 @@ found:
ctx->value_len = slcf->value_len;
ctx->last_out = &ctx->out;
+ ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
ctx->output = 1;
ctx->params.elts = ctx->params_array;
@@ -2119,10 +2122,12 @@ static ngx_int_t
ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t **params)
{
+ u_char *p;
+ uintptr_t len;
ngx_int_t key;
ngx_uint_t i;
ngx_buf_t *b;
- ngx_str_t *var, *value, text;
+ ngx_str_t *var, *value, *enc, text;
ngx_chain_t *cl;
ngx_http_variable_value_t *vv;
@@ -2170,6 +2175,69 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
}
+ enc = params[NGX_HTTP_SSI_ECHO_ENCODING];
+
+ if (enc) {
+ if (enc->len == 4 && ngx_strncmp(enc->data, "none", 4) == 0) {
+
+ ctx->encoding = NGX_HTTP_SSI_NO_ENCODING;
+
+ } else if (enc->len == 3 && ngx_strncmp(enc->data, "url", 3) == 0) {
+
+ ctx->encoding = NGX_HTTP_SSI_URL_ENCODING;
+
+ } else if (enc->len == 6 && ngx_strncmp(enc->data, "entity", 6) == 0) {
+
+ ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
+
+ } else {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "unknown encoding \"%V\" in the \"echo\" command",
+ enc);
+ }
+ }
+
+ switch (ctx->encoding) {
+
+ case NGX_HTTP_SSI_NO_ENCODING:
+ break;
+
+ case NGX_HTTP_SSI_URL_ENCODING:
+ len = 2 * ngx_escape_uri(NULL, value->data, value->len,
+ NGX_ESCAPE_HTML);
+
+ if (len) {
+ p = ngx_palloc(r->pool, value->len + len);
+ if (p == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
+
+ value->len += len;
+ value->data = p;
+ }
+
+ break;
+
+ case NGX_HTTP_SSI_ENTITY_ENCODING:
+ len = ngx_escape_html(NULL, value->data, value->len);
+
+ if (len) {
+ p = ngx_palloc(r->pool, value->len + len);
+ if (p == NULL) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ (void) ngx_escape_html(p, value->data, value->len);
+
+ value->len += len;
+ value->data = p;
+ }
+
+ break;
+ }
+
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_HTTP_SSI_ERROR;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h
index 915d89073..6ab18841c 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.h
+++ b/src/http/modules/ngx_http_ssi_filter_module.h
@@ -13,15 +13,20 @@
#include <ngx_http.h>
-#define NGX_HTTP_SSI_MAX_PARAMS 16
+#define NGX_HTTP_SSI_MAX_PARAMS 16
-#define NGX_HTTP_SSI_COMMAND_LEN 32
-#define NGX_HTTP_SSI_PARAM_LEN 32
-#define NGX_HTTP_SSI_PARAMS_N 4
+#define NGX_HTTP_SSI_COMMAND_LEN 32
+#define NGX_HTTP_SSI_PARAM_LEN 32
+#define NGX_HTTP_SSI_PARAMS_N 4
-#define NGX_HTTP_SSI_COND_IF 1
-#define NGX_HTTP_SSI_COND_ELSE 2
+#define NGX_HTTP_SSI_COND_IF 1
+#define NGX_HTTP_SSI_COND_ELSE 2
+
+
+#define NGX_HTTP_SSI_NO_ENCODING 0
+#define NGX_HTTP_SSI_URL_ENCODING 1
+#define NGX_HTTP_SSI_ENTITY_ENCODING 2
typedef struct {
@@ -60,6 +65,7 @@ typedef struct {
ngx_array_t *blocks;
unsigned conditional:2;
+ unsigned encoding:2;
unsigned block:1;
unsigned output:1;
unsigned output_chosen:1;