Skip to content

[Demangler][Tests] Re-add getObjcClassByMangledName test. #38903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/Demangling/TypeLookupError.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,10 @@ template <typename... Args>
static TypeLookupError TypeLookupErrorImpl(const char *fmt, Args... args) {
return TypeLookupError([=] {
char *str;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
swift_asprintf(&str, fmt, args...);
#pragma clang diagnostic pop
return str;
});
}
Expand Down
1 change: 0 additions & 1 deletion include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "swift/Reflection/TypeLowering.h"
#include "swift/Reflection/TypeRef.h"
#include "llvm/ADT/Optional.h"

#include <vector>
#include <unordered_map>

Expand Down
4 changes: 3 additions & 1 deletion lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,11 @@ std::pair<int, Node *> Remangler::mangleConstrainedType(Node *node,
Chain.push_back(node->getChild(1), Factory);
node = getChildOfType(node->getFirstChild());
}

if (node->getKind() != Node::Kind::DependentGenericParamType) {
mangle(node, depth + 1);
if (!Chain.size())
return {-1, nullptr};
node = nullptr;
}

Expand Down
10 changes: 7 additions & 3 deletions stdlib/public/runtime/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3490,13 +3490,17 @@ swift::swift_getExistentialMetatypeMetadata(const Metadata *instanceMetadata) {
ExistentialMetatypeCacheEntry::ExistentialMetatypeCacheEntry(
const Metadata *instanceMetadata) {
ExistentialTypeFlags flags;
if (instanceMetadata->getKind() == MetadataKind::Existential) {
switch (instanceMetadata->getKind()) {
case MetadataKind::Existential:
flags = static_cast<const ExistentialTypeMetadata*>(instanceMetadata)
->Flags;
} else {
assert(instanceMetadata->getKind() == MetadataKind::ExistentialMetatype);
break;
case MetadataKind::ExistentialMetatype:
flags = static_cast<const ExistentialMetatypeMetadata*>(instanceMetadata)
->Flags;
break;
default:
assert(false && "expected existential metadata");
}

Data.setKind(MetadataKind::ExistentialMetatype);
Expand Down
6 changes: 6 additions & 0 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,12 @@ class DecodedMetadataBuilder {
TypeLookupErrorOr<BuiltType> createExistentialMetatypeType(
BuiltType instance,
llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const {
if (instance->getKind() != MetadataKind::Existential
&& instance->getKind() != MetadataKind::ExistentialMetatype) {
return TYPE_LOOKUP_ERROR_FMT("Tried to build an existential metatype from "
"a type that was neither an existential nor "
"an existential metatype");
}
return swift_getExistentialMetatypeMetadata(instance);
}

Expand Down
28 changes: 28 additions & 0 deletions test/Demangle/Inputs/objc-getclass.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# These were found by fuzzing getObjCClassByMangledName

# rdar://63485806
# This results in an abort(), whereas it should be an error; rdar://79725187
# covers improving error handling; until that's done, disable this test case

# 3…KySSyGSkySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
# SSmSySyySGGSGyGSyySyySySSGGSGyS78iSLccSGSyySSySSGGccLcV1yVS~^§!zzzzzzzzzzzzhzzzzzSLzSEzzzzzzzzzzzzzzzzzxxxxx8K_S0ttnIx4_
# ˇyySySyySySyGnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnSgZ1laSgSg
# SSx3…KySyySGSSG_S2ItLHPˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇMd7KLPlKSSFTc•OSgS
# 3…KySSiGSeySySSGiGSiySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
# 3…KySSiGSyySySSGiG3(KˇˇˇˇˇˇˇˇˇˇˇˇˇˇCwKySSiKySS
# SyySyySSySyyGSyySyyGGSGyGSyySySyySySSGGSGGˇˇˇˇˇS4S_SmˇˇAGmmmmmmmmmtLHPL(LHPTVdLHV

# rdar://63488139
1_SxSt_S4KSgS9OSgRSLAPALÂ

# rdar://63496478
BwXp
1TSpXpBOXp
SJSJSFSrSJSKSKSKSKm_tmcXpXpStmcXpXpSE_tmcXpXpmcXpXpStmcXpXpSE_tmcXpBpXp!E_tXpXpStmcXpZpSE_tmcXpXpSE_tmc3
x_xSx_SxTd_SySyyS6dyGˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBˇˇˇˇˇˇˇˇˇˇXpXpXpf:8–VSBP0

# rdar://63410196
SlSIxip6/XXS*”PLEPÓd}}}}}}}

# rdar://68449341
ySfmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmf%mmmmmmmmmmmmmf%w
1 change: 1 addition & 0 deletions test/Demangle/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# suffixes: A list of file extensions to treat as test files.
config.suffixes.add('.test')
config.suffixes.add('.cpp')
84 changes: 84 additions & 0 deletions test/Demangle/objc-getclass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// RUN: %empty-directory(%t)
// RUN: %target-clang %s -isysroot %sdk -L%swift_obj_root/lib/swift/%target-sdk-name -lswiftCore -o %t/objc-getclass
// RUN: %target-codesign %t/objc-getclass
// RUN: %target-run %t/objc-getclass %S/Inputs/objc-getclass.txt

// REQUIRES: executable_test
// REQUIRES: objc_interop

#include <objc/runtime.h>
#include <dlfcn.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>

static BOOL dummyHook(const char * _Nonnull name,
Class _Nullable * _Nonnull outClass) {
return NO;
}

int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: objc-getclass <input.txt>\n"
"\n"
"Test demangling class names to get classes.\n");
return 0;
}

// Find the class-by-mangled-name hook
objc_hook_getClass getObjCClassByMangledName = NULL;

if (__builtin_available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *)) {
objc_hook_getClass dummy = NULL;
objc_setHook_getClass(dummyHook, &getObjCClassByMangledName);
objc_setHook_getClass(getObjCClassByMangledName, &dummy);
} else {
fprintf(stderr, "objc-getclass: macOS version is too old\n");
return 1;
}

// Open the input file
FILE *fp = fopen(argv[1], "rt");
if (!fp) {
fprintf(stderr, "objc-getclass: unable to open \"%s\" - %s\n",
argv[1], strerror(errno));
}

// Input file is a list of manglings; we don't really care what classes they
// resolve to here; this test is about whether or not they actually crash or
// assert.
char *line = NULL;
size_t linecap = 0;
ssize_t linelen = 0;

while ((linelen = getline(&line, &linecap, fp)) > 0) {
char *mangling = line;

// Trim whitespace
while (isspace(*mangling))
++mangling;

char *end = line + linelen;
while (end > line && isspace(end[-1]))
--end;
*end = '\0';

// Skip comments and blank lines
if (*mangling == '#' || !*mangling)
continue;

// Try to get a class
Class outClass = nil;
BOOL result = getObjCClassByMangledName(mangling, &outClass);

if (result)
printf("%s -> %s\n", mangling, class_getName(outClass));
else
printf("%s not found\n", mangling);
}

fclose(fp);

return 0;
}