Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit fe0bcec

Browse files
appleguyAdlai Holler
authored andcommitted
[NSArray+Diffing] Use heap-based allocation for array diff. (#2926)
This avoids compiler warnings when using the strictest clang settings. It also ensures that stack overflow can't occur even with the largest datasets.
1 parent 7205ea0 commit fe0bcec

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

AsyncDisplayKit/Details/NSArray+Diffing.m

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,19 @@ - (NSIndexSet *)_asdk_commonIndexesWithArray:(NSArray *)array compareBlock:(BOOL
6060
NSInteger arrayCount = array.count;
6161

6262
// Allocate the diff map in the heap so we don't blow the stack for large arrays.
63-
NSInteger (*lengths)[arrayCount+1] = NULL;
64-
size_t lengthsSize = ((selfCount+1) * sizeof(*lengths));
65-
// Would rather use initWithCapacity: to skip the zeroing, but TECHNICALLY
66-
// `mutableBytes` is only guaranteed to be non-NULL if the data object has a non-zero length.
67-
NS_VALID_UNTIL_END_OF_SCOPE NSMutableData *lengthsData = [[NSMutableData alloc] initWithLength:lengthsSize];
68-
lengths = lengthsData.mutableBytes;
63+
NSInteger **lengths = NULL;
64+
lengths = (NSInteger **)malloc(sizeof(NSInteger*) * (selfCount+1));
6965
if (lengths == NULL) {
70-
ASDisplayNodeFailAssert(@"Failed to allocate memory for diffing with size %tu", lengthsSize);
66+
ASDisplayNodeFailAssert(@"Failed to allocate memory for diffing");
7167
return nil;
7268
}
7369

7470
for (NSInteger i = 0; i <= selfCount; i++) {
71+
lengths[i] = (NSInteger *)malloc(sizeof(NSInteger) * (arrayCount+1));
72+
if (lengths[i] == NULL) {
73+
ASDisplayNodeFailAssert(@"Failed to allocate memory for diffing");
74+
return nil;
75+
}
7576
id selfObj = i > 0 ? self[i-1] : nil;
7677
for (NSInteger j = 0; j <= arrayCount; j++) {
7778
if (i == 0 || j == 0) {
@@ -96,7 +97,11 @@ - (NSIndexSet *)_asdk_commonIndexesWithArray:(NSArray *)array compareBlock:(BOOL
9697
j--;
9798
}
9899
}
99-
100+
101+
for (NSInteger i = 0; i <= selfCount; i++) {
102+
free(lengths[i]);
103+
}
104+
free(lengths);
100105
return common;
101106
}
102107

0 commit comments

Comments
 (0)