diff options
author | Vitaly Buka <vitalybuka@google.com> | 2017-09-02 03:15:13 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2017-09-02 03:15:13 +0000 |
commit | 074e282b60af6fa3954381faba5b121df4f4ea99 (patch) | |
tree | 0cd97172b966eada9f3b5e23ba0f3a0e2f3d987d /lib/WindowsManifest | |
parent | 4f10103672ff84759c4d2c1e675f04149b21366c (diff) |
llvm-mt: Fix memory management in WindowsManifestMergerImpl::getMergedManifest
Summary:
xmlDoc needs to be released with xmlFreeDoc.
XML_PARSE_NODICT is needed for safe moving nodes between documents.
Buffer returned from xmlDocDumpFormatMemoryEnc needs xmlFree, but it needs
outlive users of getMergedManifest results.
Reviewers: ecbeckmann, rnk, zturner, ruiu
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D37321
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312406 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/WindowsManifest')
-rw-r--r-- | lib/WindowsManifest/WindowsManifestMerger.cpp | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/lib/WindowsManifest/WindowsManifestMerger.cpp b/lib/WindowsManifest/WindowsManifestMerger.cpp index 91547c98469..c1ace5065e6 100644 --- a/lib/WindowsManifest/WindowsManifestMerger.cpp +++ b/lib/WindowsManifest/WindowsManifestMerger.cpp @@ -44,6 +44,14 @@ private: #if LLVM_LIBXML2_ENABLED xmlDocPtr CombinedDoc = nullptr; std::vector<xmlDocPtr> MergedDocs; + + bool Merged = false; + struct XmlDeleter { + void operator()(xmlChar *Ptr) { xmlFree(Ptr); } + void operator()(xmlDoc *Ptr) { xmlFreeDoc(Ptr); } + }; + int BufferSize = 0; + std::unique_ptr<xmlChar, XmlDeleter> Buffer; #endif bool ParseErrorOccurred = false; }; @@ -613,14 +621,17 @@ WindowsManifestMerger::WindowsManifestMergerImpl::~WindowsManifestMergerImpl() { Error WindowsManifestMerger::WindowsManifestMergerImpl::merge( const MemoryBuffer &Manifest) { + if (Merged) + return make_error<WindowsManifestError>( + "merge after getMergedManifest is not supported"); if (Manifest.getBufferSize() == 0) return make_error<WindowsManifestError>( "attempted to merge empty manifest"); xmlSetGenericErrorFunc((void *)this, WindowsManifestMergerImpl::errorCallback); - xmlDocPtr ManifestXML = - xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(), - "manifest.xml", nullptr, XML_PARSE_NOBLANKS); + xmlDocPtr ManifestXML = xmlReadMemory( + Manifest.getBufferStart(), Manifest.getBufferSize(), "manifest.xml", + nullptr, XML_PARSE_NOBLANKS | XML_PARSE_NODICT); xmlSetGenericErrorFunc(nullptr, nullptr); if (auto E = getParseError()) return E; @@ -646,22 +657,29 @@ Error WindowsManifestMerger::WindowsManifestMergerImpl::merge( std::unique_ptr<MemoryBuffer> WindowsManifestMerger::WindowsManifestMergerImpl::getMergedManifest() { - unsigned char *XmlBuff; - int BufferSize = 0; - if (CombinedDoc) { + if (!Merged) { + Merged = true; + + if (!CombinedDoc) + return nullptr; + xmlNodePtr CombinedRoot = xmlDocGetRootElement(CombinedDoc); std::vector<xmlNsPtr> RequiredPrefixes; checkAndStripPrefixes(CombinedRoot, RequiredPrefixes); - std::unique_ptr<xmlDoc> OutputDoc(xmlNewDoc((const unsigned char *)"1.0")); + std::unique_ptr<xmlDoc, XmlDeleter> OutputDoc( + xmlNewDoc((const unsigned char *)"1.0")); xmlDocSetRootElement(OutputDoc.get(), CombinedRoot); + assert(0 == xmlDocGetRootElement(CombinedDoc)); + xmlKeepBlanksDefault(0); - xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &XmlBuff, &BufferSize, "UTF-8", - 1); + xmlChar *Buff = nullptr; + xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &Buff, &BufferSize, "UTF-8", 1); + Buffer.reset(Buff); } - if (BufferSize == 0) - return nullptr; - return MemoryBuffer::getMemBuffer( - StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize)); + + return BufferSize ? MemoryBuffer::getMemBuffer(StringRef( + FROM_XML_CHAR(Buffer.get()), (size_t)BufferSize)) + : nullptr; } #else |