Skip to content

Commit cc055a5

Browse files
committed
JAVA-1070: Restricted NULL Unicode character checks to cstring, so that a normal value string can contain one
1 parent c8a0773 commit cc055a5

File tree

3 files changed

+76
-38
lines changed

3 files changed

+76
-38
lines changed

src/main/org/bson/BasicBSONEncoder.java

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@
1818

1919
package org.bson;
2020

21+
import com.mongodb.DBRefBase;
22+
import org.bson.io.BasicOutputBuffer;
23+
import org.bson.io.OutputBuffer;
24+
import org.bson.types.BSONTimestamp;
25+
import org.bson.types.Binary;
26+
import org.bson.types.Code;
27+
import org.bson.types.CodeWScope;
28+
import org.bson.types.MaxKey;
29+
import org.bson.types.MinKey;
30+
import org.bson.types.ObjectId;
31+
import org.bson.types.Symbol;
32+
33+
import java.lang.reflect.Array;
34+
import java.nio.Buffer;
35+
import java.util.Date;
36+
import java.util.List;
37+
import java.util.Map;
38+
import java.util.Map.Entry;
39+
import java.util.Set;
40+
import java.util.UUID;
41+
import java.util.concurrent.atomic.AtomicInteger;
42+
import java.util.concurrent.atomic.AtomicLong;
43+
import java.util.regex.Pattern;
44+
2145
import static org.bson.BSON.ARRAY;
2246
import static org.bson.BSON.BINARY;
2347
import static org.bson.BSON.BOOLEAN;
@@ -43,31 +67,6 @@
4367
import static org.bson.BSON.UNDEFINED;
4468
import static org.bson.BSON.regexFlags;
4569

46-
import java.lang.reflect.Array;
47-
import java.nio.Buffer;
48-
import java.util.Date;
49-
import java.util.List;
50-
import java.util.Map;
51-
import java.util.Map.Entry;
52-
import java.util.Set;
53-
import java.util.UUID;
54-
import java.util.concurrent.atomic.AtomicInteger;
55-
import java.util.concurrent.atomic.AtomicLong;
56-
import java.util.regex.Pattern;
57-
58-
import org.bson.io.BasicOutputBuffer;
59-
import org.bson.io.OutputBuffer;
60-
import org.bson.types.BSONTimestamp;
61-
import org.bson.types.Binary;
62-
import org.bson.types.Code;
63-
import org.bson.types.CodeWScope;
64-
import org.bson.types.MaxKey;
65-
import org.bson.types.MinKey;
66-
import org.bson.types.ObjectId;
67-
import org.bson.types.Symbol;
68-
69-
import com.mongodb.DBRefBase;
70-
7170
/**
7271
* this is meant to be pooled or cached
7372
* there is some per instance memory for string conversion, etc...
@@ -433,8 +432,8 @@ protected void putObjectId( String name , ObjectId oid ){
433432

434433
private void putPattern( String name, Pattern p ) {
435434
_put( REGEX , name );
436-
_put( p.pattern() );
437-
_put( regexFlags( p.flags() ) );
435+
_put( p.pattern(), true );
436+
_put( regexFlags( p.flags() ), true );
438437
}
439438

440439
private void putMinKey( String name ) {
@@ -454,13 +453,13 @@ private void putMaxKey( String name ) {
454453
*/
455454
protected void _put( byte type , String name ){
456455
_buf.write( type );
457-
_put( name );
456+
_put( name, true );
458457
}
459458

460459
protected void _putValueString( String s ){
461460
int lenPos = _buf.getPosition();
462461
_buf.writeInt( 0 ); // making space for size
463-
int strLen = _put( s );
462+
int strLen = _put( s, false );
464463
_buf.writeInt( lenPos , strLen );
465464
}
466465

@@ -473,14 +472,21 @@ void _reset( Buffer b ){
473472
* puts as utf-8 string
474473
*/
475474
protected int _put( String str ){
475+
return _put(str, false);
476+
}
477+
478+
/**
479+
* puts as utf-8 string
480+
*/
481+
private int _put(String str, boolean checkForNullCharacters) {
476482

477483
final int len = str.length();
478484
int total = 0;
479485

480486
for ( int i=0; i<len; ){
481487
int c = Character.codePointAt( str , i );
482488

483-
if (c == 0x0) {
489+
if (checkForNullCharacters && c == 0x0) {
484490
throw new BSONException(
485491
String.format("BSON cstring '%s' is not valid because it contains a null character at index %d", str, i));
486492
}
@@ -525,7 +531,7 @@ public void writeLong( long x ){
525531
}
526532

527533
public void writeCString( String s ){
528-
_put( s );
534+
_put(s, true);
529535
}
530536

531537
protected OutputBuffer _buf;

src/test/com/mongodb/DBCollectionTest.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.mongodb;
1818

1919
import com.mongodb.util.TestCase;
20-
2120
import org.bson.types.ObjectId;
2221
import org.testng.Assert;
2322
import org.testng.annotations.Test;
@@ -335,7 +334,7 @@ public void testMultiInsertWithContinue() {
335334
} catch (MongoException e) {
336335
assertEquals(11000, e.getCode());
337336
}
338-
assertEquals( c.count(), 2 );
337+
assertEquals(c.count(), 2);
339338
}
340339

341340
@Test( expectedExceptions = IllegalArgumentException.class )
@@ -348,17 +347,27 @@ public void testDotKeysFail() {
348347
}
349348

350349
@Test( expectedExceptions = IllegalArgumentException.class )
351-
public void testNullKeysFail() {
352-
DBCollection c = _db.getCollection("testnullkeysFail");
350+
public void testNullCharacterInKeyFails() {
351+
DBCollection c = _db.getCollection("testNullCharacterInKeyFails");
353352
c.drop();
354353

355354
DBObject obj = BasicDBObjectBuilder.start().add("x",1).add("y",2).add("foo\0bar","baz").get();
356355
c.insert(obj);
357356
}
358357

358+
@Test
359+
public void testNullCharacterInValueSucceeds() {
360+
DBCollection c = _db.getCollection("testNullCharacterInValueSucceeds");
361+
c.drop();
362+
363+
DBObject obj = BasicDBObjectBuilder.start().add("x", "foo\0bar").add("nested", new BasicDBObject("y", "foo\0bar")).get();
364+
c.insert(obj);
365+
assertEquals(obj, c.findOne());
366+
}
367+
359368
@Test( expectedExceptions = IllegalArgumentException.class )
360-
public void testNullKeysFailWhenNested() {
361-
DBCollection c = _db.getCollection("testnullkeysFailWhenNested");
369+
public void testNullCharacterInNestedKeyFails() {
370+
DBCollection c = _db.getCollection("testNullCharacterInNestedKeyFails");
362371
c.drop();
363372

364373
final BasicDBList list = new BasicDBList();

src/test/org/bson/BasicBSONEncoderTest.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,35 @@
2121
import org.testng.Assert;
2222
import org.testng.annotations.Test;
2323

24+
import java.util.regex.Pattern;
25+
2426
public class BasicBSONEncoderTest extends Assert {
2527

2628
@Test(expectedExceptions = BSONException.class)
27-
public void testNullCharacterInCString() {
29+
public void nullCharacterInCStringShouldThrowException() {
2830
BasicBSONEncoder encoder = new BasicBSONEncoder();
2931
encoder.set(new BasicOutputBuffer());
3032
encoder.writeCString("hell\u0000world");
3133
}
34+
35+
@Test(expectedExceptions = BSONException.class)
36+
public void nullCharacterInKeyShouldThrowException() {
37+
BasicBSONEncoder encoder = new BasicBSONEncoder();
38+
encoder.set(new BasicOutputBuffer());
39+
encoder.putString("ke\u0000y", "helloWorld");
40+
}
41+
42+
@Test(expectedExceptions = BSONException.class)
43+
public void nullCharacterInRegexStringShouldThrowException() {
44+
BasicBSONEncoder encoder = new BasicBSONEncoder();
45+
encoder.set(new BasicOutputBuffer());
46+
encoder._putObjectField("key", Pattern.compile("hello\u0000World"));
47+
}
48+
49+
@Test
50+
public void nullCharacterInStringShouldNotThrowException() {
51+
BasicBSONEncoder encoder = new BasicBSONEncoder();
52+
encoder.set(new BasicOutputBuffer());
53+
encoder.putString("key", "hell\u0000world");
54+
}
3255
}

0 commit comments

Comments
 (0)