Skip to content

Commit d65bae5

Browse files
committed
demangler: catch more cases where the demangler crashes on malformed symbols
1 parent 300d261 commit d65bae5

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

lib/Demangling/Demangler.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ NodePointer Demangler::demangleTypeMangling() {
392392
auto TypeMangling = createNode(Node::Kind::TypeMangling);
393393

394394
addChild(TypeMangling, LabelList);
395-
addChild(TypeMangling, Type);
395+
TypeMangling = addChild(TypeMangling, Type);
396396
return TypeMangling;
397397
}
398398

@@ -908,8 +908,12 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
908908
auto LabelList = createNode(Node::Kind::LabelList);
909909
for (unsigned i = 0, n = ParameterType->getIndex(); i != n; ++i) {
910910
auto Label = popNode();
911-
assert(Label && (Label->getKind() == Node::Kind::Identifier ||
912-
Label->getKind() == Node::Kind::FirstElementMarker));
911+
if (!Label)
912+
return nullptr;
913+
if (Label->getKind() != Node::Kind::Identifier &&
914+
Label->getKind() != Node::Kind::FirstElementMarker)
915+
return nullptr;
916+
913917
LabelList->addChild(Label, *this);
914918
}
915919

@@ -1999,16 +2003,16 @@ NodePointer Demangler::demangleFunctionEntity() {
19992003
case None:
20002004
break;
20012005
case Index:
2002-
addChild(Entity, NameOrIndex);
2006+
Entity = addChild(Entity, NameOrIndex);
20032007
break;
20042008
case TypeAndMaybePrivateName:
20052009
addChild(Entity, LabelList);
2006-
addChild(Entity, ParamType);
2010+
Entity = addChild(Entity, ParamType);
20072011
addChild(Entity, NameOrIndex);
20082012
break;
20092013
case TypeAndIndex:
2010-
addChild(Entity, NameOrIndex);
2011-
addChild(Entity, ParamType);
2014+
Entity = addChild(Entity, NameOrIndex);
2015+
Entity = addChild(Entity, ParamType);
20122016
break;
20132017
}
20142018
return Entity;
@@ -2035,9 +2039,9 @@ NodePointer Demangler::demangleSubscript() {
20352039
NodePointer Context = popContext();
20362040

20372041
NodePointer Subscript = createNode(Node::Kind::Subscript);
2038-
addChild(Subscript, Context);
2042+
Subscript = addChild(Subscript, Context);
20392043
addChild(Subscript, LabelList);
2040-
addChild(Subscript, Type);
2044+
Subscript = addChild(Subscript, Type);
20412045
addChild(Subscript, PrivateName);
20422046

20432047
return demangleAccessor(Subscript);

lib/Demangling/NodePrinter.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,27 @@ class NodePrinter {
163163
DemanglerPrinter Printer;
164164
DemangleOptions Options;
165165
bool SpecializationPrefixPrinted = false;
166+
bool isValid = true;
166167

167168
public:
168169
NodePrinter(DemangleOptions options) : Options(options) {}
169170

170171
std::string printRoot(NodePointer root) {
172+
isValid = true;
171173
print(root);
172-
return std::move(Printer).str();
174+
if (isValid)
175+
return std::move(Printer).str();
176+
return "";
173177
}
174178

175-
private:
179+
private:
180+
/// Called when the node tree in valid.
181+
///
182+
/// The demangler already catches most error cases and mostly produces valid
183+
/// node trees. But some cases are difficult to catch in the demangler and
184+
/// instead the NodePrinter bails.
185+
void setInvalid() { isValid = false; }
186+
176187
void printChildren(Node::iterator begin,
177188
Node::iterator end,
178189
const char *sep = nullptr) {
@@ -553,7 +564,10 @@ class NodePrinter {
553564

554565
void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType,
555566
bool showTypes) {
556-
assert(ParameterType->getKind() == Node::Kind::ArgumentTuple);
567+
if (ParameterType->getKind() != Node::Kind::ArgumentTuple) {
568+
setInvalid();
569+
return;
570+
}
557571

558572
NodePointer Parameters = ParameterType->getFirstChild();
559573
assert(Parameters->getKind() == Node::Kind::Type);
@@ -609,7 +623,10 @@ class NodePrinter {
609623
}
610624

611625
void printFunctionType(NodePointer LabelList, NodePointer node) {
612-
assert(node->getNumChildren() == 2 || node->getNumChildren() == 3);
626+
if (node->getNumChildren() != 2 && node->getNumChildren() != 3) {
627+
setInvalid();
628+
return;
629+
}
613630
unsigned startIndex = 0;
614631
if (node->getChild(0)->getKind() == Node::Kind::ThrowsAnnotation)
615632
startIndex = 1;
@@ -1925,6 +1942,10 @@ printEntity(NodePointer Entity, bool asPrefixContext, TypePrinting TypePr,
19251942
if (TypePr != TypePrinting::NoType) {
19261943
NodePointer type = getChildIf(Entity, Node::Kind::Type);
19271944
assert(type && "malformed entity");
1945+
if (!type) {
1946+
setInvalid();
1947+
return nullptr;
1948+
}
19281949
type = type->getChild(0);
19291950
if (TypePr == TypePrinting::FunctionStyle) {
19301951
// We expect to see a function type here, but if we don't, use the colon.

test/Demangle/Inputs/manglings.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,10 @@ _T0So5GizmoC11doSomethingySQyypGSQySaySSGGFToTembnn_ ---> outlined bridged metho
278278
_T0So5GizmoC12modifyString_10withNumber0D6FoobarSQySSGAF_SiSQyypGtFToTembnnnb_ ---> outlined bridged method (mbnnnb) of @objc __ObjC.Gizmo.modifyString(_: Swift.String!, withNumber: Swift.Int, withFoobar: Any!) -> Swift.String!
279279
_T04test1SVyxGAA1RA2A1ZRzAA1Y2ZZRpzl1A_AhaGPWT ---> {C} associated type witness table accessor for A.ZZ : test.Y in <A where A: test.Z, A.ZZ: test.Y> test.S<A> : test.R in test
280280
_T0s24_UnicodeScalarExceptions33_0E4228093681F6920F0AB2E48B4F1C69LLVACycfC ---> Swift.(_UnicodeScalarExceptions in _0E4228093681F6920F0AB2E48B4F1C69).init() -> Swift.(_UnicodeScalarExceptions in _0E4228093681F6920F0AB2E48B4F1C69)
281+
_T0D ---> _T0D
282+
_T0s18EnumeratedIteratorVyxGs8Sequencess0B8ProtocolRzlsADP5splitSay03SubC0QzGSi9maxSplits_Sb25omittingEmptySubsequencesSb7ElementQzKc14whereSeparatortKFTW ---> _T0s18EnumeratedIteratorVyxGs8Sequencess0B8ProtocolRzlsADP5splitSay03SubC0QzGSi9maxSplits_Sb25omittingEmptySubsequencesSb7ElementQzKc14whereSeparatortKFTW
283+
_T0s3SetVyxGs10CollectiotySivm ---> _T0s3SetVyxGs10CollectiotySivm
284+
_T0s18ReversedCollectionVyxGs04LazyB8ProtocolfC ---> _T0s18ReversedCollectionVyxGs04LazyB8ProtocolfC
285+
_T0iW ---> _T0iW
286+
_T0s5print_9separator10terminatoryypfC ---> _T0s5print_9separator10terminatoryypfC
281287

0 commit comments

Comments
 (0)