[PATCH 04 of 10] Charset: fixed reuse of buffers without associated memory
Maxim Dounin
mdounin at mdounin.ru
Sun May 17 00:12:37 UTC 2026
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1778975065 -10800
# Sun May 17 02:44:25 2026 +0300
# Node ID 7dca2cab958f44f580af78bef97bc0037032d7f4
# Parent 52d992b6a7d5e79107616f948fed273a69fb7d53
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.
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