1From 1bdf6d8ba878c1fe1d779824be70001fc0bebd2c Mon Sep 17 00:00:00 2001
2From: Even Rouault <even.rouault@spatialys.com>
3Date: Fri, 27 Aug 2021 01:33:27 +0200
4Subject: [PATCH] InMemMsgLoader::loadMsg(): fix memory leak when transcoding
5 fails.
6
7Seen with the IconvGNU transcoder when parsing "<aaa.xsdopengis.net/gml\x96".
8The reason is that XMLString::transcode(repText2, manager) throws a TranscodingException
9which causes the tmp1 string to leak.
10
11```
120 0x8791409 in operator new(unsigned int) /src/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:99:3
131 0xbd147f7 in xercesc_4_0::MemoryManagerImpl::allocate(unsigned int) gdal/xerces-c/src/xercesc/internal/MemoryManagerImpl.cpp:40:18
142 0xbe8c73e in xercesc_4_0::IconvGNULCPTranscoder::transcode(char const*, xercesc_4_0::MemoryManager*) gdal/xerces-c/src/xercesc/util/Transcoders/IconvGNU/IconvGNUTransService.cpp:870:32
153 0xbc22ca2 in xercesc_4_0::XMLString::transcode(char const*, xercesc_4_0::MemoryManager*) gdal/xerces-c/src/xercesc/util/XMLString.cpp:621:25
164 0xbe8f4ad in xercesc_4_0::InMemMsgLoader::loadMsg(unsigned int, char16_t*, unsigned int, char const*, char const*, char const*, char const*, xercesc_4_0::MemoryManager*) gdal/xerces-c/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp:157:16
175 0xbc20175 in xercesc_4_0::XMLException::loadExceptText(xercesc_4_0::XMLExcepts::Codes, char const*, char const*, char const*, char const*) gdal/xerces-c/src/xercesc/util/XMLException.cpp:241:23
186 0xbc48bee in xercesc_4_0::UTFDataFormatException::UTFDataFormatException(char const*, unsigned long long, xercesc_4_0::XMLExcepts::Codes, char const*, char const*, char const*, char const*, xercesc_4_0::MemoryManager*) gdal/xerces-c/src/xercesc/util/UTFDataFormatException.hpp:31:1
197 0xbc4824e in xercesc_4_0::XMLUTF8Transcoder::transcodeFrom(unsigned char const*, unsigned int, char16_t*, unsigned int, unsigned int&, unsigned char*) gdal/xerces-c/src/xercesc/util/XMLUTF8Transcoder.cpp:182:13
208 0xbd27d7e in xercesc_4_0::XMLReader::xcodeMoreChars(char16_t*, unsigned char*, unsigned int) gdal/xerces-c/src/xercesc/internal/XMLReader.cpp:1926:34
219 0xbd271dd in xercesc_4_0::XMLReader::refreshCharBuffer() gdal/xerces-c/src/xercesc/internal/XMLReader.cpp:571:19
2210 0xbd15c63 in xercesc_4_0::XMLReader::peekNextChar(char16_t&) gdal/xerces-c/src/xercesc/internal/XMLReader.hpp:767:14
2311 0xbd15aaf in xercesc_4_0::ReaderMgr::peekNextChar() gdal/xerces-c/src/xercesc/internal/ReaderMgr.cpp:158:21
2412 0xbd328da in xercesc_4_0::XMLScanner::scanProlog() gdal/xerces-c/src/xercesc/internal/XMLScanner.cpp:1241:45
2513 0xbd31ef4 in xercesc_4_0::XMLScanner::scanFirst(xercesc_4_0::InputSource const&, xercesc_4_0::XMLPScanToken&) gdal/xerces-c/src/xercesc/internal/XMLScanner.cpp:549:9
2614 0xbdadcff in xercesc_4_0::SAX2XMLReaderImpl::parseFirst(xercesc_4_0::InputSource const&, xercesc_4_0::XMLPScanToken&) gdal/xerces-c/src/xercesc/parsers/SAX2XMLReaderImpl.cpp:500:22
27```
28Upstream: https://github.com/apache/xerces-c/commit/1bdf6d8ba878c1fe1d779824be70001fc0bebd2c
29
30Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
31
32---
33 .../MsgLoaders/InMemory/InMemMsgLoader.cpp    | 31 ++++++++++++++-----
34 1 file changed, 23 insertions(+), 8 deletions(-)
35
36diff --git a/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp b/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp
37index cda103226..6971fde96 100644
38--- a/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp
39+++ b/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp
40@@ -25,6 +25,7 @@
41 // ---------------------------------------------------------------------------
42 #include <xercesc/util/BitOps.hpp>
43 #include <xercesc/util/PlatformUtils.hpp>
44+#include <xercesc/util/TranscodingException.hpp>
45 #include <xercesc/util/XMLMsgLoader.hpp>
46 #include <xercesc/util/XMLString.hpp>
47 #include <xercesc/util/XMLUni.hpp>
48@@ -153,14 +154,28 @@ bool InMemMsgLoader::loadMsg(const  XMLMsgLoader::XMLMsgId  msgToLoad
49     XMLCh* tmp4 = 0;
50
51     bool bRet = false;
52-    if (repText1)
53-        tmp1 = XMLString::transcode(repText1, manager);
54-    if (repText2)
55-        tmp2 = XMLString::transcode(repText2, manager);
56-    if (repText3)
57-        tmp3 = XMLString::transcode(repText3, manager);
58-    if (repText4)
59-        tmp4 = XMLString::transcode(repText4, manager);
60+    try
61+    {
62+        if (repText1)
63+            tmp1 = XMLString::transcode(repText1, manager);
64+        if (repText2)
65+            tmp2 = XMLString::transcode(repText2, manager);
66+        if (repText3)
67+            tmp3 = XMLString::transcode(repText3, manager);
68+        if (repText4)
69+            tmp4 = XMLString::transcode(repText4, manager);
70+    }
71+    catch( const TranscodingException& )
72+    {
73+        if (tmp1)
74+            manager->deallocate(tmp1);
75+        if (tmp2)
76+            manager->deallocate(tmp2);
77+        if (tmp3)
78+            manager->deallocate(tmp3);
79+        // Note: tmp4 cannot leak
80+        throw;
81+    }
82
83     bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4, manager);
84
85--
862.17.1
87
88