Skip to content

Commit

Permalink
Issue #9554 - add javadoc for illegal vchar methods and move to HttpT…
Browse files Browse the repository at this point in the history
…okens

Signed-off-by: Lachlan Roberts <[email protected]>
  • Loading branch information
lachlan-roberts committed May 4, 2023
1 parent 5b9f4bb commit d940e1b
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 49 deletions.
55 changes: 55 additions & 0 deletions jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,5 +231,60 @@ else if (b >= 0x80) // OBS
}
}
}

/**
* This is used when decoding to not decode illegal characters based on RFC9110.
* CR, LF, or NUL are replaced with ' ', all other control and multibyte characters
* are replaced with '?'. If this is given a legal character the same value will be returned.
*
* @param c the character to test.
* @return the original character or the replacement character ' ' or '?'.
*/
public static char sanitizeFieldVchar(char c)
{
switch (c)
{
// A recipient of CR, LF, or NUL within a field value MUST either reject the message
// or replace each of those characters with SP before further processing
case '\r':
case '\n':
case 0x00:
return ' ';

default:
if (c >= 256 || c < ' ')
return '?';
}

return c;
}

/**
* This is used when decoding to not decode illegal characters based on RFC9110.
* CR, LF, or NUL are replaced with ' ', all other control and multibyte characters
* are replaced with '?'. If this is given a legal character the same value will be returned.
*
* @param i the character to test.
* @return the original character or the replacement character ' ' or '?'.
*/
public static int sanitizeFieldVchar(int i)
{
if (i > Character.MAX_VALUE)
return '?';
return sanitizeFieldVchar((char)i);
}

/**
* Checks whether this is an invalid VCHAR based on RFC9110.
* If this not a valid ISO-8859-1 character or a control character
* we say that it is illegal.
*
* @param c the character to test.
* @return true if this is invalid VCHAR.
*/
public static boolean isIllegalFieldVchar(char c)
{
return (c >= 256 || c < ' ');
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -346,47 +346,4 @@ private Huffman()
}
}
}

public static boolean isIllegalCharacter(char c)
{
return (c >= 256 || c < ' ');
}

public static char getReplacementCharacter(char c)
{
switch (c)
{
// A recipient of CR, LF, or NUL within a field value MUST either reject the message
// or replace each of those characters with SP before further processing
case '\r':
case '\n':
case 0x00:
return ' ';

default:
if (c >= 256 || c < ' ')
return '?';
}

return c;
}

public static int getReplacementCharacter(int i)
{
switch (i)
{
// A recipient of CR, LF, or NUL within a field value MUST either reject the message
// or replace each of those characters with SP before further processing
case '\r':
case '\n':
case 0x00:
return ' ';

default:
if (i >= 256 || i < ' ')
return '?';
}

return i;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.nio.ByteBuffer;

import org.eclipse.jetty.http.HttpTokens;
import org.eclipse.jetty.util.CharsetStringBuilder;

import static org.eclipse.jetty.http.compression.Huffman.rowbits;
Expand Down Expand Up @@ -72,7 +73,7 @@ public String decode(ByteBuffer buffer) throws EncodingException

// terminal node
int i = 0xFF & rowsym[_node];
i = Huffman.getReplacementCharacter(i);
i = HttpTokens.sanitizeFieldVchar(i);
_builder.append((byte)i);
_bits -= rowbits[_node];
_node = 0;
Expand Down Expand Up @@ -107,7 +108,7 @@ public String decode(ByteBuffer buffer) throws EncodingException
}

int i = 0xFF & rowsym[_node];
i = Huffman.getReplacementCharacter(i);
i = HttpTokens.sanitizeFieldVchar(i);
_builder.append((byte)i);
_bits -= rowbits[_node];
_node = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import java.nio.ByteBuffer;

import org.eclipse.jetty.http.HttpTokens;

import static org.eclipse.jetty.http.compression.Huffman.CODES;
import static org.eclipse.jetty.http.compression.Huffman.LCCODES;

Expand Down Expand Up @@ -67,7 +69,7 @@ private static int octetsNeeded(final int[][] table, String s)
for (int i = 0; i < len; i++)
{
char c = s.charAt(i);
if (Huffman.isIllegalCharacter(c))
if (HttpTokens.isIllegalFieldVchar(c))
return -1;
needed += table[c][1];
}
Expand All @@ -88,7 +90,7 @@ private static void encode(final int[][] table, ByteBuffer buffer, String s)
for (int i = 0; i < len; i++)
{
char c = s.charAt(i);
if (Huffman.isIllegalCharacter(c))
if (HttpTokens.isIllegalFieldVchar(c))
throw new IllegalArgumentException();
int code = table[c][0];
int bits = table[c][1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTokens;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.http.compression.Huffman;
import org.eclipse.jetty.http.compression.HuffmanEncoder;
import org.eclipse.jetty.http.compression.NBitIntegerEncoder;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
Expand Down Expand Up @@ -468,7 +468,7 @@ static void encodeValue(ByteBuffer buffer, boolean huffman, String value)
for (int i = 0; i < value.length(); i++)
{
char c = value.charAt(i);
c = Huffman.getReplacementCharacter(c);
c = HttpTokens.sanitizeFieldVchar(c);
buffer.put((byte)c);
}
}
Expand Down

0 comments on commit d940e1b

Please sign in to comment.