summaryrefslogtreecommitdiffstats
path: root/source/l/exiv2/patches/16c1cd7d.patch
blob: fc8dc9b28110bdbf7a3f7fb2c707a52088690091 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
From 16c1cd7da0cd159ee2d53c39088564edaf046c77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Milo=C5=A1=20Komar=C4=8Devi=C4=87?=
 <miloskomarcevic@aim.com>
Date: Fri, 16 Jun 2023 17:05:39 +0200
Subject: [PATCH] Fix regression parsing PNG text chunks with zero length
 payload

---
 src/pngchunk_int.cpp | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp
index 697a30c63c..81fbcd942d 100644
--- a/src/pngchunk_int.cpp
+++ b/src/pngchunk_int.cpp
@@ -100,20 +100,24 @@ DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkTyp
     }
 
     // compressed string after the compression technique spec
-    const byte* compressedText = data.c_data(keysize + nullSeparators);
     size_t compressedTextSize = data.size() - keysize - nullSeparators;
-    enforce(compressedTextSize < data.size(), ErrorCode::kerCorruptedMetadata);
+    if (compressedTextSize) {
+      const byte* compressedText = data.c_data(keysize + nullSeparators);
+      enforce(compressedTextSize < data.size(), ErrorCode::kerCorruptedMetadata);
 
-    zlibUncompress(compressedText, static_cast<uint32_t>(compressedTextSize), arr);
+      zlibUncompress(compressedText, static_cast<uint32_t>(compressedTextSize), arr);
+    }
   } else if (type == tEXt_Chunk) {
     enforce(data.size() >= Safe::add(keysize, static_cast<size_t>(1)), ErrorCode::kerCorruptedMetadata);
     // Extract a non-compressed Latin-1 text chunk
 
     // the text comes after the key, but isn't null terminated
-    const byte* text = data.c_data(keysize + 1);
     size_t textsize = data.size() - keysize - 1;
+    if (textsize) {
+      const byte* text = data.c_data(keysize + 1);
 
-    arr = DataBuf(text, textsize);
+      arr = DataBuf(text, textsize);
+    }
   } else if (type == iTXt_Chunk) {
     enforce(data.size() > Safe::add(keysize, static_cast<size_t>(3)), ErrorCode::kerCorruptedMetadata);
     const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size() - 1), '\0');
@@ -127,7 +131,8 @@ DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkTyp
     const byte compressionMethod = data.read_uint8(keysize + 2);
 
     enforce(compressionFlag == 0x00 || compressionFlag == 0x01, ErrorCode::kerCorruptedMetadata);
-    enforce(compressionMethod == 0x00, ErrorCode::kerCorruptedMetadata);
+    if (compressionFlag == 0x01)
+      enforce(compressionMethod == 0x00, ErrorCode::kerFailedToReadImageData);
 
     // language description string after the compression technique spec
     const size_t languageTextMaxSize = data.size() - keysize - 3;
@@ -141,14 +146,14 @@ DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkTyp
                                                              data.size() - (keysize + 3 + languageTextSize + 1));
     const size_t translatedKeyTextSize = translatedKeyText.size();
 
-    if ((compressionFlag == 0x00) || (compressionFlag == 0x01 && compressionMethod == 0x00)) {
-      enforce(Safe::add(keysize + 3 + languageTextSize + 1, Safe::add(translatedKeyTextSize, static_cast<size_t>(1))) <=
-                  data.size(),
-              ErrorCode::kerCorruptedMetadata);
+    enforce(Safe::add(keysize + 3 + languageTextSize + 1, Safe::add(translatedKeyTextSize, static_cast<size_t>(1))) <=
+                data.size(),
+            ErrorCode::kerCorruptedMetadata);
 
+    const auto textsize =
+        static_cast<long>(data.size() - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1));
+    if (textsize) {
       const byte* text = data.c_data(keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1);
-      const auto textsize =
-          static_cast<long>(data.size() - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1));
 
       if (compressionFlag == 0x00) {
         // then it's an uncompressed iTXt chunk
@@ -156,7 +161,7 @@ DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkTyp
         std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n";
 #endif
         arr = DataBuf(text, textsize);
-      } else if (compressionFlag == 0x01 && compressionMethod == 0x00) {
+      } else {
         // then it's a zlib compressed iTXt chunk
 #ifdef EXIV2_DEBUG_MESSAGES
         std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n";
@@ -165,12 +170,6 @@ DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkTyp
         // the compressed text comes after the translated keyword, but isn't null terminated
         zlibUncompress(text, textsize, arr);
       }
-    } else {
-      // then it isn't zlib compressed and we are sunk
-#ifdef EXIV2_DEBUG_MESSAGES
-      std::cerr << "Exiv2::PngChunk::parseTXTChunk: Non-standard iTXt compression method.\n";
-#endif
-      throw Error(ErrorCode::kerFailedToReadImageData);
     }
   } else {
 #ifdef DEBUG