| From 1bdf6d8ba878c1fe1d779824be70001fc0bebd2c Mon Sep 17 00:00:00 2001 |
| From: Even Rouault <even.rouault@spatialys.com> |
| Date: Fri, 27 Aug 2021 01:33:27 +0200 |
| Subject: [PATCH] InMemMsgLoader::loadMsg(): fix memory leak when transcoding |
| fails. |
| |
| Seen with the IconvGNU transcoder when parsing "<aaa.xsdopengis.net/gml\x96". |
| The reason is that XMLString::transcode(repText2, manager) throws a TranscodingException |
| which causes the tmp1 string to leak. |
| |
| ``` |
| 0 0x8791409 in operator new(unsigned int) /src/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:99:3 |
| 1 0xbd147f7 in xercesc_4_0::MemoryManagerImpl::allocate(unsigned int) gdal/xerces-c/src/xercesc/internal/MemoryManagerImpl.cpp:40:18 |
| 2 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 |
| 3 0xbc22ca2 in xercesc_4_0::XMLString::transcode(char const*, xercesc_4_0::MemoryManager*) gdal/xerces-c/src/xercesc/util/XMLString.cpp:621:25 |
| 4 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 |
| 5 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 |
| 6 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 |
| 7 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 |
| 8 0xbd27d7e in xercesc_4_0::XMLReader::xcodeMoreChars(char16_t*, unsigned char*, unsigned int) gdal/xerces-c/src/xercesc/internal/XMLReader.cpp:1926:34 |
| 9 0xbd271dd in xercesc_4_0::XMLReader::refreshCharBuffer() gdal/xerces-c/src/xercesc/internal/XMLReader.cpp:571:19 |
| 10 0xbd15c63 in xercesc_4_0::XMLReader::peekNextChar(char16_t&) gdal/xerces-c/src/xercesc/internal/XMLReader.hpp:767:14 |
| 11 0xbd15aaf in xercesc_4_0::ReaderMgr::peekNextChar() gdal/xerces-c/src/xercesc/internal/ReaderMgr.cpp:158:21 |
| 12 0xbd328da in xercesc_4_0::XMLScanner::scanProlog() gdal/xerces-c/src/xercesc/internal/XMLScanner.cpp:1241:45 |
| 13 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 |
| 14 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 |
| ``` |
| Upstream: https://github.com/apache/xerces-c/commit/1bdf6d8ba878c1fe1d779824be70001fc0bebd2c |
| |
| Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com> |
| |
| --- |
| .../MsgLoaders/InMemory/InMemMsgLoader.cpp | 31 ++++++++++++++----- |
| 1 file changed, 23 insertions(+), 8 deletions(-) |
| |
| diff --git a/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp b/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp |
| index cda103226..6971fde96 100644 |
| --- a/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp |
| +++ b/src/xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.cpp |
| @@ -25,6 +25,7 @@ |
| // --------------------------------------------------------------------------- |
| #include <xercesc/util/BitOps.hpp> |
| #include <xercesc/util/PlatformUtils.hpp> |
| +#include <xercesc/util/TranscodingException.hpp> |
| #include <xercesc/util/XMLMsgLoader.hpp> |
| #include <xercesc/util/XMLString.hpp> |
| #include <xercesc/util/XMLUni.hpp> |
| @@ -153,14 +154,28 @@ bool InMemMsgLoader::loadMsg(const XMLMsgLoader::XMLMsgId msgToLoad |
| XMLCh* tmp4 = 0; |
| |
| bool bRet = false; |
| - if (repText1) |
| - tmp1 = XMLString::transcode(repText1, manager); |
| - if (repText2) |
| - tmp2 = XMLString::transcode(repText2, manager); |
| - if (repText3) |
| - tmp3 = XMLString::transcode(repText3, manager); |
| - if (repText4) |
| - tmp4 = XMLString::transcode(repText4, manager); |
| + try |
| + { |
| + if (repText1) |
| + tmp1 = XMLString::transcode(repText1, manager); |
| + if (repText2) |
| + tmp2 = XMLString::transcode(repText2, manager); |
| + if (repText3) |
| + tmp3 = XMLString::transcode(repText3, manager); |
| + if (repText4) |
| + tmp4 = XMLString::transcode(repText4, manager); |
| + } |
| + catch( const TranscodingException& ) |
| + { |
| + if (tmp1) |
| + manager->deallocate(tmp1); |
| + if (tmp2) |
| + manager->deallocate(tmp2); |
| + if (tmp3) |
| + manager->deallocate(tmp3); |
| + // Note: tmp4 cannot leak |
| + throw; |
| + } |
| |
| bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4, manager); |
| |
| -- |
| 2.17.1 |
| |