You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2023/12/13 08:23:50 UTC

(httpcomponents-core) 23/37: HTTPCORE-756: replace CR, LF, NULL in header values with SP per RFC 9110 section 5.5

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

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit d1f1e33bd65d245741ed79b1314ce623b8ccf5a8
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Oct 1 13:39:02 2023 +0200

    HTTPCORE-756: replace CR, LF, NULL in header values with SP per RFC 9110 section 5.5
---
 .../main/java/org/apache/hc/core5/http/Chars.java  |  1 +
 .../hc/core5/http/message/BufferedHeader.java      | 25 +++++++++++++++++++++-
 .../hc/core5/http/message/TestBufferedHeader.java  | 22 +++++++++++++++++++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/Chars.java b/httpcore5/src/main/java/org/apache/hc/core5/http/Chars.java
index 355aaefcc..7b1a35e2d 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/Chars.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/Chars.java
@@ -34,6 +34,7 @@ package org.apache.hc.core5.http;
  */
 public final class Chars {
 
+    public static final int NULL = 0; // <US-ASCII NUL, null (0)>
     public static final int CR = 13; // <US-ASCII CR, carriage return (13)>
     public static final int LF = 10; // <US-ASCII LF, linefeed (10)>
     public static final int SP = 32; // <US-ASCII SP, space (32)>
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BufferedHeader.java b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BufferedHeader.java
index 6148e09d9..8e73ecf9c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/message/BufferedHeader.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/message/BufferedHeader.java
@@ -29,6 +29,7 @@ package org.apache.hc.core5.http.message;
 
 import java.io.Serializable;
 
+import org.apache.hc.core5.http.Chars;
 import org.apache.hc.core5.http.FormattedHeader;
 import org.apache.hc.core5.http.ParseException;
 import org.apache.hc.core5.util.Args;
@@ -60,6 +61,8 @@ public class BufferedHeader implements FormattedHeader, Serializable {
      */
     private final int valuePos;
 
+    private String value;
+
     /**
      * @since 5.0
      */
@@ -110,7 +113,27 @@ public class BufferedHeader implements FormattedHeader, Serializable {
 
     @Override
     public String getValue() {
-        return this.buffer.substringTrimmed(this.valuePos, this.buffer.length());
+        if (value == null) {
+            int beginIdx = valuePos;
+            int endIdx = buffer.length();
+            while (beginIdx < buffer.length() && Tokenizer.isWhitespace(buffer.charAt(beginIdx))) {
+                beginIdx++;
+            }
+            while (endIdx > beginIdx && Tokenizer.isWhitespace(buffer.charAt(endIdx - 1))) {
+                endIdx--;
+            }
+            final StringBuilder buf = new StringBuilder(endIdx - beginIdx);
+            for (int i = beginIdx; i < endIdx; i++) {
+                final char ch = buffer.charAt(i);
+                if (ch == Chars.CR || ch == Chars.LF || ch == Chars.NULL) {
+                    buf.append((char) Chars.SP);
+                } else {
+                    buf.append(ch);
+                }
+            }
+            value = buf.toString();
+        }
+        return value;
     }
 
     @Override
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBufferedHeader.java b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBufferedHeader.java
index 2fd8ccbe7..425bd8521 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBufferedHeader.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestBufferedHeader.java
@@ -97,5 +97,27 @@ public class TestBufferedHeader {
         Assertions.assertThrows(ParseException.class, () -> new BufferedHeader(buf, true));
     }
 
+    @Test
+    public void testCRLFNullInHeaderValue() throws Exception {
+        final CharArrayBuffer buf = new CharArrayBuffer(16);
+        buf.clear();
+        buf.append("name:  blah\0blah  ");
+        final BufferedHeader header1 = new BufferedHeader(buf, false);
+        Assertions.assertEquals("name", header1.getName());
+        Assertions.assertEquals("blah blah", header1.getValue());
+
+        buf.clear();
+        buf.append("name:  blah\rblah  ");
+        final BufferedHeader header2 = new BufferedHeader(buf, false);
+        Assertions.assertEquals("name", header2.getName());
+        Assertions.assertEquals("blah blah", header2.getValue());
+
+        buf.clear();
+        buf.append("name:  blah\nblah  ");
+        final BufferedHeader header3 = new BufferedHeader(buf, false);
+        Assertions.assertEquals("name", header3.getName());
+        Assertions.assertEquals("blah blah", header3.getValue());
+    }
+
 }