summaryrefslogtreecommitdiff
path: root/lib/WindowsManifest
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2017-09-02 03:15:13 +0000
committerVitaly Buka <vitalybuka@google.com>2017-09-02 03:15:13 +0000
commit074e282b60af6fa3954381faba5b121df4f4ea99 (patch)
tree0cd97172b966eada9f3b5e23ba0f3a0e2f3d987d /lib/WindowsManifest
parent4f10103672ff84759c4d2c1e675f04149b21366c (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.cpp44
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