diff --git a/Sources/HTMLParser.m b/Sources/HTMLParser.m index aa13ecf..3652149 100644 --- a/Sources/HTMLParser.m +++ b/Sources/HTMLParser.m @@ -1559,7 +1559,17 @@ - (void)inTableBodyInsertionModeHandleStartTagToken:(HTMLStartTagToken *)token [self switchInsertionMode:HTMLInRowInsertionMode]; [self reprocessToken:token]; } else if (StringIsEqualToAnyOf(token.tagName, @"caption", @"col", @"colgroup", @"tbody", @"tfoot", @"thead")) { - [self inTableBodyInsertionModeHandleTableCaptionStartTagOrTableEndTagToken:token]; + if (![self elementInTableScopeWithTagNameInArray:@[ @"tbody", @"thead", @"tfoot" ] namespace:HTMLNamespaceHTML]) { + [self addParseError:@"Start tag '%@' when none of , , in table scope; ignoring", token.tagName]; + return; + } + + [self clearStackBackToATableBodyContext]; + + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInTableInsertionMode]; + + [self reprocessToken:token]; } else { [self inTableBodyInsertionModeHandleAnythingElse:token]; } @@ -1576,7 +1586,17 @@ - (void)inTableBodyInsertionModeHandleEndTagToken:(HTMLEndTagToken *)token [_stackOfOpenElements removeLastObject]; [self switchInsertionMode:HTMLInTableInsertionMode]; } else if ([token.tagName isEqualToString:@"table"]) { - [self inTableBodyInsertionModeHandleTableCaptionStartTagOrTableEndTagToken:token]; + if (![self elementInTableScopeWithTagNameInArray:@[ @"tbody", @"thead", @"tfoot" ] namespace:HTMLNamespaceHTML]) { + [self addParseError:@"End tag 'table' when none of , , in table scope; ignoring"]; + return; + } + + [self clearStackBackToATableBodyContext]; + + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInTableInsertionMode]; + + [self reprocessToken:token]; } else if (StringIsEqualToAnyOf(token.tagName, @"body", @"caption", @"col", @"colgroup", @"html", @"td", @"th", @"tr")) { [self addParseError:@"End tag '%@' in body", token.tagName]; } else { @@ -1615,11 +1635,22 @@ - (void)inRowInsertionModeHandleStartTagToken:(HTMLStartTagToken *)token { if (StringIsEqualToAnyOf(token.tagName, @"th", @"td")) { [self clearStackBackToATableRowContext]; + [self insertElementForToken:token]; [self switchInsertionMode:HTMLInCellInsertionMode]; + [self pushMarkerOnToListOfActiveFormattingElements]; } else if (StringIsEqualToAnyOf(token.tagName, @"caption", @"col", @"colgroup", @"tbody", @"tfoot", @"thead", @"tr")) { - [self inRowInsertionModeHandleTableCaptionStartTagOrTableEndTagToken:token]; + if (![self elementInTableScopeWithTagName:@"tr" namespace:HTMLNamespaceHTML]) { + [self addParseError:@"Start tag '%@' without in table scope; ignoring", token.tagName]; + return; + } + + [self clearStackBackToATableRowContext]; + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInTableBodyInsertionMode]; + + [self reprocessToken:token]; } else { [self inRowInsertionModeHandleAnythingElse:token]; } @@ -1628,15 +1659,27 @@ - (void)inRowInsertionModeHandleStartTagToken:(HTMLStartTagToken *)token - (void)inRowInsertionModeHandleEndTagToken:(HTMLEndTagToken *)token { if ([token.tagName isEqualToString:@"tr"]) { - if (![self elementInTableScopeWithTagName:@"tr"]) { + if (![self elementInTableScopeWithTagName:@"tr" namespace:HTMLNamespaceHTML]) { [self addParseError:@"End tag 'tr' for unknown element in "]; return; } + [self clearStackBackToATableRowContext]; + [_stackOfOpenElements removeLastObject]; [self switchInsertionMode:HTMLInTableBodyInsertionMode]; } else if ([token.tagName isEqualToString:@"table"]) { - [self inRowInsertionModeHandleTableCaptionStartTagOrTableEndTagToken:token]; + if (![self elementInTableScopeWithTagName:@"tr" namespace:HTMLNamespaceHTML]) { + [self addParseError:@"End tag 'table' without in table scope; ignoring"]; + return; + } + + [self clearStackBackToATableRowContext]; + + [_stackOfOpenElements removeLastObject]; + [self switchInsertionMode:HTMLInTableBodyInsertionMode]; + + [self reprocessToken:token]; } else if (StringIsEqualToAnyOf(token.tagName, @"tbody", @"tfoot", @"thead")) { if (![self elementInTableScopeWithTagName:token.tagName]) { [self addParseError:@"End tag '%@' for unknown element in ", token.tagName];