Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 074e282

Browse files
committed
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
1 parent 4f10103 commit 074e282

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

lib/WindowsManifest/WindowsManifestMerger.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ class WindowsManifestMerger::WindowsManifestMergerImpl {
4444
#if LLVM_LIBXML2_ENABLED
4545
xmlDocPtr CombinedDoc = nullptr;
4646
std::vector<xmlDocPtr> MergedDocs;
47+
48+
bool Merged = false;
49+
struct XmlDeleter {
50+
void operator()(xmlChar *Ptr) { xmlFree(Ptr); }
51+
void operator()(xmlDoc *Ptr) { xmlFreeDoc(Ptr); }
52+
};
53+
int BufferSize = 0;
54+
std::unique_ptr<xmlChar, XmlDeleter> Buffer;
4755
#endif
4856
bool ParseErrorOccurred = false;
4957
};
@@ -613,14 +621,17 @@ WindowsManifestMerger::WindowsManifestMergerImpl::~WindowsManifestMergerImpl() {
613621

614622
Error WindowsManifestMerger::WindowsManifestMergerImpl::merge(
615623
const MemoryBuffer &Manifest) {
624+
if (Merged)
625+
return make_error<WindowsManifestError>(
626+
"merge after getMergedManifest is not supported");
616627
if (Manifest.getBufferSize() == 0)
617628
return make_error<WindowsManifestError>(
618629
"attempted to merge empty manifest");
619630
xmlSetGenericErrorFunc((void *)this,
620631
WindowsManifestMergerImpl::errorCallback);
621-
xmlDocPtr ManifestXML =
622-
xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(),
623-
"manifest.xml", nullptr, XML_PARSE_NOBLANKS);
632+
xmlDocPtr ManifestXML = xmlReadMemory(
633+
Manifest.getBufferStart(), Manifest.getBufferSize(), "manifest.xml",
634+
nullptr, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);
624635
xmlSetGenericErrorFunc(nullptr, nullptr);
625636
if (auto E = getParseError())
626637
return E;
@@ -646,22 +657,29 @@ Error WindowsManifestMerger::WindowsManifestMergerImpl::merge(
646657

647658
std::unique_ptr<MemoryBuffer>
648659
WindowsManifestMerger::WindowsManifestMergerImpl::getMergedManifest() {
649-
unsigned char *XmlBuff;
650-
int BufferSize = 0;
651-
if (CombinedDoc) {
660+
if (!Merged) {
661+
Merged = true;
662+
663+
if (!CombinedDoc)
664+
return nullptr;
665+
652666
xmlNodePtr CombinedRoot = xmlDocGetRootElement(CombinedDoc);
653667
std::vector<xmlNsPtr> RequiredPrefixes;
654668
checkAndStripPrefixes(CombinedRoot, RequiredPrefixes);
655-
std::unique_ptr<xmlDoc> OutputDoc(xmlNewDoc((const unsigned char *)"1.0"));
669+
std::unique_ptr<xmlDoc, XmlDeleter> OutputDoc(
670+
xmlNewDoc((const unsigned char *)"1.0"));
656671
xmlDocSetRootElement(OutputDoc.get(), CombinedRoot);
672+
assert(0 == xmlDocGetRootElement(CombinedDoc));
673+
657674
xmlKeepBlanksDefault(0);
658-
xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &XmlBuff, &BufferSize, "UTF-8",
659-
1);
675+
xmlChar *Buff = nullptr;
676+
xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &Buff, &BufferSize, "UTF-8", 1);
677+
Buffer.reset(Buff);
660678
}
661-
if (BufferSize == 0)
662-
return nullptr;
663-
return MemoryBuffer::getMemBuffer(
664-
StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize));
679+
680+
return BufferSize ? MemoryBuffer::getMemBuffer(StringRef(
681+
FROM_XML_CHAR(Buffer.get()), (size_t)BufferSize))
682+
: nullptr;
665683
}
666684

667685
#else

0 commit comments

Comments
 (0)