Closed dsanghan closed 5 years ago
@dsanghan Hey there, could you provide a HTML snippet/document, that causes this?
@iabudiab: The attached html file will work on the main thread, but async thread's have a recursion depth of 1000 and the attached html has 2066 nodes by depth - which is what causes the crash.
@iabudiab: To repro:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSString *path = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"txt"];
NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:0 error:nil];
HTMLDocument *document = [HTMLDocument documentWithString:html];
HTMLNode *node = document.body.childNodes[1];
NSMutableArray *stack = [[NSMutableArray alloc] init];
while (node) {
if ([node childNodesCount] > 2) {
node = [node childNodeAtIndex:2];
[stack safeAddObject:node];
} else {
node = nil;
}
}
NSLog(@"Stack depth: %lu", stack.count);
html = document.rootElement.outerHTML;
});
@iabudiab Temporary workaround:
diff --git a/Canary/Pods/HTMLKit/Sources/HTMLNode.m b/Canary/Pods/HTMLKit/Sources/HTMLNode.m
index d948ff9fc..c90d2bc76 100644
--- a/Canary/Pods/HTMLKit/Sources/HTMLNode.m
+++ b/Canary/Pods/HTMLKit/Sources/HTMLNode.m
@@ -139,6 +139,10 @@ - (NSUInteger)index
return [_parentNode indexOfChildNode:self];
}
+- (NSUInteger)level {
+ return _parentNode.level + 1;
+}
+
- (NSString *)textContent
{
return nil;
@@ -264,6 +268,10 @@ - (HTMLNode *)insertNode:(HTMLNode *)node beforeChildNode:(HTMLNode *)child
#ifndef HTMLKIT_NO_DOM_CHECKS
[self ensurePreInsertionValidityOfNode:node beforeChildNode:child];
#endif
+
+ if (self.level >= 400) {
+ return nil;
+ }
[self.ownerDocument adoptNode:node];
@dsanghan Hey there, thanks for the sample file and the workarounds 👍 . The fix, that I've already started, should fix the underlying issue fundamentally, i.e. should work for any depth. I hope I'll have a fix and a release sometime next week.
@dsanghan Hey there, I've just pushed a new implementation for HTML serialization, which does not use recursion => should work for any DOM depth, even async on iOS.
You can check it out on this commit: 98f7c8304fbf6ed92fa1a2556e6164ba5a5468b5
I'll release a new version after I've written some tests to ensure correct behaviour.
@iabudiab Thanks a lot!
Example Stacktrace:
Maybe put in a check for that? Not sure how to reproduce but seeing this out in the wild.