handle empty strings properly in Pattern.split

We were incorrectly returning an empty array when the input was empty,
whereas we ought to return an array containing a single empty string.
When the pattern to match was empty, we went into a loop to create an
infinite list of empty strings, only to crash once we've run out of
memory.  This commit addresses both problems.
This commit is contained in:
Joel Dice 2010-09-06 11:16:27 -06:00
parent a26eb1b2b9
commit 250a77dc13
2 changed files with 59 additions and 5 deletions

View File

@ -115,23 +115,34 @@ public class Pattern {
List<CharSequence> list = new LinkedList();
int index = 0;
int trailing = 0;
while (index < input.length() && list.size() < limit) {
int i = indexOf(input, pattern, index);
int patternLength = pattern.length();
while (index < input.length() && list.size() < limit - 1) {
int i;
if (patternLength == 0) {
if (list.size() == 0) {
i = 0;
} else {
i = index + 1;
}
} else {
i = indexOf(input, pattern, index);
}
if (i >= 0) {
if (i == index) {
if (patternLength != 0 && i == index) {
++ trailing;
} else {
trailing = 0;
}
list.add(input.subSequence(index, i));
index = i + pattern.length();
index = i + patternLength;
} else {
break;
}
}
if (strip && index == input.length()) {
if (strip && index > 0 && index == input.length()) {
++ trailing;
} else {
trailing = 0;

View File

@ -3,6 +3,24 @@ public class Strings {
if (! v) throw new RuntimeException();
}
private static boolean equal(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
private static boolean arraysEqual(Object[] a, Object[] b) {
if (a.length != b.length) {
return false;
}
for (int i = 0; i < a.length; ++i) {
if (! equal(a[i], b[i])) {
return false;
}
}
return true;
}
public static void main(String[] args) {
expect(new String(new byte[] { 99, 111, 109, 46, 101, 99, 111, 118, 97,
116, 101, 46, 110, 97, 116, 46, 98, 117,
@ -13,6 +31,31 @@ public class Strings {
expect(months.split("\u00ae").length == 3);
expect(months.replaceAll("\u00ae", ".").equals("Jan.Feb.Mar."));
expect(arraysEqual
("xyz".split("", 0), new String[] { "", "x", "y", "z" }));
expect(arraysEqual
("xyz".split("", 1), new String[] { "xyz" }));
expect(arraysEqual
("xyz".split("", 2), new String[] { "", "xyz" }));
expect(arraysEqual
("xyz".split("", 3), new String[] { "", "x", "yz" }));
expect(arraysEqual
("xyz".split("", 4), new String[] { "", "x", "y", "z" }));
expect(arraysEqual
("xyz".split("", 5), new String[] { "", "x", "y", "z", "" }));
expect(arraysEqual
("xyz".split("", 6), new String[] { "", "x", "y", "z", "" }));
expect(arraysEqual
("xyz".split("", -1), new String[] { "", "x", "y", "z", "" }));
expect(arraysEqual("".split("xyz", 0), new String[] { "" }));
expect(arraysEqual("".split("xyz", 1), new String[] { "" }));
expect(arraysEqual("".split("xyz", -1), new String[] { "" }));
expect(arraysEqual("".split("", 0), new String[] { "" }));
expect(arraysEqual("".split("", 1), new String[] { "" }));
expect(arraysEqual("".split("", -1), new String[] { "" }));
expect("foo_foofoo__foo".replaceAll("_", "__")
.equals("foo__foofoo____foo"));