Skip to content

Commit

Permalink
Filter characters before byte conversion (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
vismayku authored and ok2c committed Sep 15, 2023
1 parent 0b126ee commit f255736
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.hc.core5.http.nio.SessionOutputBuffer;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.CharArrayBuffer;
import org.apache.hc.core5.util.TextUtils;

class SessionOutputBufferImpl extends ExpandableBuffer implements SessionOutputBuffer {

Expand Down Expand Up @@ -171,12 +172,14 @@ public void writeLine(final CharArrayBuffer lineBuffer) throws CharacterCodingEx
final int off = buffer().position();
final int arrayOffset = buffer().arrayOffset();
for (int i = 0; i < len; i++) {
b[arrayOffset + off + i] = (byte) lineBuffer.charAt(i);
final int c = lineBuffer.charAt(i);
b[arrayOffset + off + i] = TextUtils.castAsByte(c);
}
buffer().position(off + len);
} else {
for (int i = 0; i < lineBuffer.length(); i++) {
buffer().put((byte) lineBuffer.charAt(i));
final int c = lineBuffer.charAt(i);
buffer().put(TextUtils.castAsByte(c));
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,7 @@ public void append(final char[] b, final int off, final int len) {
}

for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
final int c = b[i1];
if ((c >= 0x20 && c <= 0x7E) || // Visible ASCII
(c >= 0xA0 && c <= 0xFF) || // Visible ISO-8859-1
c == 0x09) { // TAB
this.array[i2] = (byte) c;
} else {
this.array[i2] = '?';
}
this.array[i2] = TextUtils.castAsByte(b[i1]);
}
this.len = newlen;
}
Expand Down
19 changes: 19 additions & 0 deletions httpcore5/src/main/java/org/apache/hc/core5/util/TextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

import java.util.Locale;

import org.apache.hc.core5.annotation.Internal;

/**
* @since 4.3
*/
Expand Down Expand Up @@ -141,4 +143,21 @@ public static String toLowerCase(final String s) {
return s.toLowerCase(Locale.ROOT);
}

/**
* Casts character to byte filtering non-visible and non-ASCII characters
* before conversion
*
* @since 5.2
*/
@Internal
public static byte castAsByte(final int c) {
if ((c >= 0x20 && c <= 0x7E) || // Visible ASCII
(c >= 0xA0 && c <= 0xFF) || // Visible ISO-8859-1
c == 0x09) { // TAB
return (byte) c;
} else {
return '?';
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,34 @@ public void testWriteLineChunks() throws Exception {
Assertions.assertEquals("One\r\nTwo\r\nThree\r\nFour\r\n", s);
}

@Test
public void testNonASCIIWriteLine() throws Exception {
final String testString = "123\u010Anew-header-from-some-header:injected-value";
final String expectedResult = "123?new-header-from-some-header:injected-value";

final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16);

chbuffer.clear();
chbuffer.append(testString);
outbuf.writeLine(chbuffer);

//this write operation should have no effect
outbuf.writeLine(null);

final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final WritableByteChannel outChannel = newChannel(outStream);
outbuf.flush(outChannel);

final ReadableByteChannel channel = newChannel(outStream.toByteArray());

final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, 0);
inbuf.fill(channel);
chbuffer.clear();
inbuf.readLine(chbuffer, true);
Assertions.assertEquals(expectedResult, chbuffer.toString());
}

@Test
public void testBasicReadWriteLine() throws Exception {

Expand Down

0 comments on commit f255736

Please sign in to comment.