add length limit to authors on saving/loading, fix type issue causing mass duplication

When making a local save, then stamping and loading the stamp (without doing anything else in between), issues with the code would cause the unsigned int in the json to turn into a normal int. It would then think the authors data from the stamp was from something else and append it. For users that do an excessive amount of stamping, this causes duplication in the authors links that shouldn't have ever happened.
This commit is contained in:
jacob1
2017-07-28 20:00:19 -04:00
parent cbad202ac2
commit b02a72a77b
3 changed files with 22 additions and 16 deletions

View File

@@ -2023,16 +2023,15 @@ void Client::MergeStampAuthorInfo(Json::Value stampAuthors)
// unless there is nothing loaded currently, then set authors directly // unless there is nothing loaded currently, then set authors directly
if (authors.size()) if (authors.size())
{ {
// Don't add if it's exactly the same
if (stampAuthors["links"].size() == 1 && stampAuthors["links"][0] == Client::Ref().authors)
return;
if (authors["username"] != stampAuthors["username"]) if (authors["username"] != stampAuthors["username"])
{ {
// Don't add if it's exactly the same // 2nd arg of MergeAuthorInfo needs to be an array
if (stampAuthors["links"].size() != 1 || stampAuthors["links"][0] != Client::Ref().authors) Json::Value toAdd;
{ toAdd.append(stampAuthors);
// 2nd arg of MergeAuthorInfo needs to be an array MergeAuthorInfo(toAdd);
Json::Value toAdd;
toAdd.append(stampAuthors);
MergeAuthorInfo(toAdd);
}
} }
else if (stampAuthors["links"].size()) else if (stampAuthors["links"].size())
{ {

View File

@@ -2346,7 +2346,7 @@ fin:
return (char*)outputData; return (char*)outputData;
} }
void GameSave::ConvertBsonToJson(bson_iterator *iter, Json::Value *j) void GameSave::ConvertBsonToJson(bson_iterator *iter, Json::Value *j, int depth)
{ {
bson_iterator subiter; bson_iterator subiter;
bson_iterator_subiterator(iter, &subiter); bson_iterator_subiterator(iter, &subiter);
@@ -2360,23 +2360,28 @@ void GameSave::ConvertBsonToJson(bson_iterator *iter, Json::Value *j)
else if (bson_iterator_type(&subiter) == BSON_INT) else if (bson_iterator_type(&subiter) == BSON_INT)
(*j)[key] = bson_iterator_int(&subiter); (*j)[key] = bson_iterator_int(&subiter);
else if (bson_iterator_type(&subiter) == BSON_LONG) else if (bson_iterator_type(&subiter) == BSON_LONG)
(*j)[key] = (Json::Value::Int64)bson_iterator_long(&subiter); (*j)[key] = (Json::Value::UInt64)bson_iterator_long(&subiter);
else if (bson_iterator_type(&subiter) == BSON_ARRAY) else if (bson_iterator_type(&subiter) == BSON_ARRAY && depth < 5)
{ {
bson_iterator arrayiter; bson_iterator arrayiter;
bson_iterator_subiterator(&subiter, &arrayiter); bson_iterator_subiterator(&subiter, &arrayiter);
int length = 0, length2 = 0;
while (bson_iterator_next(&arrayiter)) while (bson_iterator_next(&arrayiter))
{ {
if (bson_iterator_type(&arrayiter) == BSON_OBJECT && !strcmp(bson_iterator_key(&arrayiter), "part")) if (bson_iterator_type(&arrayiter) == BSON_OBJECT && !strcmp(bson_iterator_key(&arrayiter), "part"))
{ {
Json::Value tempPart; Json::Value tempPart;
ConvertBsonToJson(&arrayiter, &tempPart); ConvertBsonToJson(&arrayiter, &tempPart, depth + 1);
(*j)["links"].append(tempPart); (*j)["links"].append(tempPart);
length++;
} }
else if (bson_iterator_type(&arrayiter) == BSON_INT && !strcmp(bson_iterator_key(&arrayiter), "saveID")) else if (bson_iterator_type(&arrayiter) == BSON_INT && !strcmp(bson_iterator_key(&arrayiter), "saveID"))
{ {
(*j)["links"].append(bson_iterator_int(&arrayiter)); (*j)["links"].append(bson_iterator_int(&arrayiter));
} }
length2++;
if (length > (int)(40 / std::pow(depth+1, 2)) || length2 > 50)
break;
} }
} }
} }
@@ -2422,14 +2427,15 @@ void GameSave::ConvertJsonToBson(bson *b, Json::Value j, int depth)
bson_append_string(b, member.c_str(), j[member].asCString()); bson_append_string(b, member.c_str(), j[member].asCString());
else if (j[member].isBool()) else if (j[member].isBool())
bson_append_bool(b, member.c_str(), j[member].asBool()); bson_append_bool(b, member.c_str(), j[member].asBool());
else if (j[member].isInt() || j[member].isUInt()) else if (j[member].type() == Json::intValue)
bson_append_int(b, member.c_str(), j[member].asInt()); bson_append_int(b, member.c_str(), j[member].asInt());
else if (j[member].isInt64() || j[member].isUInt64()) else if (j[member].type() == Json::uintValue)
bson_append_long(b, member.c_str(), j[member].asInt64()); bson_append_long(b, member.c_str(), j[member].asInt64());
else if (j[member].isArray()) else if (j[member].isArray())
{ {
bson_append_start_array(b, member.c_str()); bson_append_start_array(b, member.c_str());
std::set<int> saveIDs = std::set<int>(); std::set<int> saveIDs = std::set<int>();
int length = 0;
for (Json::Value::ArrayIndex i = 0; i < j[member].size(); i++) for (Json::Value::ArrayIndex i = 0; i < j[member].size(); i++)
{ {
// only supports objects and ints here because that is all we need // only supports objects and ints here because that is all we need
@@ -2440,7 +2446,7 @@ void GameSave::ConvertJsonToBson(bson *b, Json::Value j, int depth)
} }
if (!j[member][i].isObject()) if (!j[member][i].isObject())
continue; continue;
if (depth > 4) if (depth > 4 || length > (int)(40 / std::pow(depth+1, 2)))
{ {
std::set<int> nestedSaveIDs = GetNestedSaveIDs(j[member][i]); std::set<int> nestedSaveIDs = GetNestedSaveIDs(j[member][i]);
saveIDs.insert(nestedSaveIDs.begin(), nestedSaveIDs.end()); saveIDs.insert(nestedSaveIDs.begin(), nestedSaveIDs.end());
@@ -2451,6 +2457,7 @@ void GameSave::ConvertJsonToBson(bson *b, Json::Value j, int depth)
ConvertJsonToBson(b, j[member][i], depth+1); ConvertJsonToBson(b, j[member][i], depth+1);
bson_append_finish_object(b); bson_append_finish_object(b);
} }
length++;
} }
for (std::set<int>::iterator iter = saveIDs.begin(), end = saveIDs.end(); iter != end; ++iter) for (std::set<int>::iterator iter = saveIDs.begin(), end = saveIDs.end(); iter != end; ++iter)
{ {

View File

@@ -117,7 +117,7 @@ private:
void readPSv(char * data, int dataLength); void readPSv(char * data, int dataLength);
char * serialiseOPS(unsigned int & dataSize); char * serialiseOPS(unsigned int & dataSize);
void ConvertJsonToBson(bson *b, Json::Value j, int depth = 0); void ConvertJsonToBson(bson *b, Json::Value j, int depth = 0);
void ConvertBsonToJson(bson_iterator *b, Json::Value *j); void ConvertBsonToJson(bson_iterator *b, Json::Value *j, int depth = 0);
}; };
#endif #endif