Merge branch 'jetty-9.4.x' into jetty-10.0.x
# Conflicts: # jetty-documentation/src/main/asciidoc/development/frameworks/weld.adoc # jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormInputStreamTest.java
This commit is contained in:
commit
da3bd1da8b
|
@ -36,9 +36,9 @@ import java.util.Arrays;
|
||||||
*/
|
*/
|
||||||
public class SearchPattern
|
public class SearchPattern
|
||||||
{
|
{
|
||||||
static final int alphabetSize = 256;
|
private static final int ALPHABET_SIZE = 256;
|
||||||
private int[] table;
|
private final int[] table = new int[ALPHABET_SIZE];
|
||||||
private byte[] pattern;
|
private final byte[] pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces a SearchPattern instance which can be used
|
* Produces a SearchPattern instance which can be used
|
||||||
|
@ -70,16 +70,11 @@ public class SearchPattern
|
||||||
private SearchPattern(byte[] pattern)
|
private SearchPattern(byte[] pattern)
|
||||||
{
|
{
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
|
|
||||||
if (pattern.length == 0)
|
if (pattern.length == 0)
|
||||||
throw new IllegalArgumentException("Empty Pattern");
|
throw new IllegalArgumentException("Empty Pattern");
|
||||||
|
|
||||||
//Build up the pre-processed table for this pattern.
|
//Build up the pre-processed table for this pattern.
|
||||||
table = new int[alphabetSize];
|
Arrays.fill(table, pattern.length);
|
||||||
for (int i = 0; i < table.length; ++i)
|
|
||||||
{
|
|
||||||
table[i] = pattern.length;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < pattern.length - 1; ++i)
|
for (int i = 0; i < pattern.length - 1; ++i)
|
||||||
{
|
{
|
||||||
table[0xff & pattern[i]] = pattern.length - 1 - i;
|
table[0xff & pattern[i]] = pattern.length - 1 - i;
|
||||||
|
@ -97,7 +92,7 @@ public class SearchPattern
|
||||||
*/
|
*/
|
||||||
public int match(byte[] data, int offset, int length)
|
public int match(byte[] data, int offset, int length)
|
||||||
{
|
{
|
||||||
validate(data, offset, length);
|
validateArgs(data, offset, length);
|
||||||
|
|
||||||
int skip = offset;
|
int skip = offset;
|
||||||
while (skip <= offset + length - pattern.length)
|
while (skip <= offset + length - pattern.length)
|
||||||
|
@ -125,7 +120,7 @@ public class SearchPattern
|
||||||
*/
|
*/
|
||||||
public int endsWith(byte[] data, int offset, int length)
|
public int endsWith(byte[] data, int offset, int length)
|
||||||
{
|
{
|
||||||
validate(data, offset, length);
|
validateArgs(data, offset, length);
|
||||||
|
|
||||||
int skip = (pattern.length <= length) ? (offset + length - pattern.length) : offset;
|
int skip = (pattern.length <= length) ? (offset + length - pattern.length) : offset;
|
||||||
while (skip < offset + length)
|
while (skip < offset + length)
|
||||||
|
@ -136,10 +131,8 @@ public class SearchPattern
|
||||||
return (offset + length - skip);
|
return (offset + length - skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip + pattern.length - 1 < data.length)
|
// We can't use the pre-processed table as we are not matching on the full pattern.
|
||||||
skip += table[0xff & data[skip + pattern.length - 1]];
|
skip++;
|
||||||
else
|
|
||||||
skip++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -157,10 +150,9 @@ public class SearchPattern
|
||||||
*/
|
*/
|
||||||
public int startsWith(byte[] data, int offset, int length, int matched)
|
public int startsWith(byte[] data, int offset, int length, int matched)
|
||||||
{
|
{
|
||||||
validate(data, offset, length);
|
validateArgs(data, offset, length);
|
||||||
|
|
||||||
int matchedCount = 0;
|
int matchedCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < pattern.length - matched && i < length; i++)
|
for (int i = 0; i < pattern.length - matched && i < length; i++)
|
||||||
{
|
{
|
||||||
if (data[offset + i] == pattern[i + matched])
|
if (data[offset + i] == pattern[i + matched])
|
||||||
|
@ -180,7 +172,7 @@ public class SearchPattern
|
||||||
* @param offset The offset within the data to start the search
|
* @param offset The offset within the data to start the search
|
||||||
* @param length The length of the data to search
|
* @param length The length of the data to search
|
||||||
*/
|
*/
|
||||||
private void validate(byte[] data, int offset, int length)
|
private void validateArgs(byte[] data, int offset, int length)
|
||||||
{
|
{
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
throw new IllegalArgumentException("offset was negative");
|
throw new IllegalArgumentException("offset was negative");
|
||||||
|
|
|
@ -32,10 +32,10 @@ public class SearchPatternTest
|
||||||
@Test
|
@Test
|
||||||
public void testBasicSearch()
|
public void testBasicSearch()
|
||||||
{
|
{
|
||||||
byte[] p1 = new String("truth").getBytes(StandardCharsets.US_ASCII);
|
byte[] p1 = "truth".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] p2 = new String("evident").getBytes(StandardCharsets.US_ASCII);
|
byte[] p2 = "evident".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] p3 = new String("we").getBytes(StandardCharsets.US_ASCII);
|
byte[] p3 = "we".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String("we hold these truths to be self evident").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = "we hold these truths to be self evident".getBytes(StandardCharsets.US_ASCII);
|
||||||
|
|
||||||
// Testing Compiled Pattern p1 "truth"
|
// Testing Compiled Pattern p1 "truth"
|
||||||
SearchPattern sp1 = SearchPattern.compile(p1);
|
SearchPattern sp1 = SearchPattern.compile(p1);
|
||||||
|
@ -65,8 +65,8 @@ public class SearchPatternTest
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleMatch()
|
public void testDoubleMatch()
|
||||||
{
|
{
|
||||||
byte[] p = new String("violent").getBytes(StandardCharsets.US_ASCII);
|
byte[] p = "violent".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String("These violent delights have violent ends.").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = "These violent delights have violent ends.".getBytes(StandardCharsets.US_ASCII);
|
||||||
SearchPattern sp = SearchPattern.compile(p);
|
SearchPattern sp = SearchPattern.compile(p);
|
||||||
assertEquals(6, sp.match(d, 0, d.length));
|
assertEquals(6, sp.match(d, 0, d.length));
|
||||||
assertEquals(-1, sp.match(d, 6, p.length - 1));
|
assertEquals(-1, sp.match(d, 6, p.length - 1));
|
||||||
|
@ -113,8 +113,8 @@ public class SearchPatternTest
|
||||||
@Test
|
@Test
|
||||||
public void testAlmostMatch()
|
public void testAlmostMatch()
|
||||||
{
|
{
|
||||||
byte[] p = new String("violent").getBytes(StandardCharsets.US_ASCII);
|
byte[] p = "violent".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String("vio lent violen v iolent violin vioviolenlent viiolent").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = "vio lent violen v iolent violin vioviolenlent viiolent".getBytes(StandardCharsets.US_ASCII);
|
||||||
SearchPattern sp = SearchPattern.compile(p);
|
SearchPattern sp = SearchPattern.compile(p);
|
||||||
assertEquals(-1, sp.match(d, 0, d.length));
|
assertEquals(-1, sp.match(d, 0, d.length));
|
||||||
}
|
}
|
||||||
|
@ -123,14 +123,14 @@ public class SearchPatternTest
|
||||||
public void testOddSizedPatterns()
|
public void testOddSizedPatterns()
|
||||||
{
|
{
|
||||||
// Test Large Pattern
|
// Test Large Pattern
|
||||||
byte[] p = new String("pneumonoultramicroscopicsilicovolcanoconiosis").getBytes(StandardCharsets.US_ASCII);
|
byte[] p = "pneumonoultramicroscopicsilicovolcanoconiosis".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String("pneumon").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = "pneumon".getBytes(StandardCharsets.US_ASCII);
|
||||||
SearchPattern sp = SearchPattern.compile(p);
|
SearchPattern sp = SearchPattern.compile(p);
|
||||||
assertEquals(-1, sp.match(d, 0, d.length));
|
assertEquals(-1, sp.match(d, 0, d.length));
|
||||||
|
|
||||||
// Test Single Character Pattern
|
// Test Single Character Pattern
|
||||||
p = new String("s").getBytes(StandardCharsets.US_ASCII);
|
p = "s".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String("the cake is a lie").getBytes(StandardCharsets.US_ASCII);
|
d = "the cake is a lie".getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(10, sp.match(d, 0, d.length));
|
assertEquals(10, sp.match(d, 0, d.length));
|
||||||
}
|
}
|
||||||
|
@ -138,30 +138,36 @@ public class SearchPatternTest
|
||||||
@Test
|
@Test
|
||||||
public void testEndsWith()
|
public void testEndsWith()
|
||||||
{
|
{
|
||||||
byte[] p = new String("pneumonoultramicroscopicsilicovolcanoconiosis").getBytes(StandardCharsets.US_ASCII);
|
byte[] p = "pneumonoultramicroscopicsilicovolcanoconiosis".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String("pneumonoultrami").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = "pneumonoultrami".getBytes(StandardCharsets.US_ASCII);
|
||||||
SearchPattern sp = SearchPattern.compile(p);
|
SearchPattern sp = SearchPattern.compile(p);
|
||||||
assertEquals(15, sp.endsWith(d, 0, d.length));
|
assertEquals(15, sp.endsWith(d, 0, d.length));
|
||||||
|
|
||||||
p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String("abcdefghijklmnopqrstuvwxyzabcdefghijklmno").getBytes(StandardCharsets.US_ASCII);
|
d = "abcdefghijklmnopqrstuvwxyzabcdefghijklmno".getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(0, sp.match(d, 0, d.length));
|
assertEquals(0, sp.match(d, 0, d.length));
|
||||||
assertEquals(-1, sp.match(d, 1, d.length - 1));
|
assertEquals(-1, sp.match(d, 1, d.length - 1));
|
||||||
assertEquals(15, sp.endsWith(d, 0, d.length));
|
assertEquals(15, sp.endsWith(d, 0, d.length));
|
||||||
|
|
||||||
p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
d = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(0, sp.match(d, 0, d.length));
|
assertEquals(0, sp.match(d, 0, d.length));
|
||||||
assertEquals(26, sp.match(d, 1, d.length - 1));
|
assertEquals(26, sp.match(d, 1, d.length - 1));
|
||||||
assertEquals(26, sp.endsWith(d, 0, d.length));
|
assertEquals(26, sp.endsWith(d, 0, d.length));
|
||||||
|
|
||||||
//test no match
|
//test no match
|
||||||
p = new String("hello world").getBytes(StandardCharsets.US_ASCII);
|
p = "hello world".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String("there is definitely no match in here").getBytes(StandardCharsets.US_ASCII);
|
d = "there is definitely no match in here".getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(0, sp.endsWith(d, 0, d.length));
|
assertEquals(0, sp.endsWith(d, 0, d.length));
|
||||||
|
|
||||||
|
//Test with range on array.
|
||||||
|
p = "abcde".getBytes(StandardCharsets.US_ASCII);
|
||||||
|
d = "?abc00000".getBytes(StandardCharsets.US_ASCII);
|
||||||
|
sp = SearchPattern.compile(p);
|
||||||
|
assertEquals(3, sp.endsWith(d, 0, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -178,39 +184,54 @@ public class SearchPatternTest
|
||||||
|
|
||||||
private void testStartsWith(String offset)
|
private void testStartsWith(String offset)
|
||||||
{
|
{
|
||||||
byte[] p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
byte[] p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
byte[] d = new String(offset + "ijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
byte[] d = (offset + "ijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
||||||
SearchPattern sp = SearchPattern.compile(p);
|
SearchPattern sp = SearchPattern.compile(p);
|
||||||
assertEquals(18 + offset.length(), sp.match(d, offset.length(), d.length - offset.length()));
|
assertEquals(18 + offset.length(), sp.match(d, offset.length(), d.length - offset.length()));
|
||||||
assertEquals(-1, sp.match(d, offset.length() + 19, d.length - 19 - offset.length()));
|
assertEquals(-1, sp.match(d, offset.length() + 19, d.length - 19 - offset.length()));
|
||||||
assertEquals(26, sp.startsWith(d, offset.length(), d.length - offset.length(), 8));
|
assertEquals(26, sp.startsWith(d, offset.length(), d.length - offset.length(), 8));
|
||||||
|
|
||||||
p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String(offset + "ijklmnopqrstuvwxyNOMATCH").getBytes(StandardCharsets.US_ASCII);
|
d = (offset + "ijklmnopqrstuvwxyNOMATCH").getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(0, sp.startsWith(d, offset.length(), d.length - offset.length(), 8));
|
assertEquals(0, sp.startsWith(d, offset.length(), d.length - offset.length(), 8));
|
||||||
|
|
||||||
p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String(offset + "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
d = (offset + "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(26, sp.startsWith(d, offset.length(), d.length - offset.length(), 0));
|
assertEquals(26, sp.startsWith(d, offset.length(), d.length - offset.length(), 0));
|
||||||
|
|
||||||
//test no match
|
//test no match
|
||||||
p = new String("hello world").getBytes(StandardCharsets.US_ASCII);
|
p = "hello world".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String(offset + "there is definitely no match in here").getBytes(StandardCharsets.US_ASCII);
|
d = (offset + "there is definitely no match in here").getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(0, sp.startsWith(d, offset.length(), d.length - offset.length(), 0));
|
assertEquals(0, sp.startsWith(d, offset.length(), d.length - offset.length(), 0));
|
||||||
|
|
||||||
//test large pattern small buffer
|
//test large pattern small buffer
|
||||||
p = new String("abcdefghijklmnopqrstuvwxyz").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String(offset + "mnopqrs").getBytes(StandardCharsets.US_ASCII);
|
d = (offset + "mnopqrs").getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(19, sp.startsWith(d, offset.length(), d.length - offset.length(), 12));
|
assertEquals(19, sp.startsWith(d, offset.length(), d.length - offset.length(), 12));
|
||||||
|
|
||||||
//partial pattern
|
//partial pattern
|
||||||
p = new String("abcdef").getBytes(StandardCharsets.US_ASCII);
|
p = "abcdef".getBytes(StandardCharsets.US_ASCII);
|
||||||
d = new String(offset + "cde").getBytes(StandardCharsets.US_ASCII);
|
d = (offset + "cde").getBytes(StandardCharsets.US_ASCII);
|
||||||
sp = SearchPattern.compile(p);
|
sp = SearchPattern.compile(p);
|
||||||
assertEquals(5, sp.startsWith(d, offset.length(), d.length - offset.length(), 2));
|
assertEquals(5, sp.startsWith(d, offset.length(), d.length - offset.length(), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExampleFrom4673()
|
||||||
|
{
|
||||||
|
SearchPattern pattern = SearchPattern.compile("\r\n------WebKitFormBoundaryhXfFAMfUnUKhmqT8".getBytes(StandardCharsets.US_ASCII));
|
||||||
|
byte[] data = new byte[]{118,97,108,117,101,49,
|
||||||
|
'\r','\n','-','-','-','-',
|
||||||
|
0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0};
|
||||||
|
int length = 12;
|
||||||
|
|
||||||
|
int partialMatch = pattern.endsWith(data, 0, length);
|
||||||
|
System.err.println("match1: " + partialMatch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue