tests: fix type promotion on 32-bit arches in http test code

As reported in the bug:

> On a 32-bit architecture (i386):
> 1. `chunks * chunk_size` evaluates to `unsigned int` (32-bit
>    unsigned).
> 2. Due to Usual Arithmetic Conversions in C, the signed `-1` (int)
>    operand of the ternary operator is promoted to `unsigned int`,
>    yielding `4294967295` (0xFFFFFFFF).
> 3. The ternary operator returns `4294967295` as an `unsigned int`.
> 4. This unsigned value is then assigned to `r->clength` (apr_off_t,
>    64-bit signed). Since the source is unsigned, it is zero-extended,
>    resulting in `r->clength` becoming `+4294967295`.
> 5. The subsequently executed check `if(r->clength >= 0)` evaluates to
>    true.
> 6. Inside the block, `apr_ltoa(r->pool, (long)r->clength)` casts it to
>    a 32-bit signed `long` (on 32-bit platforms), which truncates it
>    back to `-1`, formatting it as "-1" and sending the
>    "Content-Length: -1" header.
>
> On a 64-bit architecture (amd64), `size_t` is 64-bit, and `-1` (32-bit
> int) is promoted to `unsigned long` (64-bit), yielding
> `18446744073709551615`. When assigned to `r->clength` (64-bit signed),
> it wraps back to `-1`, which correctly skips the Content-Length
> generation.
>
> This type promotion mismatch can be safely fixed by avoiding the
> signed/unsigned mixture in the ternary operator.

Origin: debian, https://bugs.debian.org/1140793
Bug-Debian: https://bugs.debian.org/1140793

These are standard Debian patches' trailers, I can get rid of then if you prefer.

I've tested the fix using [debusine on i386 runner](https://debusine.debian.net/debian/developers/artifact/4083252/raw/log):

> 782s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[http/1.0] PASSED [ 17%]
> 782s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[http/1.1] PASSED [ 18%]
> 782s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[h2] PASSED [ 18%]

Versus the [i386 run in Debian's infrastructure](https://debusine.debian.net/debian/developers/artifact/4084220/raw/log):

> 2690s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[http/1.0] FAILED [ 17%]
> 2690s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[http/1.1] PASSED [ 18%]
> 2690s tests/http/test_05_errors.py::TestErrors::test_05_04_unclean_tls_shutdown[h2] PASSED [ 18%]

Closes #22210
This commit is contained in:
Keng-Yu Lin 2026-06-28 17:43:01 -03:00 committed by Viktor Szakats
parent 1128177a6f
commit 703a999602
No known key found for this signature in database

View file

@ -404,7 +404,10 @@ static int curltest_tweak_handler(request_rec *r)
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "error_handler: processing "
"request, %s", r->args? r->args : "(no args)");
r->status = http_status;
r->clength = with_cl ? (chunks * chunk_size) : -1;
if(with_cl)
r->clength = (apr_off_t)chunks * chunk_size;
else
r->clength = -1;
r->chunked = (r->proto_num >= HTTP_VERSION(1, 1)) && !with_cl;
apr_table_setn(r->headers_out, "request-id", request_id);
if(r->clength >= 0) {