Skip to content

Commit 8db56f0

Browse files
committed
[Demangler][Tests] Add an explicit test for getObjCClassByMangledName.
Added a special test for getObjCClassByMangledName; this needs testing separately as it uses the DecodedMetadataBuilder, which doesn't get exercised by the normal demangling tests. Added all the test cases from rdar://63485806, rdar://63488139, rdar://63496478, rdar://63410196 and rdar://68449341. The test cases from rdar://63485806 are disabled for now because the problem there is the error handling mechanism (or lack thereof), rather than us not handling errors. Fixes the remaining cases from rdar://63488139 rdar://63496478
1 parent 9a48cf9 commit 8db56f0

File tree

8 files changed

+130
-4
lines changed

8 files changed

+130
-4
lines changed

include/swift/Demangling/TypeLookupError.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ template <typename... Args>
207207
static TypeLookupError TypeLookupErrorImpl(const char *fmt, Args... args) {
208208
return TypeLookupError([=] {
209209
char *str;
210+
#pragma clang diagnostic push
211+
#pragma clang diagnostic ignored "-Wformat-security"
210212
swift_asprintf(&str, fmt, args...);
213+
#pragma clang diagnostic pop
211214
return str;
212215
});
213216
}

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "swift/Reflection/TypeLowering.h"
2525
#include "swift/Reflection/TypeRef.h"
2626
#include "llvm/ADT/Optional.h"
27-
2827
#include <vector>
2928
#include <unordered_map>
3029

lib/Demangling/Remangler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,9 +441,11 @@ std::pair<int, Node *> Remangler::mangleConstrainedType(Node *node,
441441
Chain.push_back(node->getChild(1), Factory);
442442
node = getChildOfType(node->getFirstChild());
443443
}
444-
444+
445445
if (node->getKind() != Node::Kind::DependentGenericParamType) {
446446
mangle(node, depth + 1);
447+
if (!Chain.size())
448+
return {-1, nullptr};
447449
node = nullptr;
448450
}
449451

stdlib/public/runtime/Metadata.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,10 @@ ExistentialMetatypeValueWitnessTableCacheEntry(unsigned numWitnessTables) {
34843484
SWIFT_RUNTIME_EXPORT
34853485
const ExistentialMetatypeMetadata *
34863486
swift::swift_getExistentialMetatypeMetadata(const Metadata *instanceMetadata) {
3487+
if (instanceMetadata->getKind() != MetadataKind::Existential
3488+
&& instanceMetadata->getKind() != MetadataKind::ExistentialMetatype)
3489+
return nullptr;
3490+
34873491
return &ExistentialMetatypes.getOrInsert(instanceMetadata).first->Data;
34883492
}
34893493

@@ -3494,7 +3498,6 @@ ExistentialMetatypeCacheEntry::ExistentialMetatypeCacheEntry(
34943498
flags = static_cast<const ExistentialTypeMetadata*>(instanceMetadata)
34953499
->Flags;
34963500
} else {
3497-
assert(instanceMetadata->getKind() == MetadataKind::ExistentialMetatype);
34983501
flags = static_cast<const ExistentialMetatypeMetadata*>(instanceMetadata)
34993502
->Flags;
35003503
}

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,13 @@ class DecodedMetadataBuilder {
14461446
TypeLookupErrorOr<BuiltType> createExistentialMetatypeType(
14471447
BuiltType instance,
14481448
llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const {
1449-
return swift_getExistentialMetatypeMetadata(instance);
1449+
BuiltType result = swift_getExistentialMetatypeMetadata(instance);
1450+
if (!result) {
1451+
return TYPE_LOOKUP_ERROR_FMT("Tried to build an existential metatype from "
1452+
"a type that was neither an existential nor "
1453+
"an existential metatype");
1454+
}
1455+
return result;
14501456
}
14511457

14521458
TypeLookupErrorOr<BuiltType>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# These were found by fuzzing getObjCClassByMangledName
2+
3+
# rdar://63485806
4+
# This results in an abort(), whereas it should be an error; rdar://79725187
5+
# covers improving error handling; until that's done, disable this test case
6+
7+
# 3…KySSyGSkySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
8+
# SSmSySyySGGSGyGSyySyySySSGGSGyS78iSLccSGSyySSySSGGccLcV1yVS~^§!zzzzzzzzzzzzhzzzzzSLzSEzzzzzzzzzzzzzzzzzxxxxx8K_S0ttnIx4_
9+
# ˇyySySyySySyGnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnSgZ1laSgSg
10+
# SSx3…KySyySGSSG_S2ItLHPˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇMd7KLPlKSSFTc•OSgS
11+
# 3…KySSiGSeySySSGiGSiySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
12+
# 3…KySSiGSyySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
13+
# SyySyySSySyyGSyySyyGGSGyGSyySySyySySSGGSGGˇˇˇˇˇS4S_SmˇˇAGmmmmmmmmmtLHPL(LHPTVdLHV
14+
15+
# rdar://63488139
16+
1_SxSt_S4KSgS9OSgRSLAPALÂ
17+
18+
# rdar://63496478
19+
BwXp
20+
1TSpXpBOXp
21+
SJSJSFSrSJSKSKSKSKm_tmcXpXpStmcXpXpSE_tmcXpXpmcXpXpStmcXpXpSE_tmcXpBpXp!E_tXpXpStmcXpZpSE_tmcXpXpSE_tmc3
22+
x_xSx_SxTd_SySyyS6dyGˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBˇˇˇˇˇˇˇˇˇˇXpXpXpf:8–VSBP0
23+
24+
# rdar://63410196
25+
SlSIxip6/XXS*”PLEPÓd}}}}}}}
26+
27+
# rdar://68449341
28+
ySfmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmf%mmmmmmmmmmmmmf%w

test/Demangle/lit.local.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# suffixes: A list of file extensions to treat as test files.
22
config.suffixes.add('.test')
3+
config.suffixes.add('.cpp')

test/Demangle/objc-getclass.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-clang %s -isysroot %sdk -L%swift_obj_root/lib/swift/%target-os-abi -lswiftCore -o %t/objc-getclass
3+
// RUN: %target-codesign %t/objc-getclass
4+
// RUN: %target-run %t/objc-getclass %S/Inputs/objc-getclass.txt
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: objc_interop
8+
9+
#include <objc/runtime.h>
10+
#include <dlfcn.h>
11+
#include <stdio.h>
12+
#include <ctype.h>
13+
#include <errno.h>
14+
#include <string.h>
15+
16+
static BOOL dummyHook(const char * _Nonnull name,
17+
Class _Nullable * _Nonnull outClass) {
18+
return NO;
19+
}
20+
21+
int main(int argc, char **argv) {
22+
if (argc != 2) {
23+
fprintf(stderr, "usage: objc-getclass <input.txt>\n"
24+
"\n"
25+
"Test demangling class names to get classes.\n");
26+
return 0;
27+
}
28+
29+
// Find the class-by-mangled-name hook
30+
objc_hook_getClass getObjCClassByMangledName = NULL;
31+
32+
if (__builtin_available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *)) {
33+
objc_hook_getClass dummy = NULL;
34+
objc_setHook_getClass(dummyHook, &getObjCClassByMangledName);
35+
objc_setHook_getClass(getObjCClassByMangledName, &dummy);
36+
} else {
37+
fprintf(stderr, "objc-getclass: macOS version is too old\n");
38+
return 1;
39+
}
40+
41+
// Open the input file
42+
FILE *fp = fopen(argv[1], "rt");
43+
if (!fp) {
44+
fprintf(stderr, "objc-getclass: unable to open \"%s\" - %s\n",
45+
argv[1], strerror(errno));
46+
}
47+
48+
// Input file is a list of manglings; we don't really care what classes they
49+
// resolve to here; this test is about whether or not they actually crash or
50+
// assert.
51+
char *line = NULL;
52+
size_t linecap = 0;
53+
ssize_t linelen = 0;
54+
55+
while ((linelen = getline(&line, &linecap, fp)) > 0) {
56+
char *mangling = line;
57+
58+
// Trim whitespace
59+
while (isspace(*mangling))
60+
++mangling;
61+
62+
char *end = line + linelen;
63+
while (end > line && isspace(end[-1]))
64+
--end;
65+
*end = '\0';
66+
67+
// Skip comments and blank lines
68+
if (*mangling == '#' || !*mangling)
69+
continue;
70+
71+
// Try to get a class
72+
Class outClass = nil;
73+
BOOL result = getObjCClassByMangledName(mangling, &outClass);
74+
75+
if (result)
76+
printf("%s -> %s\n", mangling, class_getName(outClass));
77+
else
78+
printf("%s not found\n", mangling);
79+
}
80+
81+
fclose(fp);
82+
83+
return 0;
84+
}

0 commit comments

Comments
 (0)