Skip to content

Commit d2c2cd7

Browse files
committed
Fix infinite loop when parsing invalid regular expressions
JAVA-2228
1 parent 17abd87 commit d2c2cd7

File tree

5 files changed

+82
-6
lines changed

5 files changed

+82
-6
lines changed

bson/src/main/org/bson/json/JsonBuffer.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class JsonBuffer {
2020

2121
private final String buffer;
2222
private int position;
23+
private boolean eof;
2324

2425
public JsonBuffer(final String buffer) {
2526
this.buffer = buffer;
@@ -34,10 +35,18 @@ public void setPosition(final int position) {
3435
}
3536

3637
public int read() {
37-
return (position >= buffer.length()) ? -1 : buffer.charAt(position++);
38+
if (eof) {
39+
throw new JsonParseException("Trying to read past EOF.");
40+
} else if (position >= buffer.length()) {
41+
eof = true;
42+
return -1;
43+
} else {
44+
return buffer.charAt(position++);
45+
}
3846
}
3947

4048
public void unread(final int c) {
49+
eof = false;
4150
if (c != -1 && buffer.charAt(position - 1) == c) {
4251
position--;
4352
}

bson/src/main/org/bson/json/JsonScanner.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ private JsonToken scanRegularExpression() {
134134
switch (state) {
135135
case IN_PATTERN:
136136
switch (c) {
137+
case -1:
138+
state = RegularExpressionState.INVALID;
139+
break;
137140
case '/':
138141
state = RegularExpressionState.IN_OPTIONS;
139142
options = buffer.getPosition();
@@ -174,6 +177,7 @@ private JsonToken scanRegularExpression() {
174177
}
175178
break;
176179
default:
180+
break;
177181
}
178182

179183
switch (state) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2008-2014 MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.bson.json;
18+
19+
import org.junit.Test;
20+
21+
import static org.junit.Assert.assertEquals;
22+
23+
public class JsonBufferTest {
24+
25+
@Test
26+
public void testRead() {
27+
JsonBuffer buffer = new JsonBuffer("ABC");
28+
assertEquals('A', buffer.read());
29+
assertEquals('B', buffer.read());
30+
assertEquals('C', buffer.read());
31+
assertEquals(-1, buffer.read());
32+
}
33+
34+
@Test
35+
public void testUnRead() {
36+
JsonBuffer buffer = new JsonBuffer("A");
37+
buffer.unread(buffer.read());
38+
assertEquals('A', buffer.read());
39+
assertEquals(-1, buffer.read());
40+
}
41+
42+
@Test
43+
public void testPosition() {
44+
JsonBuffer buffer = new JsonBuffer("ABC");
45+
46+
buffer.setPosition(2);
47+
assertEquals(2, buffer.getPosition());
48+
}
49+
50+
@Test(expected = JsonParseException.class)
51+
public void testEOFCheck() {
52+
JsonBuffer buffer = new JsonBuffer("");
53+
54+
buffer.read();
55+
buffer.read();
56+
}
57+
}

bson/src/test/unit/org/bson/json/JsonReaderTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,6 @@ public void testClosedState() {
590590
bsonReader.readBinaryData();
591591
}
592592

593-
//TODO Together with next text this is just an indicator that our behavior is not very correct.
594593
@Test(expected = JsonParseException.class)
595594
public void testEndOfFile0() {
596595
String json = "{";
@@ -600,13 +599,13 @@ public void testEndOfFile0() {
600599
bsonReader.readBsonType();
601600
}
602601

603-
@Test
602+
@Test(expected = JsonParseException.class)
604603
public void testEndOfFile1() {
605604
String json = "{ test : ";
606605
bsonReader = new JsonReader(json);
607606
assertEquals(BsonType.DOCUMENT, bsonReader.readBsonType());
608607
bsonReader.readStartDocument();
609-
assertEquals(BsonType.END_OF_DOCUMENT, bsonReader.readBsonType());
608+
bsonReader.readBsonType();
610609
}
611610

612611
@Test

bson/src/test/unit/org/bson/json/JsonScannerTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public void testEndOfFile() {
3131
JsonToken token = scanner.nextToken();
3232
assertEquals(JsonTokenType.END_OF_FILE, token.getType());
3333
assertEquals("<eof>", token.getValue());
34-
assertEquals(-1, buffer.read());
3534
}
3635

3736
@Test
@@ -503,7 +502,15 @@ public void testInvalidRegularExpression() {
503502
String json = "\t /pattern/nsk,";
504503
JsonBuffer buffer = new JsonBuffer(json);
505504
JsonScanner scanner = new JsonScanner(buffer);
506-
JsonToken token = scanner.nextToken();
505+
scanner.nextToken();
506+
}
507+
508+
@Test(expected = JsonParseException.class)
509+
public void testInvalidRegularExpressionNoEnd() {
510+
String json = "/b";
511+
JsonBuffer buffer = new JsonBuffer(json);
512+
JsonScanner scanner = new JsonScanner(buffer);
513+
scanner.nextToken();
507514
}
508515

509516
@Test(expected = JsonParseException.class)

0 commit comments

Comments
 (0)