Commit 436625f8 authored by miloyip's avatar miloyip

Fix ambiguous cases in Pointer::Create()

parent b6a54f72
...@@ -305,19 +305,31 @@ public: ...@@ -305,19 +305,31 @@ public:
ValueType* v = &root; ValueType* v = &root;
bool exist = true; bool exist = true;
for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
if (t->index == kPointerInvalidIndex) { // object name if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
// Handling of '-' for last element of array v->PushBack(Value().Move(), allocator);
if (t->name[0] == '-' && t->length == 1) { v = &((*v)[v->Size() - 1]);
if (!v->IsArray()) exist = false;
v->SetArray(); // Change to Array }
v->PushBack(Value().Move(), allocator); else {
v = &((*v)[v->Size() - 1]); if (t->index == kPointerInvalidIndex) { // must be object name
exist = false;
}
else {
if (!v->IsObject()) if (!v->IsObject())
v->SetObject(); // Change to Object v->SetObject(); // Change to Object
}
else { // object name or array index
if (!v->IsArray() && !v->IsObject())
v->SetArray(); // Change to Array
}
if (v->IsArray()) {
if (t->index >= v->Size()) {
v->Reserve(t->index + 1, allocator);
while (t->index >= v->Size())
v->PushBack(Value().Move(), allocator);
exist = false;
}
v = &((*v)[t->index]);
}
else {
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length)); typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
if (m == v->MemberEnd()) { if (m == v->MemberEnd()) {
v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator); v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator);
...@@ -328,18 +340,6 @@ public: ...@@ -328,18 +340,6 @@ public:
v = &m->value; v = &m->value;
} }
} }
else { // array index
if (!v->IsArray())
v->SetArray(); // Change to Array
if (t->index >= v->Size()) {
v->Reserve(t->index + 1, allocator);
while (t->index >= v->Size())
v->PushBack(Value().Move(), allocator);
exist = false;
}
v = &((*v)[t->index]);
}
} }
if (alreadyExist) if (alreadyExist)
......
...@@ -532,9 +532,13 @@ TEST(Pointer, Create) { ...@@ -532,9 +532,13 @@ TEST(Pointer, Create) {
Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator()); Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
EXPECT_EQ(&d["foo"][1], v); EXPECT_EQ(&d["foo"][1], v);
} }
{ {
Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator()); Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
EXPECT_EQ(&d["foo"][2][0], v); // "foo/-" is a newly created null value x.
// "foo/-/-" finds that x is not an array, it converts x to empty object
// and treats - as "-" member name
EXPECT_EQ(&d["foo"][2]["-"], v);
} }
{ {
...@@ -1314,3 +1318,22 @@ TEST(Pointer, SwapValueByPointer_NoAllocator) { ...@@ -1314,3 +1318,22 @@ TEST(Pointer, SwapValueByPointer_NoAllocator) {
EXPECT_STREQ("bar", d["foo"][0].GetString()); EXPECT_STREQ("bar", d["foo"][0].GetString());
EXPECT_STREQ("baz", d["foo"][1].GetString()); EXPECT_STREQ("baz", d["foo"][1].GetString());
} }
TEST(Pointer, Ambiguity) {
{
Document d;
d.Parse("{\"0\" : [123]}");
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
}
{
Document d;
EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment