From a2c5bbfb20280698006470ceb2eda0c60e15708a Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Mon, 14 Dec 2015 18:36:20 +0900 Subject: [PATCH 01/18] Conform ampersand-error reporting to HTML spec --- .../validator/htmlparser/impl/Tokenizer.java | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/nu/validator/htmlparser/impl/Tokenizer.java b/src/nu/validator/htmlparser/impl/Tokenizer.java index 318df252..6a90a8df 100755 --- a/src/nu/validator/htmlparser/impl/Tokenizer.java +++ b/src/nu/validator/htmlparser/impl/Tokenizer.java @@ -220,6 +220,8 @@ public class Tokenizer implements Locator { public static final int PROCESSING_INSTRUCTION_QUESTION_MARK = 74; + public static final int AMBIGUOUS_AMPERSAND = 75; + /** * Magic value for UTF-16 operations. */ @@ -3106,6 +3108,7 @@ private void ensureBufferSpace(int inputLength) throws SAXException { case '<': case '&': case '\u0000': + case ';': emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) { cstart = pos; @@ -3134,17 +3137,12 @@ private void ensureBufferSpace(int inputLength) throws SAXException { firstCharKey = c - 'A'; } else { // No match - /* - * If no match can be made, then this is a parse - * error. - */ - errNoNamedCharacterMatch(); emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) { cstart = pos; } reconsume = true; - state = transition(state, returnState, reconsume, pos); + state = transition(state, Tokenizer.AMBIGUOUS_AMPERSAND, reconsume, pos); continue stateloop; } // Didn't fail yet @@ -3205,17 +3203,12 @@ private void ensureBufferSpace(int inputLength) throws SAXException { } } if (hilo == 0) { - /* - * If no match can be made, then this is a parse - * error. - */ - errNoNamedCharacterMatch(); emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) { cstart = pos; } reconsume = true; - state = transition(state, returnState, reconsume, pos); + state = transition(state, Tokenizer.AMBIGUOUS_AMPERSAND, reconsume, pos); continue stateloop; } // Didn't fail yet @@ -3298,16 +3291,12 @@ private void ensureBufferSpace(int inputLength) throws SAXException { if (candidate == -1) { // reconsume deals with CR, LF or nul - /* - * If no match can be made, then this is a parse error. - */ - errNoNamedCharacterMatch(); emitOrAppendCharRefBuf(returnState); if ((returnState & DATA_AND_RCDATA_MASK) == 0) { cstart = pos; } reconsume = true; - state = transition(state, returnState, reconsume, pos); + state = transition(state, Tokenizer.AMBIGUOUS_AMPERSAND, reconsume, pos); continue stateloop; } else { // c can't be CR, LF or nul if we got here @@ -3345,10 +3334,9 @@ private void ensureBufferSpace(int inputLength) throws SAXException { * after the U+0026 AMPERSAND (&) must be * unconsumed, and nothing is returned. */ - errNoNamedCharacterMatch(); appendCharRefBufToStrBuf(); reconsume = true; - state = transition(state, returnState, reconsume, pos); + state = transition(state, Tokenizer.AMBIGUOUS_AMPERSAND, reconsume, pos); continue stateloop; } } @@ -3411,6 +3399,28 @@ private void ensureBufferSpace(int inputLength) throws SAXException { * I'm ∉ I tell you. */ } + // XXX reorder point + case AMBIGUOUS_AMPERSAND: + ampersandloop: for (;;) { + if (reconsume) { + if (++pos == endPos) { + break stateloop; + } + pos--; + c = checkChar(buf, pos); + } + if (c == ';') { + errNoNamedCharacterMatch(); + } else if ((c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z')) { + appendStrBuf(c); + pos++; + continue; + } + state = transition(state, returnState, reconsume, pos); + continue stateloop; + } case CONSUME_NCR: if (++pos == endPos) { break stateloop; @@ -6501,7 +6511,6 @@ public void eof() throws SAXException { state = returnState; continue; case CHARACTER_REFERENCE_HILO_LOOKUP: - errNoNamedCharacterMatch(); emitOrAppendCharRefBuf(returnState); state = returnState; continue; @@ -6555,10 +6564,6 @@ public void eof() throws SAXException { } if (candidate == -1) { - /* - * If no match can be made, then this is a parse error. - */ - errNoNamedCharacterMatch(); emitOrAppendCharRefBuf(returnState); state = returnState; continue eofloop; @@ -6596,7 +6601,6 @@ public void eof() throws SAXException { * after the U+0026 AMPERSAND (&) must be * unconsumed, and nothing is returned. */ - errNoNamedCharacterMatch(); appendCharRefBufToStrBuf(); state = returnState; continue eofloop; From 2b06e4df9d7480339918468758734cfceb425a60 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Mon, 10 Nov 2014 16:15:26 +0900 Subject: [PATCH 02/18] Fix grammar problem in HTML parser error message --- src/nu/validator/htmlparser/impl/TreeBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nu/validator/htmlparser/impl/TreeBuilder.java b/src/nu/validator/htmlparser/impl/TreeBuilder.java index a81f144a..b6be15ff 100644 --- a/src/nu/validator/htmlparser/impl/TreeBuilder.java +++ b/src/nu/validator/htmlparser/impl/TreeBuilder.java @@ -6621,7 +6621,7 @@ private void errFooSeenWhenFooOpen(@Local String name) throws SAXException { if (errorHandler == null) { return; } - errNoCheck("An \u201C" + name + "\u201D start tag seen but an element of the same type was already open."); + errNoCheck("Start tag \u201C" + name + "\u201D seen but an element of the same type was already open."); } private void errHeadingWhenHeadingOpen() throws SAXException { From 8bd0b78468416171a5772118716e8d852c1b8712 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Mon, 14 Dec 2015 19:06:01 +0900 Subject: [PATCH 03/18] Fix "non-space characters insided a table" typo --- src/nu/validator/htmlparser/impl/TreeBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nu/validator/htmlparser/impl/TreeBuilder.java b/src/nu/validator/htmlparser/impl/TreeBuilder.java index b6be15ff..de3edfeb 100644 --- a/src/nu/validator/htmlparser/impl/TreeBuilder.java +++ b/src/nu/validator/htmlparser/impl/TreeBuilder.java @@ -6712,7 +6712,7 @@ private void errNoTableRowToClose() throws SAXException { } private void errNonSpaceInTable() throws SAXException { - err("Misplaced non-space characters insided a table."); + err("Misplaced non-space characters inside a table."); } private void errUnclosedChildrenInRuby() throws SAXException { From 8fac68b4f429c99d6a1f05ede3819b6fd8bf44ee Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Sat, 30 Jan 2016 20:19:10 +0900 Subject: [PATCH 04/18] Report 1024 as byte limit for meta charset sniff Fixes https://github.com/validator/validator/issues/232 --- src/nu/validator/htmlparser/impl/Tokenizer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nu/validator/htmlparser/impl/Tokenizer.java b/src/nu/validator/htmlparser/impl/Tokenizer.java index 6a90a8df..95068875 100755 --- a/src/nu/validator/htmlparser/impl/Tokenizer.java +++ b/src/nu/validator/htmlparser/impl/Tokenizer.java @@ -1289,7 +1289,7 @@ private void addAttributeWithoutValue() throws SAXException { // [NOCPP[ if (metaBoundaryPassed && AttributeName.CHARSET == attributeName && ElementName.META == tagName) { - err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes."); + err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 1024 bytes."); } // ]NOCPP] if (attributeName != null) { @@ -1337,7 +1337,7 @@ private void addAttributeWithValue() throws SAXException { // [NOCPP[ if (metaBoundaryPassed && ElementName.META == tagName && AttributeName.CHARSET == attributeName) { - err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes."); + err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 1024 bytes."); } // ]NOCPP] if (attributeName != null) { From 20eaf92512f66ae83f678e3c0bee1f0d407cfab0 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Fri, 10 Jun 2016 21:39:28 +0900 Subject: [PATCH 05/18] Make consecutive hyphens in comments a non-error Also allow `` at (IE conditional) comment end See https://github.com/whatwg/html/pull/1356 See https://github.com/whatwg/html/pull/1456 --- .../impl/ErrorReportingTokenizer.java | 10 +- .../validator/htmlparser/impl/Tokenizer.java | 199 ++++++++++++++++-- 2 files changed, 190 insertions(+), 19 deletions(-) diff --git a/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java b/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java index 9db9e8a7..7494fb28 100644 --- a/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java +++ b/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013 Mozilla Foundation + * Copyright (c) 2009-2017 Mozilla Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -413,8 +413,8 @@ private boolean isAstralPrivateUse(int c) { err("Nameless doctype."); } - @Override protected void errConsecutiveHyphens() throws SAXException { - err("Consecutive hyphens did not terminate a comment. \u201C--\u201D is not permitted inside a comment, but e.g. \u201C- -\u201D is."); + @Override protected void errNestedComment() throws SAXException { + err("Saw \u201C