[nginx] Charset: fixed reuse of buffers without associated memory.
Maxim Dounin
mdounin at mdounin.ru
Tue May 19 02:46:31 UTC 2026
details: http://freenginx.org/hg/nginx/rev/317eafac071e
branches:
changeset: 9520:317eafac071e
user: Maxim Dounin <mdounin at mdounin.ru>
date: Tue May 19 01:56:29 2026 +0300
description:
Charset: fixed reuse of buffers without associated memory.
Previously, in ngx_http_charset_body_filter() buffers with b->pos set
were assumed to have an associated memory allocation and were saved to
the ctx->free_buffers list. However, b->pos is set in all buffers,
including ones without associated memory. This was safe, since such
buffers were ignored by ngx_http_charset_get_buffer(), yet reuse of such
buffers via ngx_http_charset_get_buf() was broken.
The fix is to check b->start instead in ngx_http_charset_body_filter().
To make sure cached buffers can actually be used, various internal
fields are now properly cleared when using cached buffers.
Also, b->sync is now properly cleared in cached buffers returned by
ngx_http_charset_get_buffer(). And b->pos of the known-to-be-empty sync
buffer allocated in ngx_http_charset_recode_from_utf8() is set to
b->last, to avoid unexpected sizes shown in logs.
diffstat:
src/http/modules/ngx_http_charset_filter_module.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
diffs (55 lines):
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -630,7 +630,7 @@ ngx_http_charset_body_filter(ngx_http_re
b->shadow->pos = b->shadow->last;
}
- if (b->pos) {
+ if (b->start) {
cl->next = ctx->free_buffers;
ctx->free_buffers = cl;
continue;
@@ -821,7 +821,7 @@ ngx_http_charset_recode_from_utf8(ngx_po
b = out->buf;
- b->pos = buf->pos;
+ b->pos = buf->last;
b->last = buf->last;
b->sync = 1;
b->shadow = buf;
@@ -1094,15 +1094,23 @@ recode:
static ngx_chain_t *
ngx_http_charset_get_buf(ngx_pool_t *pool, ngx_http_charset_ctx_t *ctx)
{
+ ngx_buf_t *b;
ngx_chain_t *cl;
cl = ctx->free_bufs;
if (cl) {
ctx->free_bufs = cl->next;
+ cl->next = NULL;
- cl->buf->shadow = NULL;
- cl->next = NULL;
+ b = cl->buf;
+
+ b->temporary = 0;
+ b->memory = 0;
+ b->mmap = 0;
+ b->flush = 0;
+ b->sync = 0;
+ b->shadow = NULL;
return cl;
}
@@ -1144,6 +1152,7 @@ ngx_http_charset_get_buffer(ngx_pool_t *
b->pos = b->start;
b->temporary = 1;
+ b->sync = 0;
b->shadow = NULL;
return cl;
More information about the nginx-devel
mailing list