diff -upr tomcat-9.0.10_back/java/org/apache/coyote/http11/Http11InputBuffer.java tomcat-9.0.10/java/org/apache/coyote/http11/Http11InputBuffer.java
--- tomcat-9.0.10_back/java/org/apache/coyote/http11/Http11InputBuffer.java     2022-12-14 10:39:12.917000000 +0800
+++ tomcat-9.0.10/java/org/apache/coyote/http11/Http11InputBuffer.java  2022-12-14 10:48:31.180863424 +0800
@@ -821,7 +821,7 @@ public class Http11InputBuffer implement
                 headerData.lastSignificantChar = pos;
                 byteBuffer.position(byteBuffer.position() - 1);
                 // skipLine() will handle the error
-                return skipLine();
+                return skipLine(false);
             }
 
             // chr is next byte of header name. Convert to lowercase.
@@ -832,7 +832,7 @@ public class Http11InputBuffer implement
 
         // Skip the line and ignore the header
         if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) {
-            return skipLine();
+            return skipLine(false);
         }
 
         //
@@ -883,15 +883,11 @@ public class Http11InputBuffer implement
                     } else if (prevChr == Constants.CR && chr == Constants.LF) {
                         eol = true;
                     } else if (prevChr == Constants.CR) {
-                        // Invalid value
-                        // Delete the header (it will be the most recent one)
-                        headers.removeHeader(headers.size() - 1);
-                        return skipLine();
+                        // Invalid value - also need to delete header
+                        return skipLine(true);
                     } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
-                        // Invalid value
-                        // Delete the header (it will be the most recent one)
-                        headers.removeHeader(headers.size() - 1);
-                        return skipLine();
+                        // Invalid value - also need to delete header
+                        return skipLine(true);
                     } else if (chr == Constants.SP || chr == Constants.HT) {
                         byteBuffer.put(headerData.realPos, chr);
                         headerData.realPos++;
@@ -939,7 +935,27 @@ public class Http11InputBuffer implement
     }
 
 
-    private HeaderParseStatus skipLine() throws IOException {
+    private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException {
+        boolean rejectThisHeader = rejectIllegalHeader;
+        // Check if rejectIllegalHeader is disabled and needs to be overridden
+        // for this header. The header name is required to determine if this
+        // override is required. The header name is only available once the
+        // header has been created. If the header has been created then
+        // deleteHeader will be true.
+        if (!rejectThisHeader && deleteHeader) {
+            if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) {
+                // Malformed content-length headers must always be rejected
+                // RFC 9112, section 6.3, bullet 5.
+                rejectThisHeader = true;
+            } else {
+                // Only need to delete the header if the request isn't going to
+                // be rejected (it will be the most recent one)
+                headers.removeHeader(headers.size() - 1);
+            }
+        }
+
+        // Parse the rest of the invalid header so we can construct a useful
+        // exception and/or debug message.
         headerParsePos = HeaderParsePosition.HEADER_SKIPLINE;
         boolean eol = false;
 
@@ -967,12 +983,12 @@ public class Http11InputBuffer implement
                 headerData.lastSignificantChar = pos;
             }
         }
-        if (rejectIllegalHeader || log.isDebugEnabled()) {
+        if (rejectThisHeader || log.isDebugEnabled()) {
             String message = sm.getString("iib.invalidheader",
                     new String(byteBuffer.array(), headerData.start,
                             headerData.lastSignificantChar - headerData.start + 1,
                             StandardCharsets.ISO_8859_1));
-            if (rejectIllegalHeader) {
+            if (rejectThisHeader) {
                 throw new IllegalArgumentException(message);
             }
             log.debug(message);
diff -upr tomcat-9.0.10_back/test/org/apache/coyote/http11/TestHttp11InputBuffer.java tomcat-9.0.10/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
--- tomcat-9.0.10_back/test/org/apache/coyote/http11/TestHttp11InputBuffer.java 2022-12-14 10:39:12.971000000 +0800
+++ tomcat-9.0.10/test/org/apache/coyote/http11/TestHttp11InputBuffer.java 2022-12-14 10:51:16.845501479 +0800
@@ -643,6 +643,38 @@ public class TestHttp11InputBuffer exten
         Assert.assertTrue(client.isResponseBodyOK());
     }
 
+    @Test
+    public void testInvalidContentLength01() {
+        doTestInvalidContentLength(false);
+    }
+
+
+    @Test
+    public void testInvalidContentLength02() {
+        doTestInvalidContentLength(true);
+    }
+
+
+    private void doTestInvalidContentLength(boolean rejectIllegalHeader) {
+        getTomcatInstance().getConnector().setProperty("rejectIllegalHeader", Boolean.toString(rejectIllegalHeader));
+
+        String[] request = new String[1];
+        request[0] =
+                "POST /test HTTP/1.1" + CRLF +
+                "Host: localhost:8080" + CRLF +
+                "Content-Length: 12\u000734" + CRLF +
+                "Connection: close" + CRLF +
+                CRLF;
+
+        InvalidClient client = new InvalidClient(request);
+
+        client.doRequest();
+        Assert.assertTrue(client.getResponseLine(), client.isResponse400());
+        Assert.assertTrue(client.isResponseBodyOK());
+    }
+
+
+
 
     /**
      * Bug 48839 test client.
