This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 593915c4b899b80be8984f33ff7093b63ef7e1b2
Author: Bryan Call <[email protected]>
AuthorDate: Mon Apr 13 13:57:24 2026 -0700

    Fix prev_is_cr flag handling in chunked encoding parser (#13036)
    
    The prev_is_cr flag in ChunkedHandler::read_size() was being set
    within conditional expressions but not consistently updated, which
    could cause it to retain stale values across parsing iterations.
    
    Update the flag at the end of each loop iteration to ensure it
    accurately reflects the current character state. This improves the
    correctness of line break validation when parsing chunked transfer
    encoding with strict_chunk_parsing enabled.
    
    (cherry picked from commit 234bb4a2b7c999a2f573614f56ba7e0b38c017d5)
---
 src/proxy/http/HttpTunnel.cc                         | 12 +++++++++---
 .../chunked_encoding/bad_chunked_encoding.test.py    |  2 ++
 .../replays/malformed_chunked_header.replay.yaml     | 20 ++++++++++++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/proxy/http/HttpTunnel.cc b/src/proxy/http/HttpTunnel.cc
index feb863cf13..3695edf87a 100644
--- a/src/proxy/http/HttpTunnel.cc
+++ b/src/proxy/http/HttpTunnel.cc
@@ -191,7 +191,7 @@ ChunkedHandler::read_size()
             done  = true;
             break;
           } else {
-            if ((prev_is_cr = ParseRules::is_cr(*tmp)) == true) {
+            if (ParseRules::is_cr(*tmp)) {
               ++num_cr;
             }
             state = ChunkedState::READ_SIZE_CRLF; // now look for CRLF
@@ -213,7 +213,7 @@ ChunkedHandler::read_size()
           done                 = true;
           num_cr               = 0;
           break;
-        } else if ((prev_is_cr = ParseRules::is_cr(*tmp)) == true) {
+        } else if (ParseRules::is_cr(*tmp)) {
           if (num_cr != 0) {
             state = ChunkedState::READ_ERROR;
             done  = true;
@@ -236,7 +236,7 @@ ChunkedHandler::read_size()
           num_digits  = 0;
           num_cr      = 0;
           state       = ChunkedState::READ_SIZE;
-        } else if ((prev_is_cr = ParseRules::is_cr(*tmp)) == true) {
+        } else if (ParseRules::is_cr(*tmp)) {
           if (num_cr != 0) {
             Dbg(dbg_ctl_http_chunk, "Found multiple CRs before chunk size");
             state = ChunkedState::READ_ERROR;
@@ -249,9 +249,15 @@ ChunkedHandler::read_size()
           done  = true;
         }
       }
+      prev_is_cr = ParseRules::is_cr(*tmp);
       tmp++;
       data_size--;
     }
+
+    if (data_size > 0) {
+      prev_is_cr = ParseRules::is_cr(*tmp);
+    }
+
     if (drop_chunked_trailers) {
       chunked_buffer->write(chunked_reader, bytes_used);
       chunked_size += bytes_used;
diff --git a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py 
b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
index 80addcef0d..5b63acf2d0 100644
--- a/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
+++ b/tests/gold_tests/chunked_encoding/bad_chunked_encoding.test.py
@@ -134,6 +134,8 @@ class MalformedChunkHeaderTest:
             "chunked body of 3 bytes for key 2 with chunk stream", "Verify 
that writing the second response failed.")
         self.server.Streams.stdout += Testers.ContainsExpression(
             "Unexpected chunked content for key 3: too small", "Verify that 
writing the third response failed.")
+        self.server.Streams.stdout += Testers.ContainsExpression(
+            "Unexpected chunked content for key 8: too small", "Verify that 
writing the sixth response failed.")
 
         # ATS should close the connection before any body gets through. 
"abcwxyz"
         # is the body sent by the client for each of these chunked cases.
diff --git 
a/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
 
b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
index 9bccd5699c..e615eeaec4 100644
--- 
a/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
+++ 
b/tests/gold_tests/chunked_encoding/replays/malformed_chunked_header.replay.yaml
@@ -158,6 +158,26 @@ sessions:
     server-response:
       status: 200
 
+- transactions:
+  - client-request:
+      method: "POST"
+      version: "1.1"
+      url: /malformed/chunk/header3
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ Transfer-Encoding, chunked ]
+        - [ uuid, 8 ]
+      content:
+        transfer: plain
+        encoding: uri
+        # chunk-size is set to 1, but no chunk-data is present.
+        data: 1%0D%0A%0D%0A0%0D%0A%0D%0A
+
+    # The connection will be dropped and this response will not go out.
+    server-response:
+      status: 200
+
   #
   # Now repeat the above two malformed chunk header tests, but on the server
   # side.

Reply via email to