llvm.org GIT mirror llvm / 074e282
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 Vitaly Buka 1 year, 11 months ago
1 changed file(s) with 32 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
4343 #if LLVM_LIBXML2_ENABLED
4444 xmlDocPtr CombinedDoc = nullptr;
4545 std::vector MergedDocs;
46
47 bool Merged = false;
48 struct XmlDeleter {
49 void operator()(xmlChar *Ptr) { xmlFree(Ptr); }
50 void operator()(xmlDoc *Ptr) { xmlFreeDoc(Ptr); }
51 };
52 int BufferSize = 0;
53 std::unique_ptr Buffer;
4654 #endif
4755 bool ParseErrorOccurred = false;
4856 };
612620
613621 Error WindowsManifestMerger::WindowsManifestMergerImpl::merge(
614622 const MemoryBuffer &Manifest) {
623 if (Merged)
624 return make_error(
625 "merge after getMergedManifest is not supported");
615626 if (Manifest.getBufferSize() == 0)
616627 return make_error(
617628 "attempted to merge empty manifest");
618629 xmlSetGenericErrorFunc((void *)this,
619630 WindowsManifestMergerImpl::errorCallback);
620 xmlDocPtr ManifestXML =
621 xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(),
622 "manifest.xml", nullptr, XML_PARSE_NOBLANKS);
631 xmlDocPtr ManifestXML = xmlReadMemory(
632 Manifest.getBufferStart(), Manifest.getBufferSize(), "manifest.xml",
633 nullptr, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);
623634 xmlSetGenericErrorFunc(nullptr, nullptr);
624635 if (auto E = getParseError())
625636 return E;
645656
646657 std::unique_ptr
647658 WindowsManifestMerger::WindowsManifestMergerImpl::getMergedManifest() {
648 unsigned char *XmlBuff;
649 int BufferSize = 0;
650 if (CombinedDoc) {
659 if (!Merged) {
660 Merged = true;
661
662 if (!CombinedDoc)
663 return nullptr;
664
651665 xmlNodePtr CombinedRoot = xmlDocGetRootElement(CombinedDoc);
652666 std::vector RequiredPrefixes;
653667 checkAndStripPrefixes(CombinedRoot, RequiredPrefixes);
654 std::unique_ptr> OutputDoc(xmlNewDoc((const unsigned char *)"1.0"));
668 std::unique_ptr, XmlDeleter> OutputDoc(
669 xmlNewDoc((const unsigned char *)"1.0"));
655670 xmlDocSetRootElement(OutputDoc.get(), CombinedRoot);
671 assert(0 == xmlDocGetRootElement(CombinedDoc));
672
656673 xmlKeepBlanksDefault(0);
657 xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &XmlBuff, &BufferSize, "UTF-8",
658 1);
659 }
660 if (BufferSize == 0)
661 return nullptr;
662 return MemoryBuffer::getMemBuffer(
663 StringRef(FROM_XML_CHAR(XmlBuff), (size_t)BufferSize));
674 xmlChar *Buff = nullptr;
675 xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &Buff, &BufferSize, "UTF-8", 1);
676 Buffer.reset(Buff);
677 }
678
679 return BufferSize ? MemoryBuffer::getMemBuffer(StringRef(
680 FROM_XML_CHAR(Buffer.get()), (size_t)BufferSize))
681 : nullptr;
664682 }
665683
666684 #else