mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-14 15:35:54 +08:00
Fixed Bugs/Unit Tests Pass
Fixed bugs found by unit tests and got unit tests running with RapidJSON as well as nlohmann.
This commit is contained in:
parent
67e6160a9a
commit
06c30c4d04
@ -167,12 +167,12 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
|
||||
SECTION("parses valid numbers") {
|
||||
std::string err;
|
||||
int result = 123;
|
||||
CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"zero", 0}}, "zero",
|
||||
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"zero\" : 0}"), "zero",
|
||||
true));
|
||||
REQUIRE(err == "");
|
||||
REQUIRE(result == 0);
|
||||
|
||||
CHECK(tinygltf::ParseIntegerProperty(&result, &err, {{"int", -1234}}, "int",
|
||||
CHECK(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": -1234}"), "int",
|
||||
true));
|
||||
REQUIRE(err == "");
|
||||
REQUIRE(result == -1234);
|
||||
@ -181,7 +181,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
|
||||
SECTION("detects missing properties") {
|
||||
std::string err;
|
||||
int result = -1;
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {}, "int", true));
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("'int' property is missing"));
|
||||
REQUIRE(result == -1);
|
||||
}
|
||||
@ -190,7 +190,7 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
|
||||
std::string err;
|
||||
int result = -1;
|
||||
CHECK_FALSE(
|
||||
tinygltf::ParseIntegerProperty(&result, &err, {}, "int", false));
|
||||
tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct(""), "int", false));
|
||||
REQUIRE(err == "");
|
||||
REQUIRE(result == -1);
|
||||
}
|
||||
@ -199,29 +199,34 @@ TEST_CASE("parse-integer", "[bounds-checking]") {
|
||||
std::string err;
|
||||
int result = -1;
|
||||
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 0.5}},
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"),
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||
|
||||
// Excessively large values and NaN aren't allowed either.
|
||||
err.clear();
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, {{"int", 1e300}},
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"),
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||
|
||||
err.clear();
|
||||
{
|
||||
JsonDocument o;
|
||||
double nan = std::numeric_limits<double>::quiet_NaN();
|
||||
tinygltf::JsonAddMember(o, "int", json(nan));
|
||||
CHECK_FALSE(tinygltf::ParseIntegerProperty(
|
||||
&result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
|
||||
&result, &err, o,
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("parse-unsigned", "[bounds-checking]") {
|
||||
SECTION("parses valid unsigned integers") {
|
||||
// Use string-based parsing here, using the initializer list syntax doesn't
|
||||
// parse 0 as unsigned.
|
||||
json zero_obj = json::parse("{\"zero\": 0}");
|
||||
auto zero_obj = JsonConstruct("{\"zero\": 0}");
|
||||
|
||||
std::string err;
|
||||
size_t result = 123;
|
||||
@ -235,35 +240,40 @@ TEST_CASE("parse-unsigned", "[bounds-checking]") {
|
||||
std::string err;
|
||||
size_t result = -1;
|
||||
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", -1234}},
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": -1234}"),
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
|
||||
|
||||
err.clear();
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 0.5}},
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 0.5}"),
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
|
||||
|
||||
// Excessively large values and NaN aren't allowed either.
|
||||
err.clear();
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, {{"int", 1e300}},
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(&result, &err, JsonConstruct("{\"int\": 1e300}"),
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
|
||||
|
||||
err.clear();
|
||||
{
|
||||
JsonDocument o;
|
||||
double nan = std::numeric_limits<double>::quiet_NaN();
|
||||
tinygltf::JsonAddMember(o, "int", json(nan));
|
||||
CHECK_FALSE(tinygltf::ParseUnsignedProperty(
|
||||
&result, &err, {{"int", std::numeric_limits<double>::quiet_NaN()}},
|
||||
&result, &err, o,
|
||||
"int", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not a positive integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("parse-integer-array", "[bounds-checking]") {
|
||||
SECTION("parses valid integers") {
|
||||
std::string err;
|
||||
std::vector<int> result;
|
||||
CHECK(tinygltf::ParseIntegerArrayProperty(&result, &err,
|
||||
{{"x", {-1, 2, 3}}}, "x", true));
|
||||
JsonConstruct("{\"x\": [-1, 2, 3]}"), "x", true));
|
||||
REQUIRE(err == "");
|
||||
REQUIRE(result.size() == 3);
|
||||
REQUIRE(result[0] == -1);
|
||||
@ -275,7 +285,7 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
|
||||
std::string err;
|
||||
std::vector<int> result;
|
||||
CHECK_FALSE(tinygltf::ParseIntegerArrayProperty(
|
||||
&result, &err, {{"x", {-1, 1e300, 3}}}, "x", true));
|
||||
&result, &err, JsonConstruct("{\"x\": [-1, 1e300, 3]}"), "x", true));
|
||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||
}
|
||||
}
|
||||
|
65
tiny_gltf.h
65
tiny_gltf.h
@ -1637,9 +1637,20 @@ namespace
|
||||
assert(s_pActiveDocument == nullptr); //Code assumes only one document is active at a time
|
||||
s_pActiveDocument = this;
|
||||
}
|
||||
JsonDocument(const JsonDocument&) = delete;
|
||||
JsonDocument(JsonDocument&& rhs) noexcept : rapidjson::Document(std::move(rhs))
|
||||
{
|
||||
s_pActiveDocument = this;
|
||||
rhs.isNil = true;
|
||||
}
|
||||
~JsonDocument() {
|
||||
if (!isNil)
|
||||
{
|
||||
s_pActiveDocument = nullptr;
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool isNil = false;
|
||||
};
|
||||
#else
|
||||
using nlohmann::json;
|
||||
@ -1656,6 +1667,13 @@ namespace
|
||||
doc = json::parse(str, str + length, nullptr, throwExc);
|
||||
#endif
|
||||
}
|
||||
|
||||
JsonDocument JsonConstruct(const char* str)
|
||||
{
|
||||
JsonDocument doc;
|
||||
JsonParse(doc, str, strlen(str));
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -2881,6 +2899,10 @@ namespace
|
||||
bool FindMember(const json& o, const char* member, json_const_iterator& it)
|
||||
{
|
||||
#ifdef TINYGLTF_USE_RAPIDJSON
|
||||
if (!o.IsObject())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
it = o.FindMember(member);
|
||||
return it != o.MemberEnd();
|
||||
#else
|
||||
@ -3476,7 +3498,7 @@ static bool ParseExtensionsProperty(ExtensionMap *ret, std::string *err,
|
||||
if (!IsObject(itObj)) continue;
|
||||
std::string key(GetKey(extIt));
|
||||
if (!ParseJsonAsValue(&extensions[key], itObj)) {
|
||||
if (key.empty()) {
|
||||
if (!key.empty()) {
|
||||
// create empty object so that an extension object is still of type
|
||||
// object
|
||||
extensions[key] = Value{Value::Object{}};
|
||||
@ -4436,13 +4458,27 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
||||
|
||||
for (; it != itEnd; ++it) {
|
||||
std::string key(GetKey(it));
|
||||
if (key == "pbrMetallicRoughness") {
|
||||
if (IsObject(GetValue(it))) {
|
||||
const json &values_object = GetValue(it);
|
||||
|
||||
if ((key == "pbrMetallicRoughness") ||
|
||||
(key == "extensions") ||
|
||||
(key == "extras")) {
|
||||
continue; //Remove duplicating these in parameters
|
||||
json_const_iterator itVal(ObjectBegin(values_object));
|
||||
json_const_iterator itValEnd(ObjectEnd(values_object));
|
||||
|
||||
for (; itVal != itValEnd; ++itVal) {
|
||||
Parameter param;
|
||||
if (ParseParameterProperty(¶m, err, values_object, GetKey(itVal),
|
||||
false)) {
|
||||
material->values.emplace(GetKey(itVal), std::move(param));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (key == "extensions" || key == "extras") {
|
||||
// done later, skip, otherwise poorly parsed contents will be saved in the
|
||||
// parametermap and serialized again later
|
||||
}
|
||||
else {
|
||||
Parameter param;
|
||||
if (ParseParameterProperty(¶m, err, o, key, false)) {
|
||||
// names of materials have already been parsed. Putting it in this map
|
||||
@ -4450,6 +4486,7 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
||||
if (key != "name") material->additionalValues.emplace(std::move(key), std::move(param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material->extensions.clear();
|
||||
ParseExtensionsProperty(&material->extensions, err, o);
|
||||
@ -5607,8 +5644,8 @@ bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err,
|
||||
///////////////////////
|
||||
// GLTF Serialization
|
||||
///////////////////////
|
||||
namespace
|
||||
{
|
||||
//namespace
|
||||
//{
|
||||
json JsonFromString(const char* s)
|
||||
{
|
||||
#ifdef TINYGLTF_USE_RAPIDJSON
|
||||
@ -5680,6 +5717,15 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
void JsonSetObject(json& o)
|
||||
{
|
||||
#ifdef TINYGLTF_USE_RAPIDJSON
|
||||
o.SetObject();
|
||||
#else
|
||||
o = o.object({});
|
||||
#endif
|
||||
}
|
||||
|
||||
void JsonReserveArray(json& o, size_t s)
|
||||
{
|
||||
#ifdef TINYGLTF_USE_RAPIDJSON
|
||||
@ -5689,7 +5735,7 @@ namespace
|
||||
(void)(o);
|
||||
(void)(s);
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
// typedef std::pair<std::string, json> json_object_pair;
|
||||
|
||||
@ -5903,6 +5949,7 @@ static void SerializeExtensionMap(ExtensionMap &extensions, json &o) {
|
||||
// create empty object so that an extension name is still included in
|
||||
// json.
|
||||
json empty;
|
||||
JsonSetObject(empty);
|
||||
JsonAddMember(extMap, extIt->first.c_str(), std::move(empty));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user