[Pkg-kde-extras] Bug#1028395: bullseye-pu: package exiv2/0.27.3-3+deb11u2
Helmut Grohne
helmut at subdivi.de
Tue Jan 10 12:31:51 GMT 2023
Package: release.debian.org
Tags: bullseye
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: exiv2 at packages.debian.org, Mark Purcell <msp at debian.org>, Steve M. Robbins <smr at debian.org>
Control: affects -1 + src:exiv2
I've been working on an exiv2 security update. A significant number of
vulnerabilities have piled up and they're all tagged no-dsa. I propose
fixing them via the stable update procedure.
[ Reason ]
Hopefully obvious.
[ Impact ]
Ideally, a user shouldn't notice a difference. In some cases, the error
message for interacting with broken files changes.
[ Tests ]
I've enabled the unit test suite and the regression test suite (in
Python) during build. Unfortunately, the package previously didn't run
any tests. As a consequence, I've made the testsuite non-fatal even
though it doesn't fail any tests on amd64. Additionally I've run tests
under valgrind.
[ Risks ]
Yeah, this is a bit of code that changes. There is some risk.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
-> Note that binary changes are not representable, so I'm also
attaching the dsc.
[x] the issue is verified as fixed in unstable
[ Changes ]
The biggest chunk of changes is fixes for various vulnerabilities like
integer overflows and buffer overruns. The other part is enabling the
running of tests.
[ Other info ]
I don't think that I'm interested in putting much more effort into this.
You see, I'll be fixing this for LTS/ELTS and trying to do a drive-by
contribution to stable here. If you feel like, this needs extra work,
say "no" quickly.
Helmut
-------------- next part --------------
diff --minimal -Nru exiv2-0.27.3/debian/changelog exiv2-0.27.3/debian/changelog
--- exiv2-0.27.3/debian/changelog 2021-08-06 10:57:42.000000000 +0200
+++ exiv2-0.27.3/debian/changelog 2023-01-05 18:19:20.000000000 +0100
@@ -1,3 +1,29 @@
+exiv2 (0.27.3-3+deb11u2) bullseye; urgency=medium
+
+ * Non-maintainer upload by the LTS Team.
+ * Fix CVE-2021-3482 (Closes: #986888)
+ * Fix CVE-2021-29458 (Closes: #987277)
+ + This is a more complete fix of duplicate CVE-2021-31292
+ * Fix CVE-2021-29463 (Closes: #988241)
+ * Fix CVE-2021-29464 (Closes: #988242)
+ * Fix CVE-2021-29470 (Closes: #987450)
+ * Fix CVE-2021-29473 (Closes: #987736)
+ * Fix CVE-2021-29623 (Closes: #988481)
+ * Fix CVE-2021-32815 (Closes: #992705)
+ * Fix CVE-2021-34334 (Closes: #992706)
+ * Fix CVE-2021-34335 (Closes: #992707)
+ * Fix CVE-2021-37615
+ + Also fixes CVE-2021-37616
+ * Fix CVE-2021-37618
+ * Fix CVE-2021-37619
+ * Fix CVE-2021-37620
+ * Fix CVE-2021-37621
+ * Fix CVE-2021-37622
+ * Fix CVE-2021-37623
+ * Run unit and python tests without making the build fail.
+
+ -- Helmut Grohne <helmut at subdivi.de> Thu, 05 Jan 2023 18:19:20 +0100
+
exiv2 (0.27.3-3+deb11u1) bullseye-security; urgency=medium
* CVE-2021-31291 (Closes: #991705)
diff --minimal -Nru exiv2-0.27.3/debian/control exiv2-0.27.3/debian/control
--- exiv2-0.27.3/debian/control 2020-08-08 19:20:52.000000000 +0200
+++ exiv2-0.27.3/debian/control 2023-01-05 18:19:20.000000000 +0100
@@ -9,6 +9,7 @@
debhelper-compat (= 12),
gettext,
libexpat1-dev,
+ libgtest-dev <!nocheck>,
pkg-kde-tools,
zlib1g-dev
Build-Depends-Indep: doxygen, graphviz, libjs-jquery, xsltproc
diff --minimal -Nru exiv2-0.27.3/debian/not-installed exiv2-0.27.3/debian/not-installed
--- exiv2-0.27.3/debian/not-installed 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/not-installed 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,29 @@
+usr/bin/addmoddel
+usr/bin/convert-test
+usr/bin/easyaccess-test
+usr/bin/exifcomment
+usr/bin/exifdata-test
+usr/bin/exifdata
+usr/bin/exifprint
+usr/bin/exifvalue
+usr/bin/ini-test
+usr/bin/iotest
+usr/bin/iptceasy
+usr/bin/iptcprint
+usr/bin/iptctest
+usr/bin/key-test
+usr/bin/largeiptc-test
+usr/bin/mmap-test
+usr/bin/mrwthumb
+usr/bin/prevtest
+usr/bin/stringto-test
+usr/bin/taglist
+usr/bin/tiff-test
+usr/bin/werror-test
+usr/bin/write-test
+usr/bin/write2-test
+usr/bin/xmpparse
+usr/bin/xmpparser-test
+usr/bin/xmpprint
+usr/bin/xmpsample
+usr/bin/xmpdump
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29458.patch exiv2-0.27.3/debian/patches/CVE-2021-29458.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29458.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29458.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,103 @@
+From 0a91b56616404f7b29ca28deb01ce18b767d1871 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 9 Apr 2021 13:26:23 +0100
+Subject: [PATCH 1/5] Fix incorrect delete.
+
+---
+ src/crwimage_int.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+From c92ac88cb0ebe72a5a17654fe6cecf411ab1e572 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 9 Apr 2021 13:06:57 +0100
+Subject: [PATCH 2/5] Regression test for
+ https://github.com/Exiv2/exiv2/issues/1530
+
+---
+ test/data/issue_1530_poc.crw | Bin 0 -> 10078 bytes
+ test/data/issue_1530_poc.exv | Bin 0 -> 4793 bytes
+ tests/bugfixes/github/test_issue_1530.py | 20 ++++++++++++++++++++
+ 3 files changed, 20 insertions(+)
+ create mode 100644 test/data/issue_1530_poc.crw
+ create mode 100644 test/data/issue_1530_poc.exv
+ create mode 100644 tests/bugfixes/github/test_issue_1530.py
+
+From 9b7a19f957af53304655ed1efe32253a1b11a8d0 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 9 Apr 2021 13:37:48 +0100
+Subject: [PATCH 3/5] Fix integer overflow.
+
+---
+ src/crwimage_int.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+From fadb68718eb1bff3bd3222bd26ff3328f5306730 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 9 Apr 2021 13:47:18 +0100
+Subject: [PATCH 4/5] Fix test name
+
+---
+ tests/bugfixes/github/test_issue_1530.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+From 06d2db6e5fd2fcca9c060e95fc97f8a5b5d4c22d Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 9 Apr 2021 16:17:50 +0100
+Subject: [PATCH 5/5] Use $kerCorruptedMetadata, rather than hard-coded string.
+
+---
+ tests/bugfixes/github/test_issue_1530.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp
+index a44a67e2..6f89fa8b 100644
+--- a/src/crwimage_int.cpp
++++ b/src/crwimage_int.cpp
+@@ -579,7 +579,7 @@ namespace Exiv2 {
+ void CiffComponent::setValue(DataBuf buf)
+ {
+ if (isAllocated_) {
+- delete pData_;
++ delete[] pData_;
+ pData_ = 0;
+ size_ = 0;
+ }
+@@ -1187,7 +1187,11 @@ namespace Exiv2 {
+ pCrwMapping->crwDir_);
+ if (edX != edEnd || edY != edEnd || edO != edEnd) {
+ uint32_t size = 28;
+- if (cc && cc->size() > size) size = cc->size();
++ if (cc) {
++ if (cc->size() < size)
++ throw Error(kerCorruptedMetadata);
++ size = cc->size();
++ }
+ DataBuf buf(size);
+ std::memset(buf.pData_, 0x0, buf.size_);
+ if (cc) std::memcpy(buf.pData_ + 8, cc->pData() + 8, cc->size() - 8);
+diff --git a/tests/bugfixes/github/test_issue_1530.py b/tests/bugfixes/github/test_issue_1530.py
+new file mode 100644
+index 00000000..8c19073a
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_1530.py
+@@ -0,0 +1,20 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path
++
++
++class CrwEncode0x1810IntegerOverflow(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/issues/1530
++ """
++ url = "https://github.com/Exiv2/exiv2/issues/1530"
++
++ filename1 = path("$data_path/issue_1530_poc.crw")
++ filename2 = path("$data_path/issue_1530_poc.exv")
++ commands = ["$exiv2 in $filename1 $filename2"]
++ stdout = [""]
++ stderr = [
++"""$filename1: Could not write metadata to file: $kerCorruptedMetadata
++"""]
++ retval = [1]
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29463.patch exiv2-0.27.3/debian/patches/CVE-2021-29463.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29463.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29463.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,123 @@
+From 783b3a6ff15ed6f82a8f8e6c8a6f3b84a9b04d4b Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Mon, 19 Apr 2021 18:06:00 +0100
+Subject: [PATCH] Improve bound checking in WebPImage::doWriteMetadata()
+
+---
+ src/webpimage.cpp | 41 ++++++++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 11 deletions(-)
+
+diff --git a/src/webpimage.cpp b/src/webpimage.cpp
+index 4ddec544..fee110bc 100644
+--- a/src/webpimage.cpp
++++ b/src/webpimage.cpp
+@@ -145,7 +145,7 @@ namespace Exiv2 {
+ DataBuf chunkId(WEBP_TAG_SIZE+1);
+ chunkId.pData_ [WEBP_TAG_SIZE] = '\0';
+
+- io_->read(data, WEBP_TAG_SIZE * 3);
++ readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
+ uint64_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian);
+
+ /* Set up header */
+@@ -185,13 +185,20 @@ namespace Exiv2 {
+ case we have any exif or xmp data, also check
+ for any chunks with alpha frame/layer set */
+ while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
+- io_->read(chunkId.pData_, WEBP_TAG_SIZE);
+- io_->read(size_buff, WEBP_TAG_SIZE);
+- long size = Exiv2::getULong(size_buff, littleEndian);
++ readOrThrow(*io_, chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
++ readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
++ const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
++
++ // Check that `size_u32` is safe to cast to `long`.
++ enforce(size_u32 <= static_cast<size_t>(std::numeric_limits<unsigned int>::max()),
++ Exiv2::kerCorruptedMetadata);
++ const long size = static_cast<long>(size_u32);
+ DataBuf payload(size);
+- io_->read(payload.pData_, payload.size_);
+- byte c;
+- if ( payload.size_ % 2 ) io_->read(&c,1);
++ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
++ if ( payload.size_ % 2 ) {
++ byte c;
++ readOrThrow(*io_, &c, 1, Exiv2::kerCorruptedMetadata);
++ }
+
+ /* Chunk with information about features
+ used in the file. */
+@@ -199,6 +206,7 @@ namespace Exiv2 {
+ has_vp8x = true;
+ }
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_size) {
++ enforce(size >= 10, Exiv2::kerCorruptedMetadata);
+ has_size = true;
+ byte size_buf[WEBP_TAG_SIZE];
+
+@@ -227,6 +235,7 @@ namespace Exiv2 {
+ }
+ #endif
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_size) {
++ enforce(size >= 10, Exiv2::kerCorruptedMetadata);
+ has_size = true;
+ byte size_buf[2];
+
+@@ -244,11 +253,13 @@ namespace Exiv2 {
+
+ /* Chunk with with lossless image data. */
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_alpha) {
++ enforce(size >= 5, Exiv2::kerCorruptedMetadata);
+ if ((payload.pData_[4] & WEBP_VP8X_ALPHA_BIT) == WEBP_VP8X_ALPHA_BIT) {
+ has_alpha = true;
+ }
+ }
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_size) {
++ enforce(size >= 5, Exiv2::kerCorruptedMetadata);
+ has_size = true;
+ byte size_buf_w[2];
+ byte size_buf_h[3];
+@@ -276,11 +287,13 @@ namespace Exiv2 {
+
+ /* Chunk with animation frame. */
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_alpha) {
++ enforce(size >= 6, Exiv2::kerCorruptedMetadata);
+ if ((payload.pData_[5] & 0x2) == 0x2) {
+ has_alpha = true;
+ }
+ }
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_size) {
++ enforce(size >= 12, Exiv2::kerCorruptedMetadata);
+ has_size = true;
+ byte size_buf[WEBP_TAG_SIZE];
+
+@@ -309,16 +322,22 @@ namespace Exiv2 {
+
+ io_->seek(12, BasicIo::beg);
+ while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
+- io_->read(chunkId.pData_, 4);
+- io_->read(size_buff, 4);
++ readOrThrow(*io_, chunkId.pData_, 4, Exiv2::kerCorruptedMetadata);
++ readOrThrow(*io_, size_buff, 4, Exiv2::kerCorruptedMetadata);
++
++ const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
+
+- long size = Exiv2::getULong(size_buff, littleEndian);
++ // Check that `size_u32` is safe to cast to `long`.
++ enforce(size_u32 <= static_cast<size_t>(std::numeric_limits<unsigned int>::max()),
++ Exiv2::kerCorruptedMetadata);
++ const long size = static_cast<long>(size_u32);
+
+ DataBuf payload(size);
+- io_->read(payload.pData_, size);
++ readOrThrow(*io_, payload.pData_, size, Exiv2::kerCorruptedMetadata);
+ if ( io_->tell() % 2 ) io_->seek(+1,BasicIo::cur); // skip pad
+
+ if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X)) {
++ enforce(size >= 1, Exiv2::kerCorruptedMetadata);
+ if (has_icc){
+ payload.pData_[0] |= WEBP_VP8X_ICC_BIT;
+ } else {
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29464.patch exiv2-0.27.3/debian/patches/CVE-2021-29464.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29464.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29464.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,85 @@
+From f9308839198aca5e68a65194f151a1de92398f54 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 20 Apr 2021 12:04:13 +0100
+Subject: [PATCH] Better bounds checking in Jp2Image::encodeJp2Header()
+
+---
+ src/jp2image.cpp | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 22ed9b157bd6f3b1233c62b8625e6e93bf56f512
+Author: Robin Mills <robin at clanmills.com>
+Date: Wed Jul 8 13:51:51 2020 +0100
+
+ Fixed typo declaration of pad when writing ICC profile.
+
+Backport:
+ * fix newlen computation according to what happened upstream in refactoring
+
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index 1661151b..2689c473 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -646,11 +646,11 @@ static void boxes_check(size_t b,size_t m)
+ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf,DataBuf& outBuf)
+ {
+ DataBuf output(boxBuf.size_ + iccProfile_.size_ + 100); // allocate sufficient space
+- int outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output?
+- int inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf?
++ long outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output?
++ long inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf?
+ Jp2BoxHeader* pBox = (Jp2BoxHeader*) boxBuf.pData_;
+- int32_t length = getLong((byte*)&pBox->length, bigEndian);
+- int32_t count = sizeof (Jp2BoxHeader);
++ uint32_t length = getLong((byte*)&pBox->length, bigEndian);
++ uint32_t count = sizeof (Jp2BoxHeader);
+ char* p = (char*) boxBuf.pData_;
+ bool bWroteColor = false ;
+
+@@ -667,6 +667,7 @@ static void boxes_check(size_t b,size_t m)
+ #ifdef EXIV2_DEBUG_MESSAGES
+ std::cout << "Jp2Image::encodeJp2Header subbox: "<< toAscii(subBox.type) << " length = " << subBox.length << std::endl;
+ #endif
++ enforce(subBox.length <= length - count, Exiv2::kerCorruptedMetadata);
+ count += subBox.length;
+ newBox.type = subBox.type;
+ } else {
+@@ -675,28 +676,31 @@ static void boxes_check(size_t b,size_t m)
+ count = length;
+ }
+
+- int32_t newlen = subBox.length;
++ uint32_t newlen = subBox.length;
+ if ( newBox.type == kJp2BoxTypeColorHeader ) {
+ bWroteColor = true ;
+ if ( ! iccProfileDefined() ) {
+ const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid";
+ uint32_t psize = 15;
++ newlen = sizeof(newBox) + psize;
++ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
+ ul2Data((byte*)&newBox.length,psize ,bigEndian);
+ ul2Data((byte*)&newBox.type ,newBox.type,bigEndian);
+ ::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox));
+ ::memcpy(output.pData_+outlen+sizeof(newBox) ,pad ,psize );
+- newlen = psize ;
+ } else {
+- const char* pad = "\0x02\x00\x00";
++ const char* pad = "\x02\x00\x00";
+ uint32_t psize = 3;
++ newlen = sizeof(newBox) + psize + iccProfile_.size_;
++ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
+ ul2Data((byte*)&newBox.length,psize+iccProfile_.size_,bigEndian);
+ ul2Data((byte*)&newBox.type,newBox.type,bigEndian);
+ ::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox) );
+ ::memcpy(output.pData_+outlen+sizeof(newBox) , pad ,psize );
+ ::memcpy(output.pData_+outlen+sizeof(newBox)+psize,iccProfile_.pData_,iccProfile_.size_);
+- newlen = psize + iccProfile_.size_;
+ }
+ } else {
++ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
+ ::memcpy(output.pData_+outlen,boxBuf.pData_+inlen,subBox.length);
+ }
+
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29470.patch exiv2-0.27.3/debian/patches/CVE-2021-29470.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29470.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29470.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,73 @@
+From b3de96f4b4408347bed57e625963720e8d0dd2ea Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 21 Apr 2021 12:06:04 +0100
+Subject: [PATCH 1/2] Add more bounds checks in Jp2Image::encodeJp2Header
+
+---
+ src/jp2image.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+From c372f2677d6f7cf88a8f26ef6bc175561e406ee2 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 21 Apr 2021 12:15:50 +0100
+Subject: [PATCH 2/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-8949-hhfh-j7rj
+
+---
+ test/data/issue_ghsa_8949_hhfh_j7rj_poc.exv | Bin 0 -> 1959 bytes
+ test/data/issue_ghsa_8949_hhfh_j7rj_poc.jp2 | Bin 0 -> 40609 bytes
+ .../github/test_issue_ghsa_8949_hhfh_j7rj.py | 22 ++++++++++++++++++
+ 3 files changed, 22 insertions(+)
+ create mode 100644 test/data/issue_ghsa_8949_hhfh_j7rj_poc.exv
+ create mode 100644 test/data/issue_ghsa_8949_hhfh_j7rj_poc.jp2
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
+
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index a60a136a..d78da712 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -648,13 +648,16 @@ static void boxes_check(size_t b,size_t m)
+ DataBuf output(boxBuf.size_ + iccProfile_.size_ + 100); // allocate sufficient space
+ long outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output?
+ long inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf?
++ enforce(sizeof(Jp2BoxHeader) <= static_cast<size_t>(output.size_), Exiv2::kerCorruptedMetadata);
+ Jp2BoxHeader* pBox = (Jp2BoxHeader*) boxBuf.pData_;
+ uint32_t length = getLong((byte*)&pBox->length, bigEndian);
++ enforce(length <= static_cast<size_t>(output.size_), Exiv2::kerCorruptedMetadata);
+ uint32_t count = sizeof (Jp2BoxHeader);
+ char* p = (char*) boxBuf.pData_;
+ bool bWroteColor = false ;
+
+ while ( count < length || !bWroteColor ) {
++ enforce(sizeof(Jp2BoxHeader) <= length - count, Exiv2::kerCorruptedMetadata);
+ Jp2BoxHeader* pSubBox = (Jp2BoxHeader*) (p+count) ;
+
+ // copy data. pointer could be into a memory mapped file which we will decode!
+diff --git a/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py b/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
+new file mode 100644
+index 00000000..c98b3815
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
+@@ -0,0 +1,22 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path
++
++
++class Jp2ImageEncodeJp2HeaderOutOfBoundsRead(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-8949-hhfh-j7rj
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-8949-hhfh-j7rj"
++
++ filename1 = path("$data_path/issue_ghsa_8949_hhfh_j7rj_poc.jp2")
++ filename2 = path("$data_path/issue_ghsa_8949_hhfh_j7rj_poc.exv")
++ commands = ["$exiv2 in $filename1"]
++ stdout = [""]
++ stderr = [
++"""Error: XMP Toolkit error 201: XML parsing failure
++Warning: Failed to decode XMP metadata.
++$filename1: Could not write metadata to file: $kerCorruptedMetadata
++"""]
++ retval = [1]
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29473.patch exiv2-0.27.3/debian/patches/CVE-2021-29473.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29473.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29473.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,66 @@
+From f0ff11f044b2c8ddf4792415beb91fd815c633a1 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 23 Apr 2021 11:43:59 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-7569-phvm-vwc2
+
+---
+ test/data/issue_ghsa_7569_phvm_vwc2_poc.exv | Bin 0 -> 51 bytes
+ test/data/issue_ghsa_7569_phvm_vwc2_poc.jp2 | Bin 0 -> 4248 bytes
+ .../github/test_issue_ghsa_7569_phvm_vwc2.py | 24 ++++++++++++++++++
+ 3 files changed, 24 insertions(+)
+ create mode 100644 test/data/issue_ghsa_7569_phvm_vwc2_poc.exv
+ create mode 100644 test/data/issue_ghsa_7569_phvm_vwc2_poc.jp2
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py
+
+From e6a0982f7cd9282052b6e3485a458d60629ffa0b Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 23 Apr 2021 11:44:44 +0100
+Subject: [PATCH 2/2] Add bounds check in Jp2Image::doWriteMetadata().
+
+---
+ src/jp2image.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py b/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py
+new file mode 100644
+index 00000000..c201576b
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py
+@@ -0,0 +1,24 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path
++
++
++class Jp2ImageDoWriteMetadataOutOfBoundsRead(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-7569-phvm-vwc2
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-7569-phvm-vwc2"
++
++ filename1 = path("$data_path/issue_ghsa_7569_phvm_vwc2_poc.jp2")
++ filename2 = path("$data_path/issue_ghsa_7569_phvm_vwc2_poc.exv")
++ commands = ["$exiv2 in $filename1"]
++ stdout = [""]
++ stderr = [
++"""Warning: Directory Thumbnail, entry 0x1000 has unknown Exif (TIFF) type 28928; setting type size 1.
++Error: Directory Thumbnail: IFD entry 1 lies outside of the data buffer.
++Warning: Directory Thumbnail, entry 0x1000 has unknown Exif (TIFF) type 28928; setting type size 1.
++Error: Offset of directory Thumbnail, entry 0x1000 is out of bounds: Offset = 0x2020506a; truncating the entry
++$filename1: Could not write metadata to file: $kerCorruptedMetadata
++"""]
++ retval = [1]
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index 1694fed2..ca8c9ddb 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -908,6 +908,7 @@ static void boxes_check(size_t b,size_t m)
+
+ case kJp2BoxTypeUuid:
+ {
++ enforce(boxBuf.size_ >= 24, Exiv2::kerCorruptedMetadata);
+ if(memcmp(boxBuf.pData_ + 8, kJp2UuidExif, 16) == 0)
+ {
+ #ifdef EXIV2_DEBUG_MESSAGES
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-29623.patch exiv2-0.27.3/debian/patches/CVE-2021-29623.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-29623.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-29623.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,30 @@
+From ca661360921b5538321edc1e477ecc58cefe7cc5 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 11 May 2021 12:14:33 +0100
+Subject: [PATCH] Use readOrThrow to check error conditions of iIo.read().
+
+(cherry picked from commit 0f9eb74c44c908e170a64cab590949d53749af8e)
+---
+ src/webpimage.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/webpimage.cpp b/src/webpimage.cpp
+index 07a818d6..1de60218 100644
+--- a/src/webpimage.cpp
++++ b/src/webpimage.cpp
+@@ -754,9 +754,9 @@ namespace Exiv2 {
+ byte webp[len];
+ byte data[len];
+ byte riff[len];
+- iIo.read(riff, len);
+- iIo.read(data, len);
+- iIo.read(webp, len);
++ readOrThrow(iIo, riff, len, Exiv2::kerCorruptedMetadata);
++ readOrThrow(iIo, data, len, Exiv2::kerCorruptedMetadata);
++ readOrThrow(iIo, webp, len, Exiv2::kerCorruptedMetadata);
+ bool matched_riff = (memcmp(riff, RiffImageId, len) == 0);
+ bool matched_webp = (memcmp(webp, WebPImageId, len) == 0);
+ iIo.seek(-12, BasicIo::cur);
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-31292.patch exiv2-0.27.3/debian/patches/CVE-2021-31292.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-31292.patch 2021-08-06 10:57:26.000000000 +0200
+++ exiv2-0.27.3/debian/patches/CVE-2021-31292.patch 1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-From 9b7a19f957af53304655ed1efe32253a1b11a8d0 Mon Sep 17 00:00:00 2001
-From: Kevin Backhouse <kevinbackhouse at github.com>
-Date: Fri, 9 Apr 2021 13:37:48 +0100
-Subject: [PATCH] Fix integer overflow.
-
---- exiv2-0.27.3.orig/src/crwimage_int.cpp
-+++ exiv2-0.27.3/src/crwimage_int.cpp
-@@ -1167,7 +1167,11 @@ namespace Exiv2 {
- pCrwMapping->crwDir_);
- if (edX != edEnd || edY != edEnd || edO != edEnd) {
- uint32_t size = 28;
-- if (cc && cc->size() > size) size = cc->size();
-+ if (cc) {
-+ if (cc->size() < size)
-+ throw Error(kerCorruptedMetadata);
-+ size = cc->size();
-+ }
- DataBuf buf(size);
- std::memset(buf.pData_, 0x0, buf.size_);
- if (cc) std::memcpy(buf.pData_ + 8, cc->pData() + 8, cc->size() - 8);
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-32815.patch exiv2-0.27.3/debian/patches/CVE-2021-32815.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-32815.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-32815.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,81 @@
+From cdda410e168e51438ca2ac77d9a220a32cf71d34 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 23 Jun 2021 22:31:12 +0100
+Subject: [PATCH 1/4] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-mv9g-fxh2-m49m
+
+---
+ test/data/test_issue_ghsa_mv9g_fxh2_m49m.crw | Bin 0 -> 10078 bytes
+ .../github/test_issue_ghsa_mv9g_fxh2_m49m.py | 13 +++++++++++++
+ 2 files changed, 13 insertions(+)
+ create mode 100644 test/data/test_issue_ghsa_mv9g_fxh2_m49m.crw
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_mv9g_fxh2_m49m.py
+
+From 0c17eb33c0a7fad1796ce23b8bbc32067f511aed Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 23 Jun 2021 22:39:31 +0100
+Subject: [PATCH 2/4] Don't crash if s > size.
+
+---
+ src/crwimage_int.cpp | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+From 04466168b87dedff4ec09c09e9c23f2334ba1734 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Thu, 24 Jun 2021 10:38:19 +0100
+Subject: [PATCH 3/4] Print message to stderr when EXIV2_DEBUG_MESSAGES is
+ enabled.
+
+---
+ src/crwimage_int.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+From c79d83f25fdd09218697d482211a61db87ce5333 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Mon, 12 Jul 2021 18:00:35 +0100
+Subject: [PATCH 4/4] Better way to print the error message.
+
+---
+ src/crwimage_int.cpp | 4 +---
+ tests/bugfixes/github/test_issue_ghsa_mv9g_fxh2_m49m.py | 2 +-
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_mv9g_fxh2_m49m.py b/tests/bugfixes/github/test_issue_ghsa_mv9g_fxh2_m49m.py
+new file mode 100644
+index 00000000..eb86c49f
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_mv9g_fxh2_m49m.py
+@@ -0,0 +1,13 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path
++
++class test_issue_ghsa_mv9g_fxh2_m49m(metaclass=CaseMeta):
++
++ filename = path("$data_path/test_issue_ghsa_mv9g_fxh2_m49m.crw")
++ commands = ["$exiv2 -q fi $filename"]
++ stdout = [""]
++ stderr = ["""Exiv2 exception in fixiso action for file $filename:
++$kerCorruptedMetadata
++"""]
++ retval = [1]
+diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp
+index 7b958c26..2db56b18 100644
+--- a/src/crwimage_int.cpp
++++ b/src/crwimage_int.cpp
+@@ -1246,9 +1246,12 @@ namespace Exiv2 {
+ for (ExifData::const_iterator i = b; i != e; ++i) {
+ if (i->ifdId() != ifdId) continue;
+ const uint16_t s = i->tag()*2 + static_cast<uint16_t>(i->size());
+- assert(s <= size);
+- if (len < s) len = s;
+- i->copy(buf.pData_ + i->tag()*2, byteOrder);
++ if (s <= size) {
++ if (len < s) len = s;
++ i->copy(buf.pData_ + i->tag()*2, byteOrder);
++ } else {
++ EXV_ERROR << "packIfdId out-of-bounds error: s = " << std::dec << s << "\n";
++ }
+ }
+ // Round the size to make it even.
+ buf.size_ = len + len%2;
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-34334.patch exiv2-0.27.3/debian/patches/CVE-2021-34334.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-34334.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-34334.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,101 @@
+From a35a2fde2dcd940a756feaeb027375b390bd8a06 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 6 Jul 2021 16:31:29 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-hqjh-hpv8-8r9p
+
+---
+ .../github/test_issue_ghsa_hqjh_hpv8_8r9p.py | 51 +++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_hqjh_hpv8_8r9p.py
+
+From 97c4880882d87aee77809b4b6e8fb4a5558e4ca2 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 6 Jul 2021 18:15:40 +0100
+Subject: [PATCH 2/2] Extra checking to prevent the loop counter from wrapping
+ around.
+
+---
+ src/crwimage_int.cpp | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_hqjh_hpv8_8r9p.py b/tests/bugfixes/github/test_issue_ghsa_hqjh_hpv8_8r9p.py
+new file mode 100644
+index 00000000..d6c8d602
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_hqjh_hpv8_8r9p.py
+@@ -0,0 +1,51 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, FileDecoratorBase, path
++from struct import *
++
++# The PoC is a fairly large file, mostly consisting of zero bytes,
++# so it would be a waste of storage to check it into the repo.
++# Instead, we can generate the PoC with a small amount of code:
++class CreatePoC(FileDecoratorBase):
++ """
++ This class copies files from test/data to test/tmp
++ Copied files are NOT removed in tearDown
++ Example: @CopyTmpFiles("$data_path/test_issue_1180.exv")
++ """
++
++ #: override the name of the file list
++ FILE_LIST_NAME = '_tmp_files'
++
++ def setUp_file_action(self, expanded_file_name):
++ size = 0x20040
++ contents = pack('<2sI8sHHIIHHII', bytes(b'II'), 14, bytes(b'HEAPCCDR'), \
++ 1, 0x300b, size - 26, 12, 1, 0x102a, size - 38, 12) + \
++ bytes(bytearray(size-38))
++ f = open(expanded_file_name, 'wb')
++ f.write(contents)
++ f.close()
++
++ def tearDown_file_action(self, f):
++ """
++ Do nothing. We don't clean up TmpFiles
++ """
++
++# This decorator generates the PoC file.
++ at CreatePoC("$tmp_path/issue_ghsa_hqjh_hpv8_8r9p_poc.crw")
++
++class CrwMapDecodeArrayInfiniteLoop(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-hqjh-hpv8-8r9p
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-hqjh-hpv8-8r9p"
++
++ filename = path("$tmp_path/issue_ghsa_hqjh_hpv8_8r9p_poc.crw")
++
++ commands = ["$exiv2 $filename"]
++ stdout = [""]
++ stderr = [
++"""Exiv2 exception in print action for file $filename:
++$kerCorruptedMetadata
++"""]
++ retval = [1]
+diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp
+index 6e890275..9e77990a 100644
+--- a/src/crwimage_int.cpp
++++ b/src/crwimage_int.cpp
+@@ -888,12 +888,16 @@ namespace Exiv2 {
+ assert(ifdId != ifdIdNotSet);
+
+ std::string groupName(Internal::groupName(ifdId));
++ const uint32_t component_size = ciffComponent.size();
++ enforce(component_size % 2 == 0, kerCorruptedMetadata);
++ enforce(component_size/2 <= static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()), kerCorruptedMetadata);
++ const uint16_t num_components = static_cast<uint16_t>(component_size/2);
+ uint16_t c = 1;
+- while (uint32_t(c)*2 < ciffComponent.size()) {
++ while (c < num_components) {
+ uint16_t n = 1;
+ ExifKey key(c, groupName);
+ UShortValue value;
+- if (ifdId == canonCsId && c == 23 && ciffComponent.size() > 50) n = 3;
++ if (ifdId == canonCsId && c == 23 && component_size >= 52) n = 3;
+ value.read(ciffComponent.pData() + c*2, n*2, byteOrder);
+ image.exifData().add(key, &value);
+ if (ifdId == canonSiId && c == 21) aperture = value.toLong();
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-34335.patch exiv2-0.27.3/debian/patches/CVE-2021-34335.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-34335.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-34335.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,150 @@
+From cdc0267afd0cb23de49dbf9b3b641f31451223d5 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 29 Jun 2021 23:31:55 +0100
+Subject: [PATCH 1/3] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-pvjp-m4f6-q984
+
+---
+ test/data/issue_ghsa_pvjp_m4f6_q984_poc.exv | Bin 0 -> 45279 bytes
+ .../github/test_issue_ghsa_pvjp_m4f6_q984.py | 36 ++++++++++++++++++
+ 2 files changed, 36 insertions(+)
+ create mode 100644 test/data/issue_ghsa_pvjp_m4f6_q984_poc.exv
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_pvjp_m4f6_q984.py
+
+From 11a26fb0d4458c0ad0632506f49282a466d876d8 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 29 Jun 2021 23:32:59 +0100
+Subject: [PATCH 2/3] Prevent divide-by-zero crash.
+
+---
+ src/minoltamn_int.cpp | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+From 5ab3f2b0c5602da55b3ff86dd5baaa69573a5914 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 30 Jun 2021 11:57:46 +0100
+Subject: [PATCH 3/3] Defensive coding to avoid 0x80000000/0xFFFFFFFF FPE.
+
+---
+ include/exiv2/value.hpp | 6 +++---
+ src/tags_int.cpp | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_pvjp_m4f6_q984.py b/tests/bugfixes/github/test_issue_ghsa_pvjp_m4f6_q984.py
+new file mode 100644
+index 00000000..1a81c59f
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_pvjp_m4f6_q984.py
+@@ -0,0 +1,36 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path
++
++
++class MinoltaDivZero(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-pvjp-m4f6-q984
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-pvjp-m4f6-q984"
++
++ filename = path("$data_path/issue_ghsa_pvjp_m4f6_q984_poc.exv")
++ commands = ["$exiv2 -p t $filename"]
++ stderr = ["""Error: Upper boundary of data for directory Image, entry 0x011a is out of bounds: Offset = 0x000000f2, size = 14155784, exceeds buffer size by 14110766 Bytes; truncating the entry
++Error: Offset of directory Photo, entry 0x829a is out of bounds: Offset = 0x6d00035e; truncating the entry
++Error: Upper boundary of data for directory Photo, entry 0x8822 is out of bounds: Offset = 0x00000003, size = 56834, exceeds buffer size by 11577 Bytes; truncating the entry
++Error: Upper boundary of data for directory Photo, entry 0x8827 is out of bounds: Offset = 0x00000640, size = 1179650, exceeds buffer size by 1135990 Bytes; truncating the entry
++Warning: Directory Photo, entry 0x8832 has unknown Exif (TIFF) type 49; setting type size 1.
++Error: Offset of directory Sony2, entry 0x2006 is out of bounds: Offset = 0x00000000; truncating the entry
++Warning: Directory Sony2, entry 0x20c1 has unknown Exif (TIFF) type 181; setting type size 1.
++Error: Offset of directory Sony2, entry 0x2063 is out of bounds: Offset = 0x00000000; truncating the entry
++Error: Offset of directory Sony2, entry 0x3000 is out of bounds: Offset = 0x0057097c; truncating the entry
++Error: Offset of directory Sony2, entry 0x0115 is out of bounds: Offset = 0x00000000; truncating the entry
++Error: Upper boundary of data for directory Sony2, entry 0x2013 is out of bounds: Offset = 0x00000002, size = 37486596, exceeds buffer size by 37441338 Bytes; truncating the entry
++Warning: Directory Photo, entry 0xa003 has unknown Exif (TIFF) type 242; setting type size 1.
++Warning: Directory Iop has an unexpected next pointer; ignored.
++Warning: Directory Photo, entry 0xa402 has unknown Exif (TIFF) type 89; setting type size 1.
++Error: Offset of directory Photo, entry 0xa402 is out of bounds: Offset = 0x00000000; truncating the entry
++Error: Offset of directory Thumbnail, entry 0x0132 is out of bounds: Offset = 0xff00968b; truncating the entry
++"""]
++ retval = [0]
++
++ def compare_stdout(self, i, command, got_stdout, expected_stdout):
++ """ We don't care about the stdout, just don't crash """
++ pass
+diff --git a/src/minoltamn_int.cpp b/src/minoltamn_int.cpp
+index 7ac6e49b..6bdf7110 100644
+--- a/src/minoltamn_int.cpp
++++ b/src/minoltamn_int.cpp
+@@ -2173,16 +2173,21 @@ namespace Exiv2 {
+
+ if ( model == "ILCE-6000" && maxAperture == F1_8 ) try {
+ long focalLength = getKeyLong ("Exif.Photo.FocalLength" ,metadata);
+- long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
+- long focalRatio = (focalL35mm*100)/focalLength;
+- if ( inRange(focalRatio,145,155) ) index = 2 ;
++ if (focalLength > 0) {
++ long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
++ long focalRatio = (focalL35mm*100)/focalLength;
++ if ( inRange(focalRatio,145,155) ) index = 2 ;
++ }
+ } catch (...) {}
+
+ if ( model == "ILCE-6000" && maxApertures.find(maxAperture) != maxApertures.end() ) try {
+ long focalLength = getKeyLong ("Exif.Photo.FocalLength" ,metadata);
+- long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
+- long focalRatio = (focalL35mm*100)/focalLength;
+- if ( inRange(focalRatio,145,155) ) index = 3 ;
++ if (focalLength > 0) {
++ long focalL35mm = getKeyLong("Exif.Photo.FocalLengthIn35mmFilm", metadata);
++ long focalRatio = (focalL35mm * 100) / focalLength;
++ if (inRange(focalRatio, 145, 155))
++ index = 3;
++ }
+ } catch (...) {}
+
+ if ( index > 0 ) {
+diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp
+index 1794c36d..788a65b4 100644
+--- a/include/exiv2/value.hpp
++++ b/include/exiv2/value.hpp
+@@ -1548,7 +1548,7 @@ namespace Exiv2 {
+ {
+ value_.clear();
+ long ts = TypeInfo::typeSize(typeId());
+- if (ts != 0)
++ if (ts > 0)
+ if (len % ts != 0) len = (len / ts) * ts;
+ for (long i = 0; i < len; i += ts) {
+ value_.push_back(getValue<T>(buf + i, byteOrder));
+@@ -1632,7 +1632,7 @@ namespace Exiv2 {
+ template<>
+ inline long ValueType<Rational>::toLong(long n) const
+ {
+- ok_ = (value_[n].second != 0 && INT_MIN < value_[n].first && value_[n].first < INT_MAX );
++ ok_ = (value_.at(n).second > 0 && INT_MIN < value_.at(n).first && value_.at(n).first < INT_MAX );
+ if (!ok_) return 0;
+ return value_[n].first / value_[n].second;
+ }
+@@ -1640,7 +1640,7 @@ namespace Exiv2 {
+ template<>
+ inline long ValueType<URational>::toLong(long n) const
+ {
+- ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT);
++ ok_ = (value_.at(n).second > 0 && value_.at(n).first < LARGE_INT);
+ if (!ok_) return 0;
+ return value_[n].first / value_[n].second;
+ }
+diff --git a/src/tags_int.cpp b/src/tags_int.cpp
+index c98ab94f..ce68c5f5 100644
+--- a/src/tags_int.cpp
++++ b/src/tags_int.cpp
+@@ -2611,7 +2611,7 @@ namespace Exiv2 {
+ std::ostream& printLong(std::ostream& os, const Value& value, const ExifData*)
+ {
+ Rational r = value.toRational();
+- if (r.second != 0) return os << static_cast<long>(r.first) / r.second;
++ if (r.second > 0) return os << static_cast<long>(r.first) / r.second;
+ return os << "(" << value << ")";
+ } // printLong
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-3482.patch exiv2-0.27.3/debian/patches/CVE-2021-3482.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-3482.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-3482.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,100 @@
+From 22ea582c6b74ada30bec3a6b15de3c3e52f2b4da Mon Sep 17 00:00:00 2001
+From: Robin Mills <robin at clanmills.com>
+Date: Mon, 5 Apr 2021 20:33:25 +0100
+Subject: [PATCH] fix_1522_jp2image_exif_asan
+
+---
+ src/jp2image.cpp | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+From cac151ec052d44da3dc779e9e4028e581acb128a Mon Sep 17 00:00:00 2001
+From: Robin Mills <robin at clanmills.com>
+Date: Mon, 5 Apr 2021 20:33:38 +0100
+Subject: [PATCH] test fix_1522_jp2image_exif_asan
+
+---
+ test/data/poc_1522.jp2 | Bin 0 -> 268 bytes
+ tests/bugfixes/github/test_issue_1522.py | 25 +++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+ create mode 100644 test/data/poc_1522.jp2
+ create mode 100644 tests/bugfixes/github/test_issue_1522.py
+
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index eb31cea4..88ab9b2d 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -28,6 +28,7 @@
+ #include "image.hpp"
+ #include "image_int.hpp"
+ #include "basicio.hpp"
++#include "enforce.hpp"
+ #include "error.hpp"
+ #include "futils.hpp"
+ #include "types.hpp"
+@@ -353,7 +354,7 @@ static void boxes_check(size_t b,size_t m)
+ if (io_->error()) throw Error(kerFailedToReadImageData);
+ if (bufRead != rawData.size_) throw Error(kerInputDataReadFailed);
+
+- if (rawData.size_ > 0)
++ if (rawData.size_ > 8) // "II*\0long"
+ {
+ // Find the position of Exif header in bytes array.
+ long pos = ( (rawData.pData_[0] == rawData.pData_[1])
+@@ -497,6 +498,7 @@ static void boxes_check(size_t b,size_t m)
+ position = io_->tell();
+ box.length = getLong((byte*)&box.length, bigEndian);
+ box.type = getLong((byte*)&box.type, bigEndian);
++ enforce(box.length <= io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata);
+
+ if (bPrint) {
+ out << Internal::stringFormat("%8ld | %8ld | ", (size_t)(position - sizeof(box)),
+@@ -581,12 +583,13 @@ static void boxes_check(size_t b,size_t m)
+ throw Error(kerInputDataReadFailed);
+
+ if (bPrint) {
+- out << Internal::binaryToString(makeSlice(rawData, 0, 40));
++ out << Internal::binaryToString(
++ makeSlice(rawData, 0, rawData.size_>40?40:rawData.size_));
+ out.flush();
+ }
+ lf(out, bLF);
+
+- if (bIsExif && bRecursive && rawData.size_ > 0) {
++ if (bIsExif && bRecursive && rawData.size_ > 8) { // "II*\0long"
+ if ((rawData.pData_[0] == rawData.pData_[1]) &&
+ (rawData.pData_[0] == 'I' || rawData.pData_[0] == 'M')) {
+ BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(rawData.pData_, rawData.size_));
+diff --git a/tests/bugfixes/github/test_issue_1522.py b/tests/bugfixes/github/test_issue_1522.py
+new file mode 100644
+index 00000000..e5831b25
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_1522.py
+@@ -0,0 +1,25 @@
++# -*- coding: utf-8 -*-
++
++import system_tests
++class issue_1522_exif_asan(metaclass=system_tests.CaseMeta):
++ url = "https://github.com/Exiv2/exiv2/issues/1522"
++ filename = "$data_path/poc_1522.jp2"
++ commands = ["$exiv2 $filename"
++ ,"$exiv2 -pS $filename"
++ ]
++ retval = [ 253,1 ]
++ stderr = [ """Warning: Failed to decode Exif metadata.
++$filename: No Exif data found in the file
++""","""$exiv2_exception_message $filename:
++$kerCorruptedMetadata
++"""]
++ stdout = ["""File name : $filename
++File size : 268 Bytes
++MIME type : image/jp2
++Image size : 0 x 0
++""","""STRUCTURE OF JPEG2000 FILE: $filename
++ address | length | box | data
++ 0 | 12 | jP |
++ 12 | 25 | uuid | Exif: .
++"""
++]
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37615.patch exiv2-0.27.3/debian/patches/CVE-2021-37615.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37615.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37615.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,112 @@
+From 8e79d9a4e00828777e17276571fb8ed1b7cd49aa Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 2 Jul 2021 17:18:15 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-h9x9-4f77-336w
+
+---
+ test/data/issue_ghsa_h9x9_4f77_336w_poc.exv | Bin 0 -> 34573 bytes
+ .../github/test_issue_ghsa_h9x9_4f77_336w.py | 17 +++++++++++++++++
+ 2 files changed, 17 insertions(+)
+ create mode 100644 test/data/issue_ghsa_h9x9_4f77_336w_poc.exv
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_h9x9_4f77_336w.py
+
+From 18d168959792d1eb42bb71d001ff46b57d6b97ab Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Fri, 2 Jul 2021 17:19:58 +0100
+Subject: [PATCH 2/2] Throw exception if lens info wasn't found.
+
+---
+ src/pentaxmn_int.cpp | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_h9x9_4f77_336w.py b/tests/bugfixes/github/test_issue_ghsa_h9x9_4f77_336w.py
+new file mode 100644
+index 00000000..d8c01d20
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_h9x9_4f77_336w.py
+@@ -0,0 +1,17 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors
++
++class Jp2ImageEncodeJp2HeaderOutOfBoundsRead2(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-h9x9-4f77-336w
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-h9x9-4f77-336w"
++
++ filename = path("$data_path/issue_ghsa_h9x9_4f77_336w_poc.exv")
++ commands = ["$exiv2 -P t $filename"]
++ retval = [0]
++
++ compare_stdout = check_no_ASAN_UBSAN_errors
++ compare_stderr = check_no_ASAN_UBSAN_errors
+diff --git a/src/pentaxmn_int.cpp b/src/pentaxmn_int.cpp
+index 313577eb..73afa32b 100644
+--- a/src/pentaxmn_int.cpp
++++ b/src/pentaxmn_int.cpp
+@@ -1213,6 +1213,25 @@ namespace Exiv2 {
+ return result;
+ }
+
++ // Exception thrown by findLensInfo when the lens info can't be found.
++ class LensInfoNotFound : public std::exception {
++ public:
++ LensInfoNotFound() {}
++ };
++
++ // Throws std::exception if the LensInfo can't be found.
++ static ExifData::const_iterator findLensInfo(const ExifData* metadata) {
++ const ExifData::const_iterator dngLensInfo = metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo"));
++ if (dngLensInfo != metadata->end()) {
++ return dngLensInfo;
++ }
++ const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.Pentax.LensInfo"));
++ if (lensInfo != metadata->end()) {
++ return lensInfo;
++ }
++ throw LensInfoNotFound();
++ }
++
+ //! resolveLens0x32c print lens in human format
+ std::ostream& resolveLens0x32c(std::ostream& os, const Value& value,
+ const ExifData* metadata)
+@@ -1249,11 +1268,7 @@ namespace Exiv2 {
+ unsigned long index = 0;
+
+ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html#LensData
+- const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo")) != metadata->end()
+- ? metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo"))
+- : metadata->findKey(ExifKey("Exif.Pentax.LensInfo"))
+- ;
+- if ( lensInfo == metadata->end() ) return EXV_PRINT_COMBITAG_MULTI(pentaxLensType, 2, 1, 2)(os, value, metadata);
++ const ExifData::const_iterator lensInfo = findLensInfo(metadata);
+ if ( lensInfo->count() < 5 ) return EXV_PRINT_COMBITAG_MULTI(pentaxLensType, 2, 1, 2)(os, value, metadata);
+
+ if ( value.count() == 2 ) {
+@@ -1307,10 +1322,7 @@ namespace Exiv2 {
+ try {
+ unsigned long index = 0;
+
+- const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo")) != metadata->end()
+- ? metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo"))
+- : metadata->findKey(ExifKey("Exif.Pentax.LensInfo"))
+- ;
++ const ExifData::const_iterator lensInfo = findLensInfo(metadata);
+ if ( value.count() == 4 ) {
+ std::string model = getKeyString("Exif.Image.Model" ,metadata);
+ if ( model.find("PENTAX K-3")==0 && lensInfo->count() == 128 && lensInfo->toLong(1) == 168 && lensInfo->toLong(2) == 144 ) index = 7;
+@@ -1335,10 +1347,7 @@ namespace Exiv2 {
+ try {
+ unsigned long index = 0;
+
+- const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo")) != metadata->end()
+- ? metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo"))
+- : metadata->findKey(ExifKey("Exif.Pentax.LensInfo"))
+- ;
++ const ExifData::const_iterator lensInfo = findLensInfo(metadata);
+ if ( value.count() == 4 ) {
+ std::string model = getKeyString("Exif.Image.Model" ,metadata);
+ if ( model.find("PENTAX K-3")==0 && lensInfo->count() == 128 && lensInfo->toLong(1) == 131 && lensInfo->toLong(2) == 128 )
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37618.patch exiv2-0.27.3/debian/patches/CVE-2021-37618.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37618.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37618.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,68 @@
+From e486a7313ed4a95e26290b51407123dd0a754b81 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Mon, 5 Jul 2021 10:39:08 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-583f-w9pm-99r2
+
+(cherry picked from commit 655495847bc39170bc4c06f9727483874fdc9c93)
+---
+ test/data/issue_ghsa_583f_w9pm_99r2_poc.jp2 | Bin 0 -> 32768 bytes
+ .../github/test_issue_ghsa_583f_w9pm_99r2.py | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100644 test/data/issue_ghsa_583f_w9pm_99r2_poc.jp2
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_583f_w9pm_99r2.py
+
+From ff0077142561ecbd0f70f7389ed87c8cd2901a4d Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Mon, 5 Jul 2021 10:40:03 +0100
+Subject: [PATCH 2/2] Better bounds checking in Jp2Image::printStructure
+
+(cherry picked from commit 0fcdde80997913dde284ea98f06f9305d06cb160)
+---
+ src/jp2image.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_583f_w9pm_99r2.py b/tests/bugfixes/github/test_issue_ghsa_583f_w9pm_99r2.py
+new file mode 100644
+index 00000000..808916ae
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_583f_w9pm_99r2.py
+@@ -0,0 +1,18 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path, check_no_ASAN_UBSAN_errors
++
++class Jp2ImagePrintStructureICC(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-583f-w9pm-99r2
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-583f-w9pm-99r2"
++
++ filename = path("$data_path/issue_ghsa_583f_w9pm_99r2_poc.jp2")
++ commands = ["$exiv2 -p C $filename"]
++ stdout = [""]
++ stderr = ["""Exiv2 exception in print action for file $filename:
++$kerCorruptedMetadata
++"""]
++ retval = [1]
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index de4daf75..a6789d27 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -537,6 +537,7 @@ static void boxes_check(size_t b,size_t m)
+
+ if (subBox.type == kJp2BoxTypeColorHeader) {
+ long pad = 3; // don't know why there are 3 padding bytes
++ enforce(data.size_ >= pad, kerCorruptedMetadata);
+ if (bPrint) {
+ out << " | pad:";
+ for (int i = 0; i < 3; i++)
+@@ -546,6 +547,7 @@ static void boxes_check(size_t b,size_t m)
+ if (bPrint) {
+ out << " | iccLength:" << iccLength;
+ }
++ enforce(iccLength <= data.size_ - pad, kerCorruptedMetadata);
+ if (bICC) {
+ out.write((const char*)data.pData_ + pad, iccLength);
+ }
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37619.patch exiv2-0.27.3/debian/patches/CVE-2021-37619.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37619.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37619.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,85 @@
+From d30c95d07e647535f4c9fe6fe4a559e978d25891 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Thu, 1 Jul 2021 12:33:20 +0100
+Subject: [PATCH] fix incorrect loop condition (#1752)
+
+---
+ src/jp2image.cpp | 2 +-
+ test/data/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2 | Bin 0 -> 1692 bytes
+ .../github/test_issue_ghsa_8949_hhfh_j7rj.py | 11 +++++------
+ .../github/test_issue_ghsa_mxw9_qx4c_6m8v.py | 18 ++++++++++++++++++
+ 4 files changed, 24 insertions(+), 7 deletions(-)
+ create mode 100644 test/data/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py
+
+diff --git a/src/jp2image.cpp b/src/jp2image.cpp
+index d880297a..de4daf75 100644
+--- a/src/jp2image.cpp
++++ b/src/jp2image.cpp
+@@ -655,7 +655,7 @@ static void boxes_check(size_t b,size_t m)
+ char* p = (char*) boxBuf.pData_;
+ bool bWroteColor = false ;
+
+- while ( count < length || !bWroteColor ) {
++ while ( count < length && !bWroteColor ) {
+ enforce(sizeof(Jp2BoxHeader) <= length - count, Exiv2::kerCorruptedMetadata);
+ Jp2BoxHeader* pSubBox = (Jp2BoxHeader*) (p+count) ;
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py b/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
+index c98b3815..44f6a906 100644
+--- a/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
++++ b/tests/bugfixes/github/test_issue_ghsa_8949_hhfh_j7rj.py
+@@ -1,7 +1,7 @@
+ # -*- coding: utf-8 -*-
+
+-from system_tests import CaseMeta, path
+-
++from system_tests import CaseMeta, CopyTmpFiles, path
++ at CopyTmpFiles("$data_path/issue_ghsa_8949_hhfh_j7rj_poc.jp2","$data_path/issue_ghsa_8949_hhfh_j7rj_poc.exv")
+
+ class Jp2ImageEncodeJp2HeaderOutOfBoundsRead(metaclass=CaseMeta):
+ """
+@@ -10,13 +10,12 @@ class Jp2ImageEncodeJp2HeaderOutOfBoundsRead(metaclass=CaseMeta):
+ """
+ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-8949-hhfh-j7rj"
+
+- filename1 = path("$data_path/issue_ghsa_8949_hhfh_j7rj_poc.jp2")
+- filename2 = path("$data_path/issue_ghsa_8949_hhfh_j7rj_poc.exv")
++ filename1 = path("$tmp_path/issue_ghsa_8949_hhfh_j7rj_poc.jp2")
++ filename2 = path("$tmp_path/issue_ghsa_8949_hhfh_j7rj_poc.exv")
+ commands = ["$exiv2 in $filename1"]
+ stdout = [""]
+ stderr = [
+ """Error: XMP Toolkit error 201: XML parsing failure
+ Warning: Failed to decode XMP metadata.
+-$filename1: Could not write metadata to file: $kerCorruptedMetadata
+ """]
+- retval = [1]
++ retval = [0]
+diff --git a/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py b/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py
+new file mode 100644
+index 00000000..8f8b6676
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py
+@@ -0,0 +1,18 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors
++ at CopyTmpFiles("$data_path/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2")
++
++class Jp2ImageEncodeJp2HeaderOutOfBoundsRead2(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-mxw9-qx4c-6m8v
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-mxw9-qx4c-6m8v"
++
++ filename = path("$tmp_path/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2")
++ commands = ["$exiv2 rm $filename"]
++ stdout = [""]
++ retval = [0]
++
++ compare_stderr = check_no_ASAN_UBSAN_errors
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37620.patch exiv2-0.27.3/debian/patches/CVE-2021-37620.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37620.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37620.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,393 @@
+From 92ddbf011d6af57ef0e3470827298e8dc2e491c6 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sat, 10 Jul 2021 10:41:53 +0100
+Subject: [PATCH 1/3] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-v5g7-46xf-h728
+
+---
+ test/data/issue_ghsa_v5g7_46xf_h728_poc.exv | Bin 0 -> 276 bytes
+ .../github/test_issue_ghsa_v5g7_46xf_h728.py | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100755 test/data/issue_ghsa_v5g7_46xf_h728_poc.exv
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_v5g7_46xf_h728.py
+
+From d5ada325af1bcd203411a2aed0fa2054f5570480 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sat, 10 Jul 2021 10:42:24 +0100
+Subject: [PATCH 2/3] Check that `type` isn't an empty string.
+
+---
+ src/value.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+From dc2c77ce81331094cf474a1968c2d1141693f369 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sun, 11 Jul 2021 12:04:53 +0100
+Subject: [PATCH 3/3] Safer std::vector indexing.
+
+---
+ samples/addmoddel.cpp | 2 +-
+ samples/exiv2json.cpp | 6 +++---
+ src/actions.cpp | 21 ++++++++++++---------
+ src/basicio.cpp | 6 +++---
+ src/exiv2.cpp | 4 ++--
+ src/minoltamn_int.cpp | 2 +-
+ src/properties.cpp | 2 +-
+ src/sigmamn_int.cpp | 6 +++---
+ src/tags_int.cpp | 2 +-
+ src/tiffvisitor_int.cpp | 2 +-
+ src/types.cpp | 2 +-
+ src/utils.cpp | 4 ++--
+ src/value.cpp | 9 ++++++---
+ src/xmp.cpp | 4 ++--
+ src/xmpsidecar.cpp | 2 +-
+ 15 files changed, 40 insertions(+), 34 deletions(-)
+
+Backport:
+ * In order to avoid breaking ABI, replace kerInvalidLangAltValue with
+ kerDecodeLangAltPropertyFailed, which is roughly similar although not
+ exactly right.
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_v5g7_46xf_h728.py b/tests/bugfixes/github/test_issue_ghsa_v5g7_46xf_h728.py
+new file mode 100644
+index 00000000..de68afc2
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_v5g7_46xf_h728.py
+@@ -0,0 +1,18 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors
++
++class Jp2ImageEncodeJp2HeaderOutOfBoundsRead2(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-v5g7-46xf-h728
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-v5g7-46xf-h728"
++
++ filename = path("$data_path/issue_ghsa_v5g7_46xf_h728_poc.exv")
++ commands = ["$exiv2 $filename"]
++ stdout = [""]
++ stderr = ["""Exiv2 exception in print action for file $filename:
++Invalid XmpText type `'
++"""]
++ retval = [1]
+diff --git a/src/value.cpp b/src/value.cpp
+--- a/src/value.cpp
++++ b/src/value.cpp
+@@ -425,8 +425,10 @@ namespace Exiv2 {
+ std::string::size_type pos = comment.find_first_of(' ');
+ std::string name = comment.substr(8, pos-8);
+ // Strip quotes (so you can also specify the charset without quotes)
+- if (name[0] == '"') name = name.substr(1);
+- if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
++ if (!name.empty()) {
++ if (name[0] == '"') name = name.substr(1);
++ if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
++ }
+ charsetId = CharsetInfo::charsetIdByName(name);
+ if (charsetId == invalidCharsetId) {
+ #ifndef SUPPRESS_WARNINGS
+@@ -622,6 +622,9 @@ namespace Exiv2 {
+ if (buf.length() > 5 && buf.substr(0, 5) == "type=") {
+ std::string::size_type pos = buf.find_first_of(' ');
+ type = buf.substr(5, pos-5);
++ if (type.empty()) {
++ throw Error(kerInvalidXmpText, type);
++ }
+ // Strip quotes (so you can also specify the type without quotes)
+ if (type[0] == '"') type = type.substr(1);
+ if (type[type.length()-1] == '"') type = type.substr(0, type.length()-1);
+@@ -788,6 +790,7 @@ namespace Exiv2 {
+ if (buf.length() > 5 && buf.substr(0, 5) == "lang=") {
+ std::string::size_type pos = buf.find_first_of(' ');
+ lang = buf.substr(5, pos-5);
++ if (lang.empty()) throw Error(kerDecodeLangAltPropertyFailed, buf);
+ // Strip quotes (so you can also specify the language without quotes)
+ if (lang[0] == '"') lang = lang.substr(1);
+ if (lang[lang.length()-1] == '"') lang = lang.substr(0, lang.length()-1);
+diff --git a/samples/addmoddel.cpp b/samples/addmoddel.cpp
+index 8bd33acf..37aca8ba 100644
+--- a/samples/addmoddel.cpp
++++ b/samples/addmoddel.cpp
+@@ -101,7 +101,7 @@ try {
+ if (prv == 0) throw Exiv2::Error(Exiv2::kerErrorMessage, "Downcast failed");
+ rv = Exiv2::URationalValue::AutoPtr(prv);
+ // Modify the value directly through the interface of URationalValue
+- rv->value_[2] = std::make_pair(88,77);
++ rv->value_.at(2) = std::make_pair(88,77);
+ // Copy the modified value back to the metadatum
+ pos->setValue(rv.get());
+ std::cout << "Modified key \"" << key
+diff --git a/samples/exiv2json.cpp b/samples/exiv2json.cpp
+index 1b735f6f..35ebff9b 100644
+--- a/samples/exiv2json.cpp
++++ b/samples/exiv2json.cpp
+@@ -74,7 +74,7 @@ bool getToken(std::string& in, Token& token, std::set<std::string>* pNS = nullpt
+
+ while ( !result && in.length() ) {
+ std::string c = in.substr(0,1);
+- char C = c[0];
++ char C = c.at(0);
+ in = in.substr(1,std::string::npos);
+ if ( in.length() == 0 && C != ']' ) token.n += c;
+ if ( C == '/' || C == '[' || C == ':' || C == '.' || C == ']' || in.length() == 0 ) {
+@@ -115,7 +115,7 @@ Jzon::Node& addToTree(Jzon::Node& r1, const Token& token)
+
+ Jzon::Node& recursivelyBuildTree(Jzon::Node& root,Tokens& tokens,size_t k)
+ {
+- return addToTree( k==0 ? root : recursivelyBuildTree(root,tokens,k-1), tokens[k] );
++ return addToTree( k==0 ? root : recursivelyBuildTree(root,tokens,k-1), tokens.at(k) );
+ }
+
+ // build the json tree for this key. return location and discover the name
+@@ -128,7 +128,7 @@ Jzon::Node& objectForKey(const std::string& Key, Jzon::Object& root, std::string
+ std::string input = Key ; // Example: "XMP.xmp.MP.RegionInfo/MPRI:Regions[1]/MPReg:Rectangle"
+ while ( getToken(input,token,pNS) ) tokens.push_back(token);
+ size_t l = tokens.size()-1; // leave leaf name to push()
+- name = tokens[l].n ;
++ name = tokens.at(l).n ;
+
+ // The second token. For example: XMP.dc is a namespace
+ if ( pNS && tokens.size() > 1 ) pNS->insert(tokens[1].n);
+diff --git a/src/actions.cpp b/src/actions.cpp
+index 7398d87f..1c854bd2 100644
+--- a/src/actions.cpp
++++ b/src/actions.cpp
+@@ -995,19 +995,21 @@
+
+ const Params::PreviewNumbers& numbers = Params::instance().previewNumbers_;
+ for (Params::PreviewNumbers::const_iterator n = numbers.begin(); n != numbers.end(); ++n) {
+- if (*n == 0) {
++ size_t num = static_cast<size_t>(*n);
++ if (num == 0) {
+ // Write all previews
+- for (int num = 0; num < static_cast<int>(pvList.size()); ++num) {
+- writePreviewFile(pvMgr.getPreviewImage(pvList[num]), num + 1);
++ for (num = 0; num < pvList.size(); ++num) {
++ writePreviewFile(pvMgr.getPreviewImage(pvList[num]), static_cast<int>(num + 1));
+ }
+ break;
+ }
+- if (*n > static_cast<int>(pvList.size())) {
++ num--;
++ if (num >= pvList.size()) {
+ std::cerr << path_ << ": " << _("Image does not have preview")
+- << " " << *n << "\n";
++ << " " << num + 1 << "\n";
+ continue;
+ }
+- writePreviewFile(pvMgr.getPreviewImage(pvList[*n - 1]), *n);
++ writePreviewFile(pvMgr.getPreviewImage(pvList[num]), static_cast<int>(num + 1));
+ }
+ return 0;
+ } // Extract::writePreviews
+@@ -2070,7 +2073,7 @@ namespace {
+ << "' " << _("exists. [O]verwrite, [r]ename or [s]kip?")
+ << " ";
+ std::cin >> s;
+- switch (s[0]) {
++ switch (s.at(0)) {
+ case 'o':
+ case 'O':
+ go = false;
+@@ -2135,7 +2138,7 @@ namespace {
+ << ": " << _("Overwrite") << " `" << path << "'? ";
+ std::string s;
+ std::cin >> s;
+- if (s[0] != 'y' && s[0] != 'Y') return 1;
++ if (s.at(0) != 'y' && s.at(0) != 'Y') return 1;
+ }
+ return 0;
+ }
+diff --git a/src/basicio.cpp b/src/basicio.cpp
+index 34e6c852..6f5b023f 100644
+--- a/src/basicio.cpp
++++ b/src/basicio.cpp
+@@ -184,11 +184,11 @@ namespace Exiv2 {
+ case opRead:
+ // Flush if current mode allows reading, else reopen (in mode "r+b"
+ // as in this case we know that we can write to the file)
+- if (openMode_[0] == 'r' || openMode_[1] == '+') reopen = false;
++ if (openMode_.at(0) == 'r' || openMode_.at(1) == '+') reopen = false;
+ break;
+ case opWrite:
+ // Flush if current mode allows writing, else reopen
+- if (openMode_[0] != 'r' || openMode_[1] == '+') reopen = false;
++ if (openMode_.at(0) != 'r' || openMode_.at(1) == '+') reopen = false;
+ break;
+ case opSeek:
+ reopen = false;
+@@ -929,7 +929,7 @@ namespace Exiv2 {
+ size_t FileIo::size() const
+ {
+ // Flush and commit only if the file is open for writing
+- if (p_->fp_ != 0 && (p_->openMode_[0] != 'r' || p_->openMode_[1] == '+')) {
++ if (p_->fp_ != nullptr && (p_->openMode_.at(0) != 'r' || p_->openMode_.at(1) == '+')) {
+ std::fflush(p_->fp_);
+ #if defined WIN32 && !defined __CYGWIN__
+ // This is required on msvcrt before stat after writing to a file
+diff --git a/src/exiv2.cpp b/src/exiv2.cpp
+index 9f7c3995..fdf088bf 100644
+--- a/src/exiv2.cpp
++++ b/src/exiv2.cpp
+@@ -1478,8 +1478,8 @@ namespace {
+ if (valStart != std::string::npos) {
+ value = parseEscapes(line.substr(valStart, valEnd+1-valStart));
+ std::string::size_type last = value.length()-1;
+- if ( (value[0] == '"' && value[last] == '"')
+- || (value[0] == '\'' && value[last] == '\'')) {
++ if ( (value.at(0) == '"' && value.at(last) == '"')
++ || (value.at(0) == '\'' && value.at(last) == '\'')) {
+ value = value.substr(1, value.length()-2);
+ }
+ }
+diff --git a/src/minoltamn_int.cpp b/src/minoltamn_int.cpp
+index 6bdf7110..a3077af1 100644
+--- a/src/minoltamn_int.cpp
++++ b/src/minoltamn_int.cpp
+@@ -2030,7 +2030,7 @@ namespace Exiv2 {
+ {
+ const TagDetails* td = find(minoltaSonyLensID, lensID);
+ std::vector<std::string> tokens = split(td[0].label_,"|");
+- return os << exvGettext(trim(tokens[index-1]).c_str());
++ return os << exvGettext(trim(tokens.at(index-1)).c_str());
+ }
+
+ static std::ostream& resolveLens0x1c(std::ostream& os, const Value& value,
+diff --git a/src/properties.cpp b/src/properties.cpp
+index 4e451d75..2fa9fe86 100644
+--- a/src/properties.cpp
++++ b/src/properties.cpp
+@@ -2601,7 +2601,7 @@ namespace Exiv2 {
+ // If property is a path for a nested property, determines the innermost element
+ std::string::size_type i = property.find_last_of('/');
+ if (i != std::string::npos) {
+- for (; i != std::string::npos && !isalpha(property[i]); ++i) {}
++ for (; i != std::string::npos && !isalpha(property.at(i)); ++i) {}
+ property = property.substr(i);
+ i = property.find_first_of(':');
+ if (i != std::string::npos) {
+diff --git a/src/sigmamn_int.cpp b/src/sigmamn_int.cpp
+index c5e22f5b..f6904484 100644
+--- a/src/sigmamn_int.cpp
++++ b/src/sigmamn_int.cpp
+@@ -126,7 +126,7 @@ namespace Exiv2 {
+ std::string v = value.toString();
+ std::string::size_type pos = v.find(':');
+ if (pos != std::string::npos) {
+- if (v[pos + 1] == ' ') ++pos;
++ if (v.at(pos + 1) == ' ') ++pos;
+ v = v.substr(pos + 1);
+ }
+ return os << v;
+@@ -136,7 +136,7 @@ namespace Exiv2 {
+ const Value& value,
+ const ExifData*)
+ {
+- switch (value.toString()[0]) {
++ switch (value.toString().at(0)) {
+ case 'P': os << _("Program"); break;
+ case 'A': os << _("Aperture priority"); break;
+ case 'S': os << _("Shutter priority"); break;
+@@ -150,7 +150,7 @@ namespace Exiv2 {
+ const Value& value,
+ const ExifData*)
+ {
+- switch (value.toString()[0]) {
++ switch (value.toString().at(0)) {
+ case 'A': os << _("Average"); break;
+ case 'C': os << _("Center"); break;
+ case '8': os << _("8-Segment"); break;
+diff --git a/src/tags_int.cpp b/src/tags_int.cpp
+index a9643389..284e458f 100644
+--- a/src/tags_int.cpp
++++ b/src/tags_int.cpp
+@@ -3247,7 +3247,7 @@ namespace Exiv2 {
+ }
+
+ std::string stringValue = value.toString();
+- if (stringValue[19] == 'Z') {
++ if (stringValue.at(19) == 'Z') {
+ stringValue = stringValue.substr(0, 19);
+ }
+ for (unsigned int i = 0; i < stringValue.length(); ++i) {
+diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp
+index ccf12a4d..a24c007c 100644
+--- a/src/tiffvisitor_int.cpp
++++ b/src/tiffvisitor_int.cpp
+@@ -461,7 +461,7 @@ namespace Exiv2 {
+ uint.push_back((uint16_t) object->pValue()->toLong(i));
+ }
+ // Check this is AFInfo2 (ints[0] = bytes in object)
+- if ( ints[0] != object->pValue()->count()*2 ) return ;
++ if ( ints.at(0) != object->pValue()->count()*2 ) return ;
+
+ std::string familyGroup(std::string("Exif.") + groupName(object->group()) + ".");
+
+diff --git a/src/types.cpp b/src/types.cpp
+index c1886371..9a51d89b 100644
+--- a/src/types.cpp
++++ b/src/types.cpp
+@@ -586,7 +586,7 @@ namespace Exiv2 {
+ bool stringTo<bool>(const std::string& s, bool& ok)
+ {
+ std::string lcs(s); /* lowercase string */
+- for(unsigned i = 0; i < lcs.length(); i++) {
++ for(size_t i = 0; i < lcs.length(); i++) {
+ lcs[i] = std::tolower(s[i]);
+ }
+ /* handle the same values as xmp sdk */
+diff --git a/src/utils.cpp b/src/utils.cpp
+index 3dae2ee8..c3d305bd 100644
+--- a/src/utils.cpp
++++ b/src/utils.cpp
+@@ -61,7 +61,7 @@ namespace Util {
+ if (p.length() == 2 && p[1] == ':') return p; // For Windows paths
+ std::string::size_type idx = p.find_last_of("\\/");
+ if (idx == std::string::npos) return ".";
+- if (idx == 1 && p[0] == '\\' && p[1] == '\\') return p; // For Windows paths
++ if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return p; // For Windows paths
+ p = p.substr(0, idx == 0 ? 1 : idx);
+ while ( p.length() > 1
+ && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) {
+@@ -82,7 +82,7 @@ namespace Util {
+ }
+ if (p.length() == 2 && p[1] == ':') return ""; // For Windows paths
+ std::string::size_type idx = p.find_last_of("\\/");
+- if (idx == 1 && p[0] == '\\' && p[1] == '\\') return ""; // For Windows paths
++ if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return ""; // For Windows paths
+ if (idx != std::string::npos) p = p.substr(idx+1);
+ if (delsuffix) p = p.substr(0, p.length() - suffix(p).length());
+ return p;
+diff --git a/src/xmp.cpp b/src/xmp.cpp
+index 7bdc5cd5..b00681d9 100644
+--- a/src/xmp.cpp
++++ b/src/xmp.cpp
+@@ -499,8 +499,8 @@ namespace Exiv2 {
+ bool bNS = out.find(':') != std::string::npos && !bURI;
+
+ // pop trailing ':' on a namespace
+- if ( bNS ) {
+- std::size_t length = out.length();
++ if ( bNS && !out.empty() ) {
++ std::size_t length = out.length();
+ if ( out[length-1] == ':' ) out = out.substr(0,length-1);
+ }
+
+diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp
+index 621eec7c..70f26019 100644
+--- a/src/xmpsidecar.cpp
++++ b/src/xmpsidecar.cpp
+@@ -229,7 +229,7 @@ namespace Exiv2 {
+ std::string head(reinterpret_cast<const char*>(buf + start), len - start);
+ if (head.substr(0, 5) == "<?xml") {
+ // Forward to the next tag
+- for (unsigned i = 5; i < head.size(); ++i) {
++ for (size_t i = 5; i < head.size(); ++i) {
+ if (head[i] == '<') {
+ head = head.substr(i);
+ break;
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37621.patch exiv2-0.27.3/debian/patches/CVE-2021-37621.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37621.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37621.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,73 @@
+From 093dca0281506c86e47c07e8a2ef61f72384ff4a Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 13 Jul 2021 17:55:35 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-m479-7frc-gqqg
+
+---
+ test/data/issue_ghsa_m479_7frc_gqqg_poc.crw | Bin 0 -> 22 bytes
+ .../github/test_issue_ghsa_m479_7frc_gqqg.py | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100644 test/data/issue_ghsa_m479_7frc_gqqg_poc.crw
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_m479_7frc_gqqg.py
+
+From caf08b229e521a27c0295fb48985b4fa5b483a6e Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Tue, 13 Jul 2021 22:50:16 +0100
+Subject: [PATCH 2/2] dirLength == 0 can cause an infinite loop.
+
+---
+ src/image.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+Backport:
+ * #include "enforce.hpp"
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_m479_7frc_gqqg.py b/tests/bugfixes/github/test_issue_ghsa_m479_7frc_gqqg.py
+new file mode 100644
+index 00000000..204bd31b
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_m479_7frc_gqqg.py
+@@ -0,0 +1,18 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, path, check_no_ASAN_UBSAN_errors
++
++class ImagePrintIFDStructure(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-m479-7frc-gqqg
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-m479-7frc-gqqg"
++
++ filename = path("$data_path/issue_ghsa_m479_7frc_gqqg_poc.crw")
++ commands = ["$exiv2 -p C $filename"]
++ stdout = [""]
++ stderr = ["""Exiv2 exception in print action for file $filename:
++$kerCorruptedMetadata
++"""]
++ retval = [1]
+diff --git a/src/image.cpp b/src/image.cpp
+index bc80549e..0fdc4e41 100644
+--- a/src/image.cpp
++++ b/src/image.cpp
+@@ -30,6 +30,7 @@
+ #include "futils.hpp"
+ #include "safe_op.hpp"
+ #include "slice.hpp"
++#include "enforce.hpp"
+
+ #include "cr2image.hpp"
+ #include "crwimage.hpp"
+@@ -334,6 +334,8 @@ namespace Exiv2 {
+ throw Error(kerCorruptedMetadata);
+ }
+ uint16_t dirLength = byteSwap2(dir,0,bSwap);
++ // Prevent infinite loops. (GHSA-m479-7frc-gqqg)
++ enforce(dirLength > 0, kerCorruptedMetadata);
+
+ bool tooBig = dirLength > 500;
+ if ( tooBig ) throw Error(kerTiffDirectoryTooLarge);
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37622.patch exiv2-0.27.3/debian/patches/CVE-2021-37622.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37622.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37622.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,77 @@
+From bc0f4f5bd0c7daebb3948b5fbcc5b36745285dc6 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sat, 17 Jul 2021 12:36:44 +0100
+Subject: [PATCH 1/3] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-9jh3-fcc3-g6hv
+
+(cherry picked from commit 61cb1a1ca15282bee76c33eb9abdb416ac366471)
+---
+ test/data/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg | Bin 0 -> 75 bytes
+ .../github/test_issue_ghsa_9jh3_fcc3_g6hv.py | 21 ++++++++++++++++++
+ 2 files changed, 21 insertions(+)
+ create mode 100644 test/data/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_9jh3_fcc3_g6hv.py
+
+From 07225c05ee6c8df4f57663a48c5b06317f56cbfa Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sat, 17 Jul 2021 12:38:31 +0100
+Subject: [PATCH 2/3] Make sure that read is complete to prevent infinite loop.
+
+(cherry picked from commit ffe5eb517dad93845e62144d8e53f52b17420ecd)
+---
+ src/jpgimage.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+From 9004fb5a97e7d436454656d53e8110d1269328ed Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sun, 25 Jul 2021 19:03:50 +0100
+Subject: [PATCH 3/3] Remove redundant check.
+
+(cherry picked from commit 19026fab2bc2b6dee2150f38153feb65a41cea17)
+---
+ src/jpgimage.cpp | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_9jh3_fcc3_g6hv.py b/tests/bugfixes/github/test_issue_ghsa_9jh3_fcc3_g6hv.py
+new file mode 100644
+index 00000000..430b7a21
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_9jh3_fcc3_g6hv.py
+@@ -0,0 +1,21 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, CopyTmpFiles, path
++ at CopyTmpFiles("$data_path/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg")
++
++class JpegBasePrintStructureInfiniteLoop(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-9jh3-fcc3-g6hv
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-9jh3-fcc3-g6hv"
++
++ filename = path("$tmp_path/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg")
++ commands = ["$exiv2 -d I rm $filename"]
++ stdout = [""]
++ stderr = [
++"""Warning: JPEG format error, rc = 2
++Exiv2 exception in erase action for file $filename:
++$kerFailedToReadImageData
++"""]
++ retval = [1]
+diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp
+index 6e6f0f96..460f1b94 100644
+--- a/src/jpgimage.cpp
++++ b/src/jpgimage.cpp
+@@ -637,10 +637,8 @@ namespace Exiv2 {
+ // Read size and signature
+ std::memset(buf.pData_, 0x0, buf.size_);
+ bufRead = io_->read(buf.pData_, bufMinSize);
+- if (io_->error())
++ if (io_->error() || bufRead != bufMinSize)
+ throw Error(kerFailedToReadImageData);
+- if (bufRead < 2)
+- throw Error(kerNotAJpeg);
+ const uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
+ if (bPrint && mHasLength[marker])
+ out << Internal::stringFormat(" | %7d ", size);
diff --minimal -Nru exiv2-0.27.3/debian/patches/CVE-2021-37623.patch exiv2-0.27.3/debian/patches/CVE-2021-37623.patch
--- exiv2-0.27.3/debian/patches/CVE-2021-37623.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/CVE-2021-37623.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,72 @@
+From 16dc5f73a511b4cf51baf7eb664a0bc4c1ddf909 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Wed, 21 Jul 2021 19:53:59 +0100
+Subject: [PATCH 1/2] Regression test for
+ https://github.com/Exiv2/exiv2/security/advisories/GHSA-mvc4-g5pv-4qqq
+
+---
+ test/data/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg | Bin 0 -> 66 bytes
+ .../github/test_issue_ghsa_mvc4_g5pv_4qqq.py | 20 ++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+ create mode 100644 test/data/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg
+ create mode 100644 tests/bugfixes/github/test_issue_ghsa_mvc4_g5pv_4qqq.py
+
+From deb41bd1172f8f9b5a360f12de9b159249d4b345 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse at github.com>
+Date: Sun, 18 Jul 2021 10:39:57 +0100
+Subject: [PATCH 2/2] bufRead needs to be adjusted after seek()
+
+---
+ src/jpgimage.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+Backport:
+ * Also cherry-pick the correct value for pos[count +1] from 483a1497a05f15f9069fca1dc617ebc0a3769254 ("Improved handling of jpg segments to avoid out-of-bound reads.")
+
+diff --git a/tests/bugfixes/github/test_issue_ghsa_mvc4_g5pv_4qqq.py b/tests/bugfixes/github/test_issue_ghsa_mvc4_g5pv_4qqq.py
+new file mode 100644
+index 00000000..14222391
+--- /dev/null
++++ b/tests/bugfixes/github/test_issue_ghsa_mvc4_g5pv_4qqq.py
+@@ -0,0 +1,20 @@
++# -*- coding: utf-8 -*-
++
++from system_tests import CaseMeta, CopyTmpFiles, path
++ at CopyTmpFiles("$data_path/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg")
++
++class JpegBasePrintStructureInfiniteLoop(metaclass=CaseMeta):
++ """
++ Regression test for the bug described in:
++ https://github.com/Exiv2/exiv2/security/advisories/GHSA-mvc4-g5pv-4qqq
++ """
++ url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-mvc4-g5pv-4qqq"
++
++ filename = path("$tmp_path/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg")
++ commands = ["$exiv2 -d I rm $filename"]
++ stdout = [""]
++ stderr = [
++"""Exiv2 exception in erase action for file $filename:
++$kerFailedToReadImageData
++"""]
++ retval = [1]
+diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp
+index f35e6250..de273048 100644
+--- a/src/jpgimage.cpp
++++ b/src/jpgimage.cpp
+@@ -709,6 +709,7 @@ namespace Exiv2 {
+ io_->seek(-bufRead, BasicIo::cur);
+ iptcDataSegs.push_back(io_->tell());
+ iptcDataSegs.push_back(size);
++ bufRead = 0;
+ }
+ } else if (bPrint) {
+ const size_t start = size > 0 ? 2 : 0;
+@@ -859,7 +859,7 @@
+ pos[i + 1] = bEven ? *it : pos[i] + *it;
+ ++it;
+ }
+- pos[count + 1] = io_->size() - pos[count];
++ pos[count + 1] = io_->size();
+ #ifdef EXIV2_DEBUG_MESSAGES
+ for (uint64_t i = 0; i < count + 2; i++)
+ std::cout << pos[i] << " ";
diff --minimal -Nru exiv2-0.27.3/debian/patches/fix-gtest-1.11.patch exiv2-0.27.3/debian/patches/fix-gtest-1.11.patch
--- exiv2-0.27.3/debian/patches/fix-gtest-1.11.patch 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/patches/fix-gtest-1.11.patch 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,33 @@
+From c069e36605f05e8e58bf964e5ecbde04efb90a20 Mon Sep 17 00:00:00 2001
+From: Antonio Rojas <arojas at archlinux.org>
+Date: Fri, 18 Jun 2021 18:53:46 +0200
+Subject: [PATCH] Fix build with gtest 1.11
+
+INSTANTIATE_TYPED_TEST_CASE_P requires a non-empty prefix now
+---
+ unitTests/test_slice.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/unitTests/test_slice.cpp b/unitTests/test_slice.cpp
+index ccf80d98..59171cfc 100644
+--- a/unitTests/test_slice.cpp
++++ b/unitTests/test_slice.cpp
+@@ -440,12 +440,12 @@ REGISTER_TYPED_TEST_CASE_P(slice, atAccess, iteratorAccess, constructionFailsFro
+ constMethodsPreserveConst);
+
+ typedef ::testing::Types<const std::vector<int>, std::vector<int>, int*, const int*> test_types_t;
+-INSTANTIATE_TYPED_TEST_CASE_P(, slice, test_types_t);
++INSTANTIATE_TYPED_TEST_CASE_P(slice, slice, test_types_t);
+
+ REGISTER_TYPED_TEST_CASE_P(mutableSlice, iterators, at);
+ typedef ::testing::Types<std::vector<int>, int*> mut_test_types_t;
+-INSTANTIATE_TYPED_TEST_CASE_P(, mutableSlice, mut_test_types_t);
++INSTANTIATE_TYPED_TEST_CASE_P(slice, mutableSlice, mut_test_types_t);
+
+ REGISTER_TYPED_TEST_CASE_P(dataBufSlice, successfulConstruction, failedConstruction);
+ typedef ::testing::Types<DataBuf&, const DataBuf&> data_buf_types_t;
+-INSTANTIATE_TYPED_TEST_CASE_P(, dataBufSlice, data_buf_types_t);
++INSTANTIATE_TYPED_TEST_CASE_P(slice, dataBufSlice, data_buf_types_t);
+--
+2.39.0
+
diff --minimal -Nru exiv2-0.27.3/debian/patches/series exiv2-0.27.3/debian/patches/series
--- exiv2-0.27.3/debian/patches/series 2021-08-06 10:57:16.000000000 +0200
+++ exiv2-0.27.3/debian/patches/series 2023-01-05 18:19:20.000000000 +0100
@@ -2,4 +2,21 @@
fix-man-page-table-formatting.patch
fcf-protection-only-on-x86.diff
CVE-2021-31291.patch
-CVE-2021-31292.patch
+CVE-2021-3482.patch
+CVE-2021-29458.patch
+CVE-2021-29463.patch
+CVE-2021-29464.patch
+CVE-2021-29470.patch
+CVE-2021-29623.patch
+CVE-2021-32815.patch
+CVE-2021-34334.patch
+CVE-2021-34335.patch
+CVE-2021-29473.patch
+CVE-2021-37615.patch
+CVE-2021-37618.patch
+CVE-2021-37619.patch
+CVE-2021-37620.patch
+CVE-2021-37621.patch
+CVE-2021-37622.patch
+CVE-2021-37623.patch
+fix-gtest-1.11.patch
diff --minimal -Nru exiv2-0.27.3/debian/rules exiv2-0.27.3/debian/rules
--- exiv2-0.27.3/debian/rules 2020-08-08 18:53:14.000000000 +0200
+++ exiv2-0.27.3/debian/rules 2023-01-05 18:19:20.000000000 +0100
@@ -7,10 +7,11 @@
-DEXIV2_ENABLE_NLS=ON \
-DEXIV2_ENABLE_VIDEO=ON \
-DEXIV2_ENABLE_WEBREADY=ON \
- -DEXIV2_BUILD_SAMPLES=OFF
+ -DEXIV2_BUILD_SAMPLES=$(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),OFF,ON) \
+ -DEXIV2_BUILD_UNIT_TESTS=$(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),OFF,ON)
%:
- dh $@ --with pkgkde_symbolshelper --buildsystem cmake
+ dh $@ --with pkgkde_symbolshelper --buildsystem cmake --builddirectory=build
override_dh_auto_configure-indep:
dh_auto_configure -- \
@@ -33,6 +34,18 @@
dh_auto_build
dh_auto_build -- doc
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+override_dh_auto_test:
+ cp debian/test_data/* test/data/
+ # Ignore errors, because they were never enabled in bullseye before
+ # and we don't know whether they pass on all architectures.
+ -./build/bin/unit_tests
+ # Ignore errors, because
+ # bugfixes.github.test_issue_ghsa_mvc4_g5pv_4qqq.JpegBasePrintStructureInfiniteLoop
+ # produces a different error message than expected.
+ -$(MAKE) -C test python_tests
+endif
+
override_dh_installdocs:
dh_installdocs -A -Xcmd.txt -XMakefile -Xtemplates -XChangeLog
find $(CURDIR)/debian -name jquery.js -exec ln -sfv /usr/share/javascript/jquery/jquery.js {} \;
@@ -47,3 +60,6 @@
override_dh_fixperms-indep:
dh_fixperms -i
find $(CURDIR)/debian/libexiv2-doc -name '*.ini' -exec chmod -x {} \;
+
+execute_after_dh_clean:
+ for f in debian/test_data/*; do rm -f "test/$${f#debian/test_}"; done
diff --minimal -Nru exiv2-0.27.3/debian/source/include-binaries exiv2-0.27.3/debian/source/include-binaries
--- exiv2-0.27.3/debian/source/include-binaries 1970-01-01 01:00:00.000000000 +0100
+++ exiv2-0.27.3/debian/source/include-binaries 2023-01-05 18:19:20.000000000 +0100
@@ -0,0 +1,16 @@
+debian/test_data/issue_1530_poc.crw
+debian/test_data/issue_1530_poc.exv
+debian/test_data/issue_ghsa_583f_w9pm_99r2_poc.jp2
+debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.exv
+debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.jp2
+debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.exv
+debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.jp2
+debian/test_data/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg
+debian/test_data/issue_ghsa_h9x9_4f77_336w_poc.exv
+debian/test_data/issue_ghsa_m479_7frc_gqqg_poc.crw
+debian/test_data/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg
+debian/test_data/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2
+debian/test_data/issue_ghsa_pvjp_m4f6_q984_poc.exv
+debian/test_data/issue_ghsa_v5g7_46xf_h728_poc.exv
+debian/test_data/poc_1522.jp2
+debian/test_data/test_issue_ghsa_mv9g_fxh2_m49m.crw
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_1530_poc.crw and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_1530_poc.crw differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_1530_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_1530_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_583f_w9pm_99r2_poc.jp2 and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_583f_w9pm_99r2_poc.jp2 differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.jp2 and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_7569_phvm_vwc2_poc.jp2 differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.jp2 and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_8949_hhfh_j7rj_poc.jp2 differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_9jh3_fcc3_g6hv_poc.jpg differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_h9x9_4f77_336w_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_h9x9_4f77_336w_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_m479_7frc_gqqg_poc.crw and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_m479_7frc_gqqg_poc.crw differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_mvc4_g5pv_4qqq_poc.jpg differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2 and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2 differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_pvjp_m4f6_q984_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_pvjp_m4f6_q984_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/issue_ghsa_v5g7_46xf_h728_poc.exv and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/issue_ghsa_v5g7_46xf_h728_poc.exv differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/poc_1522.jp2 and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/poc_1522.jp2 differ
Binary files /tmp/2mNC_AwAvz/exiv2-0.27.3/debian/test_data/test_issue_ghsa_mv9g_fxh2_m49m.crw and /tmp/yhR6_tooWe/exiv2-0.27.3/debian/test_data/test_issue_ghsa_mv9g_fxh2_m49m.crw differ
-------------- next part --------------
A non-text attachment was scrubbed...
Name: exiv2_0.27.3-3+deb11u2.dsc
Type: text/prs.lines.tag
Size: 1440 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-kde-extras/attachments/20230110/ddd9f9a6/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: exiv2_0.27.3-3+deb11u2.debian.tar.xz
Type: application/x-xz
Size: 136680 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-kde-extras/attachments/20230110/ddd9f9a6/attachment-0001.xz>
More information about the pkg-kde-extras
mailing list