avoid exceptions for non iso characters
Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
bc96561865
commit
90cf7c80bd
|
@ -461,6 +461,8 @@ public class HpackContext
|
||||||
if (value != null && value.length() > 0)
|
if (value != null && value.length() > 0)
|
||||||
{
|
{
|
||||||
int huffmanLen = Huffman.octetsNeeded(value);
|
int huffmanLen = Huffman.octetsNeeded(value);
|
||||||
|
if (huffmanLen < 0)
|
||||||
|
throw new IllegalStateException("bad value");
|
||||||
int lenLen = NBitInteger.octectsNeeded(7, huffmanLen);
|
int lenLen = NBitInteger.octectsNeeded(7, huffmanLen);
|
||||||
_huffmanValue = new byte[1 + lenLen + huffmanLen];
|
_huffmanValue = new byte[1 + lenLen + huffmanLen];
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(_huffmanValue);
|
ByteBuffer buffer = ByteBuffer.wrap(_huffmanValue);
|
||||||
|
|
|
@ -392,18 +392,18 @@ public class HpackEncoder
|
||||||
if (huffman)
|
if (huffman)
|
||||||
{
|
{
|
||||||
// huffman literal value
|
// huffman literal value
|
||||||
buffer.put((byte)0x80).mark();
|
buffer.put((byte)0x80);
|
||||||
|
|
||||||
try
|
int needed = Huffman.octetsNeeded(value);
|
||||||
|
if (needed >= 0)
|
||||||
{
|
{
|
||||||
NBitInteger.encode(buffer,7,Huffman.octetsNeeded(value));
|
NBitInteger.encode(buffer, 7, needed);
|
||||||
Huffman.encode(buffer,value);
|
Huffman.encode(buffer, value);
|
||||||
}
|
}
|
||||||
catch(Throwable th)
|
else
|
||||||
{
|
{
|
||||||
LOG.ignore(th);
|
// Not iso_8859_1
|
||||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
NBitInteger.encode(buffer,7,Huffman.octetsNeeded(bytes));
|
NBitInteger.encode(buffer,7,Huffman.octetsNeeded(bytes));
|
||||||
Huffman.encode(buffer,bytes);
|
Huffman.encode(buffer,bytes);
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ public class HpackEncoder
|
||||||
char c = value.charAt(i);
|
char c = value.charAt(i);
|
||||||
if (c < ' ' || c > 127)
|
if (c < ' ' || c > 127)
|
||||||
{
|
{
|
||||||
// Not iso_8859_1, so re-encode remaining as UTF-8
|
// Not iso_8859_1, so re-encode as UTF-8
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
NBitInteger.encode(buffer,7,bytes.length);
|
NBitInteger.encode(buffer,7,bytes.length);
|
||||||
|
|
|
@ -360,7 +360,7 @@ public class Huffman
|
||||||
|
|
||||||
public static String decode(ByteBuffer buffer,int length) throws HpackException.CompressionException
|
public static String decode(ByteBuffer buffer,int length) throws HpackException.CompressionException
|
||||||
{
|
{
|
||||||
Utf8StringBuilder utf8 = new Utf8StringBuilder(length*2);
|
Utf8StringBuilder utf8 = new Utf8StringBuilder(length * 2);
|
||||||
int node = 0;
|
int node = 0;
|
||||||
int current = 0;
|
int current = 0;
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
|
@ -380,7 +380,7 @@ public class Huffman
|
||||||
throw new HpackException.CompressionException("EOS in content");
|
throw new HpackException.CompressionException("EOS in content");
|
||||||
|
|
||||||
// terminal node
|
// terminal node
|
||||||
utf8.append((byte)(0xFF&rowsym[node]));
|
utf8.append((byte)(0xFF & rowsym[node]));
|
||||||
bits -= rowbits[node];
|
bits -= rowbits[node];
|
||||||
node = 0;
|
node = 0;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ public class Huffman
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
utf8.append((byte)(0xFF&rowsym[node]));
|
utf8.append((byte)(0xFF & rowsym[node]));
|
||||||
bits -= rowbits[node];
|
bits -= rowbits[node];
|
||||||
node = 0;
|
node = 0;
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,7 @@ public class Huffman
|
||||||
{
|
{
|
||||||
char c = s.charAt(i);
|
char c = s.charAt(i);
|
||||||
if (c >= 128 || c < ' ')
|
if (c >= 128 || c < ' ')
|
||||||
throw new IllegalArgumentException();
|
return -1;
|
||||||
needed += table[c][1];
|
needed += table[c][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,17 +470,23 @@ public class Huffman
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int octetsNeeded(final int[][] table,byte[] b)
|
private static int octetsNeeded(final int[][] table,byte[] b)
|
||||||
{
|
{
|
||||||
int needed=0;
|
int needed = 0;
|
||||||
int len = b.length;
|
int len = b.length;
|
||||||
for (int i=0;i<len;i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
int c=0xFF&b[i];
|
int c = 0xFF & b[i];
|
||||||
needed += table[c][1];
|
needed += table[c][1];
|
||||||
}
|
}
|
||||||
return (needed+7) / 8;
|
return (needed + 7) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param table The table to encode by
|
||||||
|
* @param buffer The buffer to encode to
|
||||||
|
* @param s The string to encode
|
||||||
|
* @return True if the string could be encoded, false otherwise (and the buffer may have been modified).
|
||||||
|
*/
|
||||||
private static void encode(final int[][] table, ByteBuffer buffer, String s)
|
private static void encode(final int[][] table, ByteBuffer buffer, String s)
|
||||||
{
|
{
|
||||||
long current = 0;
|
long current = 0;
|
||||||
|
@ -512,18 +518,19 @@ public class Huffman
|
||||||
buffer.put((byte)(current));
|
buffer.put((byte)(current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void encode(final int[][] table,ByteBuffer buffer,byte[] b)
|
private static void encode(final int[][] table,ByteBuffer buffer,byte[] b)
|
||||||
{
|
{
|
||||||
long current = 0;
|
long current = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
byte[] array = buffer.array();
|
byte[] array = buffer.array();
|
||||||
int p=buffer.arrayOffset()+buffer.position();
|
int p = buffer.arrayOffset() + buffer.position();
|
||||||
|
|
||||||
int len = b.length;
|
int len = b.length;
|
||||||
for (int i=0;i<len;i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
int c=0xFF&b[i];
|
int c = 0xFF & b[i];
|
||||||
int code = table[c][0];
|
int code = table[c][0];
|
||||||
int bits = table[c][1];
|
int bits = table[c][1];
|
||||||
|
|
||||||
|
@ -531,20 +538,20 @@ public class Huffman
|
||||||
current |= code;
|
current |= code;
|
||||||
n += bits;
|
n += bits;
|
||||||
|
|
||||||
while (n >= 8)
|
while (n >= 8)
|
||||||
{
|
{
|
||||||
n -= 8;
|
n -= 8;
|
||||||
array[p++]=(byte)(current >> n);
|
array[p++] = (byte)(current >> n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
current <<= (8 - n);
|
current <<= (8 - n);
|
||||||
current |= (0xFF >>> n);
|
current |= (0xFF >>> n);
|
||||||
array[p++]=(byte)current;
|
array[p++] = (byte)current;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.position(p-buffer.arrayOffset());
|
buffer.position(p - buffer.arrayOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
@ -77,8 +79,7 @@ public class HuffmanTest
|
||||||
{
|
{
|
||||||
String s = "bad '" + bad + "'";
|
String s = "bad '" + bad + "'";
|
||||||
|
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThat(Huffman.octetsNeeded(s), Matchers.is(-1));
|
||||||
() -> Huffman.octetsNeeded(s));
|
|
||||||
|
|
||||||
assertThrows(BufferOverflowException.class,
|
assertThrows(BufferOverflowException.class,
|
||||||
() -> Huffman.encode(BufferUtil.allocate(32), s));
|
() -> Huffman.encode(BufferUtil.allocate(32), s));
|
||||||
|
|
Loading…
Reference in New Issue