diff options
Diffstat (limited to 'llvm/lib/Object/WindowsResource.cpp')
-rw-r--r-- | llvm/lib/Object/WindowsResource.cpp | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp index 2195a61..813b4b6 100644 --- a/llvm/lib/Object/WindowsResource.cpp +++ b/llvm/lib/Object/WindowsResource.cpp @@ -127,6 +127,39 @@ Error ResourceEntryRef::loadNext() { WindowsResourceParser::WindowsResourceParser() : Root(false) {} +static Error duplicateResourceError(const ResourceEntryRef& Entry, + StringRef File1, StringRef File2) { + std::string Ret; + raw_string_ostream OS(Ret); + + OS << "duplicate resource:"; + + OS << " type "; + if (Entry.checkTypeString()) { + std::string UTF8; + if (!convertUTF16ToUTF8String(Entry.getTypeString(), UTF8)) + UTF8 = "(failed conversion from UTF16)"; + OS << '\"' << UTF8 << '\"'; + } else { + OS << "ID " << Entry.getTypeID(); + } + + OS << "/name "; + if (Entry.checkNameString()) { + std::string UTF8; + if (!convertUTF16ToUTF8String(Entry.getNameString(), UTF8)) + UTF8 = "(failed conversion from UTF16)"; + OS << '\"' << UTF8 << '\"'; + } else { + OS << "ID " << Entry.getNameID(); + } + + OS << "/language " << Entry.getLanguage() << ", in " << File1 << " and in " + << File2; + + return make_error<GenericBinaryError>(OS.str(), object_error::parse_failed); +} + Error WindowsResourceParser::parse(WindowsResource *WR) { auto EntryOrErr = WR->getHeadEntry(); if (!EntryOrErr) { @@ -152,7 +185,13 @@ Error WindowsResourceParser::parse(WindowsResource *WR) { bool IsNewTypeString = false; bool IsNewNameString = false; - Root.addEntry(Entry, IsNewTypeString, IsNewNameString); + TreeNode* Node; + bool IsNewNode = Root.addEntry(Entry, InputFilenames.size(), + IsNewTypeString, IsNewNameString, Node); + InputFilenames.push_back(WR->getFileName()); + if (!IsNewNode) + return duplicateResourceError(Entry, InputFilenames[Node->Origin], + WR->getFileName()); if (IsNewTypeString) StringTable.push_back(Entry.getTypeString()); @@ -171,12 +210,14 @@ void WindowsResourceParser::printTree(raw_ostream &OS) const { Root.print(Writer, "Resource Tree"); } -void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry, +bool WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry, + uint32_t Origin, bool &IsNewTypeString, - bool &IsNewNameString) { + bool &IsNewNameString, + TreeNode *&Result) { TreeNode &TypeNode = addTypeNode(Entry, IsNewTypeString); TreeNode &NameNode = TypeNode.addNameNode(Entry, IsNewNameString); - NameNode.addLanguageNode(Entry); + return NameNode.addLanguageNode(Entry, Origin, Result); } WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) { @@ -186,10 +227,11 @@ WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) { WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion, uint16_t MinorVersion, - uint32_t Characteristics) + uint32_t Characteristics, + uint32_t Origin) : IsDataNode(true), MajorVersion(MajorVersion), MinorVersion(MinorVersion), - Characteristics(Characteristics) { - DataIndex = DataCount++; + Characteristics(Characteristics), Origin(Origin) { + DataIndex = DataCount++; } std::unique_ptr<WindowsResourceParser::TreeNode> @@ -205,9 +247,10 @@ WindowsResourceParser::TreeNode::createIDNode() { std::unique_ptr<WindowsResourceParser::TreeNode> WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion, uint16_t MinorVersion, - uint32_t Characteristics) { + uint32_t Characteristics, + uint32_t Origin) { return std::unique_ptr<TreeNode>( - new TreeNode(MajorVersion, MinorVersion, Characteristics)); + new TreeNode(MajorVersion, MinorVersion, Characteristics, Origin)); } WindowsResourceParser::TreeNode & @@ -228,24 +271,21 @@ WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry, return addIDChild(Entry.getNameID()); } -WindowsResourceParser::TreeNode & -WindowsResourceParser::TreeNode::addLanguageNode( - const ResourceEntryRef &Entry) { +bool WindowsResourceParser::TreeNode::addLanguageNode( + const ResourceEntryRef &Entry, uint32_t Origin, TreeNode *&Result) { return addDataChild(Entry.getLanguage(), Entry.getMajorVersion(), - Entry.getMinorVersion(), Entry.getCharacteristics()); + Entry.getMinorVersion(), Entry.getCharacteristics(), + Origin, Result); } -WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addDataChild( +bool WindowsResourceParser::TreeNode::addDataChild( uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion, - uint32_t Characteristics) { - auto Child = IDChildren.find(ID); - if (Child == IDChildren.end()) { - auto NewChild = createDataNode(MajorVersion, MinorVersion, Characteristics); - WindowsResourceParser::TreeNode &Node = *NewChild; - IDChildren.emplace(ID, std::move(NewChild)); - return Node; - } else - return *(Child->second); + uint32_t Characteristics, uint32_t Origin, TreeNode *&Result) { + auto NewChild = + createDataNode(MajorVersion, MinorVersion, Characteristics, Origin); + auto ElementInserted = IDChildren.emplace(ID, std::move(NewChild)); + Result = ElementInserted.first->second.get(); + return ElementInserted.second; } WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addIDChild( |