Skip to content

Commit c61f887

Browse files
committed
Resync embedded tinygltf
Notably fixes an issue where valid but empty gltf content is reported as a broken gltf, instead of just ignored.
1 parent 4293d4f commit c61f887

File tree

1 file changed

+52
-34
lines changed

1 file changed

+52
-34
lines changed

external/tinygltf/tiny_gltf.h

+52-34
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2626
// THE SOFTWARE.
2727

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

66536653
memcpy(&version, bytes + 4, 4);
66546654
swap4(&version);
6655-
memcpy(&length, bytes + 8, 4);
6655+
memcpy(&length, bytes + 8, 4); // Total glb size, including header and all chunks.
66566656
swap4(&length);
66576657
memcpy(&chunk0_length, bytes + 12, 4); // JSON data length
66586658
swap4(&chunk0_length);
@@ -6708,68 +6708,86 @@ bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,
67086708
bin_size_ = 0;
67096709
} else {
67106710
// Read Chunk1 info(BIN data)
6711-
// At least Chunk1 should have 12 bytes(8 bytes(header) + 4 bytes(bin
6712-
// payload could be 1~3 bytes, but need to be aligned to 4 bytes)
6713-
if ((header_and_json_size + 12ull) > uint64_t(length)) {
6711+
//
6712+
// issue-440:
6713+
// 'SHOULD' in glTF spec means 'RECOMMENDED',
6714+
// So there is a situation that Chunk1(BIN) is composed of zero-sized BIN data
6715+
// (chunksize(0) + binformat(BIN) = 8bytes).
6716+
//
6717+
if ((header_and_json_size + 8ull) > uint64_t(length)) {
67146718
if (err) {
67156719
(*err) =
67166720
"Insufficient storage space for Chunk1(BIN data). At least Chunk1 "
6717-
"Must have 4 or more bytes, but got " +
6721+
"Must have 8 or more bytes, but got " +
67186722
std::to_string((header_and_json_size + 8ull) - uint64_t(length)) +
67196723
".\n";
67206724
}
67216725
return false;
67226726
}
67236727

6724-
unsigned int chunk1_length; // 4 bytes
6725-
unsigned int chunk1_format; // 4 bytes;
6728+
unsigned int chunk1_length{0}; // 4 bytes
6729+
unsigned int chunk1_format{0}; // 4 bytes;
67266730
memcpy(&chunk1_length, bytes + header_and_json_size,
6727-
4); // JSON data length
6731+
4); // Bin data length
67286732
swap4(&chunk1_length);
67296733
memcpy(&chunk1_format, bytes + header_and_json_size + 4, 4);
67306734
swap4(&chunk1_format);
67316735

6732-
// std::cout << "chunk1_length = " << chunk1_length << "\n";
6733-
6734-
if (chunk1_length < 4) {
6736+
if (chunk1_format != 0x004e4942) {
67356737
if (err) {
6736-
(*err) = "Insufficient Chunk1(BIN) data size.";
6738+
(*err) = "Invalid chunkType for Chunk1.";
67376739
}
67386740
return false;
67396741
}
67406742

6741-
if ((chunk1_length % 4) != 0) {
6742-
if (strictness_==ParseStrictness::Permissive) {
6743-
if (warn) {
6744-
(*warn) += "BIN Chunk end is not aligned to a 4-byte boundary.\n";
6743+
if (chunk1_length == 0) {
6744+
6745+
if (header_and_json_size + 8 > uint64_t(length)) {
6746+
if (err) {
6747+
(*err) = "BIN Chunk header location exceeds the GLB size.";
67456748
}
6749+
return false;
67466750
}
6747-
else {
6751+
6752+
bin_data_ = nullptr;
6753+
6754+
} else {
6755+
6756+
// When BIN chunk size is not zero, at least Chunk1 should have 12 bytes(8 bytes(header) + 4 bytes(bin
6757+
// payload could be 1~3 bytes, but need to be aligned to 4 bytes)
6758+
6759+
if (chunk1_length < 4) {
67486760
if (err) {
6749-
(*err) = "BIN Chunk end is not aligned to a 4-byte boundary.";
6761+
(*err) = "Insufficient Chunk1(BIN) data size.";
67506762
}
67516763
return false;
67526764
}
6753-
}
67546765

6755-
if (uint64_t(chunk1_length) + header_and_json_size > uint64_t(length)) {
6756-
if (err) {
6757-
(*err) = "BIN Chunk data length exceeds the GLB size.";
6766+
if ((chunk1_length % 4) != 0) {
6767+
if (strictness_==ParseStrictness::Permissive) {
6768+
if (warn) {
6769+
(*warn) += "BIN Chunk end is not aligned to a 4-byte boundary.\n";
6770+
}
6771+
}
6772+
else {
6773+
if (err) {
6774+
(*err) = "BIN Chunk end is not aligned to a 4-byte boundary.";
6775+
}
6776+
return false;
6777+
}
67586778
}
6759-
return false;
6760-
}
67616779

6762-
if (chunk1_format != 0x004e4942) {
6763-
if (err) {
6764-
(*err) = "Invalid type for chunk1 data.";
6780+
// +8 chunk1 header size.
6781+
if (uint64_t(chunk1_length) + header_and_json_size + 8 > uint64_t(length)) {
6782+
if (err) {
6783+
(*err) = "BIN Chunk data length exceeds the GLB size.";
6784+
}
6785+
return false;
67656786
}
6766-
return false;
6767-
}
6768-
6769-
// std::cout << "chunk1_length = " << chunk1_length << "\n";
67706787

6771-
bin_data_ = bytes + header_and_json_size +
6772-
8; // 4 bytes (bin_buffer_length) + 4 bytes(bin_buffer_format)
6788+
bin_data_ = bytes + header_and_json_size +
6789+
8; // 4 bytes (bin_buffer_length) + 4 bytes(bin_buffer_format)
6790+
}
67736791

67746792
bin_size_ = size_t(chunk1_length);
67756793
}

0 commit comments

Comments
 (0)