From 71aed89574b69d823ea04c0ecb7f3ec6377417a1 Mon Sep 17 00:00:00 2001 From: iska Date: Sat, 25 Apr 2015 13:21:40 +0200 Subject: [PATCH] Fix validation for inserting a Document Fragment into a Document --- HTMLKit/HTMLNode.m | 12 +++++------ HTMLKitTests/HTMLKitNodesTests.m | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/HTMLKit/HTMLNode.m b/HTMLKit/HTMLNode.m index be7a196..f2751e9 100644 --- a/HTMLKit/HTMLNode.m +++ b/HTMLKit/HTMLNode.m @@ -319,18 +319,18 @@ NS_INLINE void CheckInvalidCombination(HTMLNode *parent, HTMLNode *node, NSStrin void (^ hierarchyError)() = ^{ [NSException raise:HTMLKitHierarchyRequestError - format:@"%@: Hierarchy Request Error. The operation would yield an incorrect node tree.", - NSStringFromSelector(_cmd)]; + format:@"%@: Hierarchy Request Error, inserting (%@) into (%@). The operation would yield an incorrect node tree.", + NSStringFromSelector(_cmd), self, node]; }; if (self.type == HTMLNodeDocument) { switch (node.type) { case HTMLNodeDocumentFragment: - if (self.childNodesCount > 1 || - [self hasChildNodeOfType:HTMLNodeText]) { + if (node.childNodesCount > 1 || + [node hasChildNodeOfType:HTMLNodeText]) { hierarchyError(); - } else if (self.childNodesCount == 1) { - if (self.hasChildNodes || + } else if (node.childNodesCount == 1) { + if ([self hasChildNodeOfType:HTMLNodeElement] || child.type == HTMLNodeDocumentType || child.nextSibling.type == HTMLNodeDocumentType) { hierarchyError(); diff --git a/HTMLKitTests/HTMLKitNodesTests.m b/HTMLKitTests/HTMLKitNodesTests.m index a38959d..9c2dccc 100644 --- a/HTMLKitTests/HTMLKitNodesTests.m +++ b/HTMLKitTests/HTMLKitNodesTests.m @@ -537,4 +537,41 @@ XCTAssertNoThrow([[HTMLTemplate new] appendNode:text]); } +- (void)testValidDocumentFragmentInsertionIntoDocument +{ + HTMLDocument *document = [HTMLDocument new]; + HTMLDocumentFragment *fragment = [[HTMLDocumentFragment alloc] initWithDocument:document]; + + void (^ reset)() = ^ { + [fragment removeAllChildNodes]; + [document removeAllChildNodes]; + }; + + [fragment appendNode:[HTMLText new]]; + XCTAssertThrows([document appendNode:fragment]); + + reset(); + [fragment appendNode:[HTMLElement new]]; + [fragment appendNode:[HTMLElement new]]; + XCTAssertThrows([document appendNode:fragment]); + + reset(); + [fragment appendNode:[HTMLElement new]]; + [document appendNode:[HTMLElement new]]; + XCTAssertThrows([document appendNode:fragment]); + + reset(); + HTMLDocumentType *doctype = [HTMLDocumentType new]; + [fragment appendNode:[HTMLElement new]]; + [document appendNode:doctype]; + XCTAssertThrows([document insertNode:fragment beforeChildNode:doctype]); + + reset(); + HTMLComment *doctypePreviousSibling = [HTMLComment new]; + [fragment appendNode:[HTMLElement new]]; + [document appendNode:doctypePreviousSibling]; + [document appendNode:doctype]; + XCTAssertThrows([document insertNode:fragment beforeChildNode:doctypePreviousSibling]); +} + @end