Skip to content

Commit

Permalink
Resync embedded tinygltf
Browse files Browse the repository at this point in the history
Notably fixes an issue where valid but empty gltf content is
reported as a broken gltf, instead of just ignored.
  • Loading branch information
nyalldawson committed Jan 29, 2024
1 parent 4293d4f commit 1fd3def
Showing 1 changed file with 52 additions and 34 deletions.
86 changes: 52 additions & 34 deletions external/tinygltf/tiny_gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Version: - v2.8.18
// Version: - v2.8.20
// See https://github.com/syoyo/tinygltf/releases for release history.
//
// Tiny glTF loader is using following third party libraries:
Expand Down Expand Up @@ -6652,7 +6652,7 @@ bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,

memcpy(&version, bytes + 4, 4);
swap4(&version);
memcpy(&length, bytes + 8, 4);
memcpy(&length, bytes + 8, 4); // Total glb size, including header and all chunks.
swap4(&length);
memcpy(&chunk0_length, bytes + 12, 4); // JSON data length
swap4(&chunk0_length);
Expand Down Expand Up @@ -6708,68 +6708,86 @@ bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,
bin_size_ = 0;
} else {
// Read Chunk1 info(BIN data)
// At least Chunk1 should have 12 bytes(8 bytes(header) + 4 bytes(bin
// payload could be 1~3 bytes, but need to be aligned to 4 bytes)
if ((header_and_json_size + 12ull) > uint64_t(length)) {
//
// issue-440:
// 'SHOULD' in glTF spec means 'RECOMMENDED',
// So there is a situation that Chunk1(BIN) is composed of zero-sized BIN data
// (chunksize(0) + binformat(BIN) = 8bytes).
//
if ((header_and_json_size + 8ull) > uint64_t(length)) {
if (err) {
(*err) =
"Insufficient storage space for Chunk1(BIN data). At least Chunk1 "
"Must have 4 or more bytes, but got " +
"Must have 8 or more bytes, but got " +
std::to_string((header_and_json_size + 8ull) - uint64_t(length)) +
".\n";
}
return false;
}

unsigned int chunk1_length; // 4 bytes
unsigned int chunk1_format; // 4 bytes;
unsigned int chunk1_length{0}; // 4 bytes
unsigned int chunk1_format{0}; // 4 bytes;
memcpy(&chunk1_length, bytes + header_and_json_size,
4); // JSON data length
4); // Bin data length
swap4(&chunk1_length);
memcpy(&chunk1_format, bytes + header_and_json_size + 4, 4);
swap4(&chunk1_format);

// std::cout << "chunk1_length = " << chunk1_length << "\n";

if (chunk1_length < 4) {
if (chunk1_format != 0x004e4942) {
if (err) {
(*err) = "Insufficient Chunk1(BIN) data size.";
(*err) = "Invalid chunkType for Chunk1.";
}
return false;
}

if ((chunk1_length % 4) != 0) {
if (strictness_==ParseStrictness::Permissive) {
if (warn) {
(*warn) += "BIN Chunk end is not aligned to a 4-byte boundary.\n";
if (chunk1_length == 0) {

if (header_and_json_size + 8 > uint64_t(length)) {
if (err) {
(*err) = "BIN Chunk header location exceeds the GLB size.";
}
return false;
}
else {

bin_data_ = nullptr;

} else {

// When BIN chunk size is not zero, at least Chunk1 should have 12 bytes(8 bytes(header) + 4 bytes(bin
// payload could be 1~3 bytes, but need to be aligned to 4 bytes)

if (chunk1_length < 4) {
if (err) {
(*err) = "BIN Chunk end is not aligned to a 4-byte boundary.";
(*err) = "Insufficient Chunk1(BIN) data size.";
}
return false;
}
}

if (uint64_t(chunk1_length) + header_and_json_size > uint64_t(length)) {
if (err) {
(*err) = "BIN Chunk data length exceeds the GLB size.";
if ((chunk1_length % 4) != 0) {
if (strictness_==ParseStrictness::Permissive) {
if (warn) {
(*warn) += "BIN Chunk end is not aligned to a 4-byte boundary.\n";
}
}
else {
if (err) {
(*err) = "BIN Chunk end is not aligned to a 4-byte boundary.";
}
return false;
}
}
return false;
}

if (chunk1_format != 0x004e4942) {
if (err) {
(*err) = "Invalid type for chunk1 data.";
// +8 chunk1 header size.
if (uint64_t(chunk1_length) + header_and_json_size + 8 > uint64_t(length)) {
if (err) {
(*err) = "BIN Chunk data length exceeds the GLB size.";
}
return false;
}
return false;
}

// std::cout << "chunk1_length = " << chunk1_length << "\n";

bin_data_ = bytes + header_and_json_size +
8; // 4 bytes (bin_buffer_length) + 4 bytes(bin_buffer_format)
bin_data_ = bytes + header_and_json_size +
8; // 4 bytes (bin_buffer_length) + 4 bytes(bin_buffer_format)
}

bin_size_ = size_t(chunk1_length);
}
Expand Down

0 comments on commit 1fd3def

Please sign in to comment.