diff options
author | Shaun Verch <shaun.verch@10gen.com> | 2013-03-28 10:41:57 -0400 |
---|---|---|
committer | Dan Pasette <dan@10gen.com> | 2013-03-29 11:38:07 -0400 |
commit | 9ba71622c9cf2af20c72469601aaf0eebd5f6e4c (patch) | |
tree | 298e6e94db69f01257b610d8c187e104d107c8cb | |
parent | ffe9de8df384792315c40c65209c1932778b52a8 (diff) | |
download | mongo-9ba71622c9cf2af20c72469601aaf0eebd5f6e4c.tar.gz |
SERVER-9082 Accept any valid value in id field of dbref
-rw-r--r-- | src/mongo/db/json.cpp | 69 | ||||
-rw-r--r-- | src/mongo/dbtests/jsontests.cpp | 45 | ||||
-rw-r--r-- | src/mongo/dbtests/jstests.cpp | 27 |
3 files changed, 81 insertions, 60 deletions
diff --git a/src/mongo/db/json.cpp b/src/mongo/db/json.cpp index 74fac9f1b3c..afe08f3b0f5 100644 --- a/src/mongo/db/json.cpp +++ b/src/mongo/db/json.cpp @@ -465,6 +465,9 @@ namespace mongo { } Status JParse::dbRefObject(const StringData& fieldName, BSONObjBuilder& builder) { + + BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); + if (!accept(COLON)) { return parseError("Expecting ':'"); } @@ -474,6 +477,8 @@ namespace mongo { if (ret != Status::OK()) { return ret; } + subBuilder.append("$ref", ns); + if (!accept(COMMA)) { return parseError("Expecting ','"); } @@ -484,42 +489,12 @@ namespace mongo { if (!accept(COLON)) { return parseError("Expecting ':'"); } - if (accept("ObjectId")) { - BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); - subBuilder.append("$ref", ns); - objectId("$id", subBuilder); - subBuilder.done(); - } - else if (accept(LBRACE)) { - BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); - subBuilder.append("$ref", ns); - if (!acceptField("$oid")) { - return parseError("Expected field name: \"$oid\""); - } - objectIdObject("$id", subBuilder); - subBuilder.done(); - if (!accept(RBRACE)) { - return parseError("Expecting '}'"); - } - } - else { - std::string id; - id.reserve(ID_RESERVE_SIZE); - Status ret = quotedString(&id); - if (ret != Status::OK()) { - return ret; - } - if (id.size() != 24) { - return parseError("Expecting 24 hex digits: " + id); - } - if (!isHexString(id)) { - return parseError("Expecting hex digits: " + id); - } - BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); - subBuilder.append("$ref", ns); - subBuilder.append("$id", OID(id)); - subBuilder.done(); + Status valueRet = value("$id", subBuilder); + if (valueRet != Status::OK()) { + return valueRet; } + + subBuilder.done(); return Status::OK(); } @@ -661,6 +636,8 @@ namespace mongo { } Status JParse::dbRef(const StringData& fieldName, BSONObjBuilder& builder) { + BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); + if (!accept(LPAREN)) { return parseError("Expecting '('"); } @@ -670,27 +647,21 @@ namespace mongo { if (refRet != Status::OK()) { return refRet; } + subBuilder.append("$ref", ns); + if (!accept(COMMA)) { return parseError("Expecting ','"); } - std::string id; - id.reserve(ID_RESERVE_SIZE); - Status idRet = quotedString(&id); - if (idRet != Status::OK()) { - return idRet; - } - if (id.size() != 24) { - return parseError("Expecting 24 hex digits: " + id); - } - if (!isHexString(id)) { - return parseError("Expecting hex digits: " + id); + + Status valueRet = value("$id", subBuilder); + if (valueRet != Status::OK()) { + return valueRet; } + if (!accept(RPAREN)) { return parseError("Expecting ')'"); } - BSONObjBuilder subBuilder(builder.subobjStart(fieldName)); - subBuilder.append("$ref", ns); - subBuilder.append("$id", OID(id)); + subBuilder.done(); return Status::OK(); } diff --git a/src/mongo/dbtests/jsontests.cpp b/src/mongo/dbtests/jsontests.cpp index 0afee14a37b..98a5624dbd4 100644 --- a/src/mongo/dbtests/jsontests.cpp +++ b/src/mongo/dbtests/jsontests.cpp @@ -860,11 +860,9 @@ namespace JsonTests { class DBRefConstructor : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - OID o; - memset( &o, 0, 12 ); BSONObjBuilder subBuilder(b.subobjStart("a")); subBuilder.append("$ref", "ns"); - subBuilder.append("$id", o); + subBuilder.append("$id", "000000000000000000000000"); subBuilder.done(); return b.obj(); } @@ -877,11 +875,9 @@ namespace JsonTests { class DBRefConstructorCapitals : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - OID o; - memset( &o, 0, 12 ); BSONObjBuilder subBuilder(b.subobjStart("a")); subBuilder.append("$ref", "ns"); - subBuilder.append("$id", o); + subBuilder.append("$id", "000000000000000000000000"); subBuilder.done(); return b.obj(); } @@ -890,14 +886,40 @@ namespace JsonTests { } }; - class DBRefObjectIDString : public Base { + class DBRefConstructorNumber : public Base { virtual BSONObj bson() const { BSONObjBuilder b; - OID o; - memset( &o, 0, 12 ); BSONObjBuilder subBuilder(b.subobjStart("a")); subBuilder.append("$ref", "ns"); - subBuilder.append("$id", o); + subBuilder.append("$id", 1); + subBuilder.done(); + return b.obj(); + } + virtual string json() const { + return "{ \"a\" : Dbref( \"ns\", 1 ) }"; + } + }; + + class DBRefNumberId : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + BSONObjBuilder subBuilder(b.subobjStart("a")); + subBuilder.append("$ref", "ns"); + subBuilder.append("$id", 1); + subBuilder.done(); + return b.obj(); + } + virtual string json() const { + return "{ \"a\" : { \"$ref\" : \"ns\", \"$id\" : 1 } }"; + } + }; + + class DBRefStringId : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + BSONObjBuilder subBuilder(b.subobjStart("a")); + subBuilder.append("$ref", "ns"); + subBuilder.append("$id", "000000000000000000000000"); subBuilder.done(); return b.obj(); } @@ -1605,7 +1627,8 @@ namespace JsonTests { add< FromJsonTests::Utf8TooShort >(); add< FromJsonTests::DBRefConstructor >(); add< FromJsonTests::DBRefConstructorCapitals >(); - add< FromJsonTests::DBRefObjectIDString >(); + add< FromJsonTests::DBRefNumberId >(); + add< FromJsonTests::DBRefStringId >(); add< FromJsonTests::DBRefObjectIDObject >(); add< FromJsonTests::DBRefObjectIDConstructor >(); add< FromJsonTests::Oid >(); diff --git a/src/mongo/dbtests/jstests.cpp b/src/mongo/dbtests/jstests.cpp index c3c9bff6f3b..67262de778b 100644 --- a/src/mongo/dbtests/jstests.cpp +++ b/src/mongo/dbtests/jstests.cpp @@ -1061,6 +1061,32 @@ namespace JSTests { class InformalDBRefTest : public TestRoundTrip { virtual BSONObj bson() const { BSONObjBuilder b; + BSONObjBuilder subBuilder(b.subobjStart("a")); + subBuilder.append("$ref", "ns"); + subBuilder.append("$id", "000000000000000000000000"); + subBuilder.done(); + return b.obj(); + } + + // Don't need to return anything because we are overriding both jsonOut and jsonIn + virtual string json() const { return ""; } + + // Need to override these because the JSON doesn't actually round trip. + // An object with "$ref" and "$id" fields is handled specially and different on the way out. + virtual string jsonOut() const { + return "{ \"a\" : DBRef( \"ns\", \"000000000000000000000000\" ) }"; + } + virtual string jsonIn() const { + stringstream ss; + ss << "{ \"a\" : { \"$ref\" : \"ns\" , " << + "\"$id\" : \"000000000000000000000000\" } }"; + return ss.str(); + } + }; + + class InformalDBRefOIDTest : public TestRoundTrip { + virtual BSONObj bson() const { + BSONObjBuilder b; OID o; memset( &o, 0, 12 ); BSONObjBuilder subBuilder(b.subobjStart("a")); @@ -1333,6 +1359,7 @@ namespace JSTests { add< RoundTripTests::DBRefTest >(); add< RoundTripTests::DBPointerTest >(); add< RoundTripTests::InformalDBRefTest >(); + add< RoundTripTests::InformalDBRefOIDTest >(); add< RoundTripTests::InformalDBRefExtraFieldTest >(); } } myall; |