e.ip = val->values;
e.pos = value->data;
e.buf = *value;
+ e.end = value->data + len;
while (*(uintptr_t *) e.ip) {
code = *(ngx_http_script_code_pt *) e.ip;
code((ngx_http_script_engine_t *) &e);
}
+ if (e.status) {
+ return NGX_ERROR;
+ }
+
*value = e.buf;
return NGX_OK;
e.ip = code_values;
e.pos = value->data;
+ e.end = value->data + len;
while (*(uintptr_t *) e.ip) {
code = *(ngx_http_script_code_pt *) e.ip;
code((ngx_http_script_engine_t *) &e);
}
+ if (e.status) {
+ return NULL;
+ }
+
return e.pos;
}
}
+ngx_int_t
+ngx_http_script_check_length(ngx_http_script_engine_t *e, size_t len)
+{
+ if (e->end == NULL) {
+ return NGX_OK;
+ }
+
+ if (e->end - e->pos < (ssize_t) len) {
+ ngx_log_error(NGX_LOG_ALERT, e->request->connection->log, 0,
+ "no buffer space in script copy");
+ e->ip = ngx_http_script_exit;
+ e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
static ngx_int_t
ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
ngx_uint_t last)
p = e->pos;
if (!e->skip) {
+
+ if (ngx_http_script_check_length(e, code->len) != NGX_OK) {
+ return;
+ }
+
e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_script_copy_code_t),
code->len);
}
}
if (value && !value->not_found) {
+
+ if (ngx_http_script_check_length(e, value->len) != NGX_OK) {
+ return;
+ }
+
p = e->pos;
e->pos = ngx_copy(p, value->data, value->len);
e->quote = code->redirect;
e->pos = e->buf.data;
+ e->end = e->buf.data + e->buf.len;
e->ip += sizeof(ngx_http_script_regex_code_t);
}
e->pos = dst;
if (code->add_args && r->args.len) {
+
+ if (ngx_http_script_check_length(e, r->args.len + 1) != NGX_OK) {
+ return;
+ }
+
*e->pos++ = (u_char) (code->args ? '&' : '?');
e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
}
e->buf.len = e->args - e->buf.data;
if (code->add_args && r->args.len) {
+
+ if (ngx_http_script_check_length(e, r->args.len + 1) != NGX_OK) {
+ return;
+ }
+
*e->pos++ = '&';
e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
}
int *cap;
u_char *p, *pos;
size_t len;
+ uintptr_t escape;
ngx_uint_t n;
ngx_http_request_t *r;
ngx_http_script_copy_capture_code_t *code;
if ((e->is_args || e->quote)
&& (e->request->quoted_uri || e->request->plus_in_uri))
{
+ escape = 2 * ngx_escape_uri(NULL, p, len, NGX_ESCAPE_ARGS);
+
+ if (ngx_http_script_check_length(e, len + escape) != NGX_OK) {
+ return;
+ }
+
e->pos = (u_char *) ngx_escape_uri(pos, p, len, NGX_ESCAPE_ARGS);
} else {
+
+ if (ngx_http_script_check_length(e, len) != NGX_OK) {
+ return;
+ }
+
e->pos = ngx_copy(pos, p, len);
}
}
}
e->pos = e->buf.data;
+ e->end = e->buf.data + len;
e->sp->len = e->buf.len;
e->sp->data = e->buf.data;
e.ip = val->values;
e.pos = value->data;
+ e.end = value->data + len;
e.buf = *value;
while (*(uintptr_t *) e.ip) {
code((ngx_stream_script_engine_t *) &e);
}
+ if (e.status) {
+ return NGX_ERROR;
+ }
+
*value = e.buf;
return NGX_OK;
e.ip = code_values;
e.pos = value->data;
+ e.end = value->data + len;
while (*(uintptr_t *) e.ip) {
code = *(ngx_stream_script_code_pt *) e.ip;
code((ngx_stream_script_engine_t *) &e);
}
+ if (e.status) {
+ return NULL;
+ }
+
return e.pos;
}
}
+ngx_int_t
+ngx_stream_script_check_length(ngx_stream_script_engine_t *e, size_t len)
+{
+ if (e->end == NULL) {
+ return NGX_OK;
+ }
+
+ if (e->end - e->pos < (ssize_t) len) {
+ ngx_log_error(NGX_LOG_ALERT, e->session->connection->log, 0,
+ "no buffer space in script copy");
+ e->ip = ngx_stream_script_exit;
+ e->status = NGX_STREAM_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
static ngx_int_t
ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc,
ngx_str_t *value, ngx_uint_t last)
p = e->pos;
if (!e->skip) {
+
+ if (ngx_stream_script_check_length(e, code->len) != NGX_OK) {
+ return;
+ }
+
e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t),
code->len);
}
}
if (value && !value->not_found) {
+
+ if (ngx_stream_script_check_length(e, value->len) != NGX_OK) {
+ return;
+ }
+
p = e->pos;
e->pos = ngx_copy(p, value->data, value->len);
cap = s->captures;
len = cap[n + 1] - cap[n];
p = s->captures_data + cap[n];
+
+ if (ngx_stream_script_check_length(e, len) != NGX_OK) {
+ return;
+ }
+
e->pos = ngx_copy(pos, p, len);
}
!= NGX_OK)
{
e->ip = ngx_stream_script_exit;
+ e->status = NGX_STREAM_INTERNAL_SERVER_ERROR;
return;
}