Skip to content

Commit b75924d

Browse files
committed
[General] Avoid crashing for cases where NSStringFromClass returns nil
1 parent b50f801 commit b75924d

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

Sources/classdumpctl/main.m

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -496,15 +496,25 @@ int main(int argc, char *argv[]) {
496496
unsigned int classCount = 0;
497497
const char **classNames = objc_copyClassNamesForImage(requestImage.fileSystemRepresentation, &classCount);
498498
for (unsigned int classIndex = 0; classIndex < classCount; classIndex++) {
499+
const char *const className = classNames[classIndex];
499500
if (listFlag) {
500-
printf("%s\n", classNames[classIndex]);
501+
printf("%s\n", className);
501502
continue;
502503
}
503-
Class const cls = objc_getClass(classNames[classIndex]);
504+
// this is the same method `NSStringFromClass` uses
505+
NSString *const nsClassName = [[NSString alloc] initWithCString:className encoding:NSUTF8StringEncoding];
506+
if (nsClassName == nil) {
507+
// these contain byte sequences that don't map to characters.
508+
// NSString doesn't seem to want to represent these sequences.
509+
// Since the header contents is broken anyway in this case, skip for now.
510+
NSLog(@"Skipping class with unsupported name: '%s'", className);
511+
continue;
512+
}
513+
Class const cls = objc_getClass(className);
504514
CDClassModel *model = safelyGenerateModelForClass(cls, blankIMP);
505515
CDSemanticString *semanticString = [model semanticLinesWithOptions:generationOptions];
506516
NSString *lines = linesForSemanticStringColorMode(semanticString, outputColorMode, NO);
507-
NSString *headerName = [NSStringFromClass(cls) stringByAppendingPathExtension:@"h"];
517+
NSString *headerName = [nsClassName stringByAppendingPathExtension:@"h"];
508518

509519
NSString *headerPath = [outputDir stringByAppendingPathComponent:headerName];
510520

@@ -668,7 +678,17 @@ int main(int argc, char *argv[]) {
668678
unsigned int classCount = 0;
669679
const char **classNames = objc_copyClassNamesForImage(imagePath.fileSystemRepresentation, &classCount);
670680
for (unsigned int classIndex = 0; classIndex < classCount; classIndex++) {
671-
Class const cls = objc_getClass(classNames[classIndex]);
681+
const char *const className = classNames[classIndex];
682+
// this is the same method `NSStringFromClass` uses
683+
NSString *const nsClassName = [[NSString alloc] initWithCString:className encoding:NSUTF8StringEncoding];
684+
if (nsClassName == nil) {
685+
// these contain byte sequences that don't map to characters.
686+
// NSString doesn't seem to want to represent these sequences.
687+
// Since the header contents is broken anyway in this case, skip for now.
688+
NSLog(@"Skipping class with unsupported name: '%s'", className);
689+
continue;
690+
}
691+
Class const cls = objc_getClass(className);
672692
// creating the model and generating the "lines" both use
673693
// functions that grab the objc runtime lock, so putting either of
674694
// these on another thread is not efficient, as they would just be blocked
@@ -679,7 +699,7 @@ int main(int argc, char *argv[]) {
679699
CDSemanticString *semanticString = [model semanticLinesWithOptions:generationOptions];
680700

681701
NSString *lines = linesForSemanticStringColorMode(semanticString, outputColorMode, NO);
682-
NSString *headerName = [NSStringFromClass(cls) stringByAppendingPathExtension:@"h"];
702+
NSString *headerName = [nsClassName stringByAppendingPathExtension:@"h"];
683703

684704
dispatch_group_async(linesWriteGroup, linesWriteQueue, ^{
685705
NSString *headerPath = [topDir stringByAppendingPathComponent:headerName];

0 commit comments

Comments
 (0)