|
@@ -162,6 +162,9 @@ inline static bool ReadValue(Value &val, T &out) {
|
|
|
|
|
|
template <class T>
|
|
|
inline static bool ReadMember(Value &obj, const char *id, T &out) {
|
|
|
+ if (!obj.IsObject()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
Value::MemberIterator it = obj.FindMember(id);
|
|
|
if (it != obj.MemberEnd()) {
|
|
|
return ReadHelper<T>::Read(it->value, out);
|
|
@@ -176,6 +179,9 @@ inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
|
|
|
}
|
|
|
|
|
|
inline Value *FindMember(Value &val, const char *id) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(id);
|
|
|
return (it != val.MemberEnd()) ? &it->value : nullptr;
|
|
|
}
|
|
@@ -193,6 +199,9 @@ inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const ch
|
|
|
// Look-up functions with type checks. Context and extra context help the user identify the problem if there's an error.
|
|
|
|
|
|
inline Value *FindStringInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(memberId);
|
|
|
if (it == val.MemberEnd()) {
|
|
|
return nullptr;
|
|
@@ -204,6 +213,9 @@ inline Value *FindStringInContext(Value &val, const char *memberId, const char*
|
|
|
}
|
|
|
|
|
|
inline Value *FindNumberInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(memberId);
|
|
|
if (it == val.MemberEnd()) {
|
|
|
return nullptr;
|
|
@@ -215,6 +227,9 @@ inline Value *FindNumberInContext(Value &val, const char *memberId, const char*
|
|
|
}
|
|
|
|
|
|
inline Value *FindUIntInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(memberId);
|
|
|
if (it == val.MemberEnd()) {
|
|
|
return nullptr;
|
|
@@ -226,6 +241,9 @@ inline Value *FindUIntInContext(Value &val, const char *memberId, const char* co
|
|
|
}
|
|
|
|
|
|
inline Value *FindArrayInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(memberId);
|
|
|
if (it == val.MemberEnd()) {
|
|
|
return nullptr;
|
|
@@ -237,6 +255,9 @@ inline Value *FindArrayInContext(Value &val, const char *memberId, const char* c
|
|
|
}
|
|
|
|
|
|
inline Value *FindObjectInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
|
|
|
+ if (!val.IsObject()) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
Value::MemberIterator it = val.FindMember(memberId);
|
|
|
if (it == val.MemberEnd()) {
|
|
|
return nullptr;
|
|
@@ -886,7 +907,7 @@ inline void Accessor::Read(Value &obj, Asset &r) {
|
|
|
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
|
|
|
{
|
|
|
const Value* countValue = FindUInt(obj, "count");
|
|
|
- if (!countValue || countValue->GetInt() < 1)
|
|
|
+ if (!countValue || countValue->GetUint() < 1)
|
|
|
{
|
|
|
throw DeadlyImportError("A strictly positive count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
|
|
|
}
|
|
@@ -1105,7 +1126,9 @@ inline Accessor::Indexer::Indexer(Accessor &acc) :
|
|
|
template <class T>
|
|
|
T Accessor::Indexer::GetValue(int i) {
|
|
|
ai_assert(data);
|
|
|
- ai_assert(i * stride < accessor.GetMaxByteSize());
|
|
|
+ if (i * stride >= accessor.GetMaxByteSize()) {
|
|
|
+ throw DeadlyImportError("GLTF: Invalid index ", i, ", count out of range for buffer with stride ", stride, " and size ", accessor.GetMaxByteSize(), ".");
|
|
|
+ }
|
|
|
// Ensure that the memcpy doesn't overwrite the local.
|
|
|
const size_t sizeToCopy = std::min(elemSize, sizeof(T));
|
|
|
T value = T();
|