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];