From cb2221ea7828af506507cc6489bed31945f9c51c Mon Sep 17 00:00:00 2001 From: Kai Dietrich Date: Wed, 21 Oct 2020 09:15:12 +0200 Subject: [PATCH 1/2] Add failing test for remove_comment() parsing zip_file::remove_comment() does some manual parsing on the dictionary and seems to miss some range check in case of broken input --- tests/test.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/test.cpp b/tests/test.cpp index 76558db..0481752 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -41017,6 +41017,56 @@ static const char *expected_content_types_string = " z; + z.assign(comment_crash_zip, comment_crash_zip+sizeof(comment_crash_zip)); + + miniz_cpp::zip_file f; + try + { + f.load(z); + } catch(const std::runtime_error &) + { + } +} + void write_existing() { std::ofstream stream(existing_file, std::ios::binary); @@ -41272,6 +41336,7 @@ void remove_existing() void test_zip() { + test_comment_crash_zip(); write_existing(); test_load_file(); test_load_stream(); From 0e1e15747dc3194c294e4f703f8e430cb4cba8c5 Mon Sep 17 00:00:00 2001 From: Kai Dietrich Date: Wed, 21 Oct 2020 09:59:28 +0200 Subject: [PATCH 2/2] Fix length checks in zip_file::remove_comment() --- zip_file.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zip_file.hpp b/zip_file.hpp index c324f70..befa3bf 100644 --- a/zip_file.hpp +++ b/zip_file.hpp @@ -5651,10 +5651,20 @@ class zip_file throw std::runtime_error("didn't find end of central directory signature"); } + if (position + 1 >= buffer_.size()) + { + throw std::runtime_error("central dictionary position invalid"); + } + uint16_t length = static_cast(buffer_[position + 1]); length = static_cast(length << 8) + static_cast(buffer_[position]); position += 2; + if (position + length > buffer_.size()) + { + throw std::runtime_error("comment too long"); + } + if(length != 0) { comment = std::string(buffer_.data() + position, buffer_.data() + position + length);