From f88f41cf1eba90aa3208d0cbe89a23e0fde9fbaa Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:01:36 +1100 Subject: [PATCH] LibWeb: Reject invalid processing instructions --- ...ment-createProcessingInstruction-xhtml.txt | 22 +++++++++++ .../Document-createProcessingInstruction.txt | 22 +++++++++++ ...nt-createProcessingInstruction-xhtml.xhtml | 15 +++++++ .../Document-createProcessingInstruction.html | 11 ++++++ .../Document-createProcessingInstruction.js | 39 +++++++++++++++++++ Userland/Libraries/LibWeb/DOM/Document.cpp | 8 +++- 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml create mode 100644 Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction.js diff --git a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.txt b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.txt new file mode 100644 index 00000000000..5c18a38fa32 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.txt @@ -0,0 +1,22 @@ +Summary + +Harness status: OK + +Rerun + +Found 12 tests + +12 Pass +Details +Result Test Name MessagePass Document.createProcessingInstruction in XML documents +Pass Should throw an INVALID_CHARACTER_ERR for target "A" and data "?>". +Pass Should throw an INVALID_CHARACTER_ERR for target "·A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "×A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "A×" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "\\A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "\f" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target 0 and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "0" and data "x". +Pass Should get a ProcessingInstruction for target "xml:fail" and data "x". +Pass Should get a ProcessingInstruction for target "A·A" and data "x". +Pass Should get a ProcessingInstruction for target "a0" and data "x". \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction.txt b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction.txt new file mode 100644 index 00000000000..257ee6d1929 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Document-createProcessingInstruction.txt @@ -0,0 +1,22 @@ +Summary + +Harness status: OK + +Rerun + +Found 12 tests + +12 Pass +Details +Result Test Name MessagePass Document.createProcessingInstruction in HTML documents +Pass Should throw an INVALID_CHARACTER_ERR for target "A" and data "?>". +Pass Should throw an INVALID_CHARACTER_ERR for target "·A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "×A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "A×" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "\\A" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "\f" and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target 0 and data "x". +Pass Should throw an INVALID_CHARACTER_ERR for target "0" and data "x". +Pass Should get a ProcessingInstruction for target "xml:fail" and data "x". +Pass Should get a ProcessingInstruction for target "A·A" and data "x". +Pass Should get a ProcessingInstruction for target "a0" and data "x". \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml new file mode 100644 index 00000000000..287be72601d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml @@ -0,0 +1,15 @@ + + +Document.createProcessingInstruction in XML documents + + + + + + + + +
+ + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction.js b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction.js new file mode 100644 index 00000000000..d6cc3725f03 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Document-createProcessingInstruction.js @@ -0,0 +1,39 @@ +test(function() { + var invalid = [ + ["A", "?>"], + ["\u00B7A", "x"], + ["\u00D7A", "x"], + ["A\u00D7", "x"], + ["\\A", "x"], + ["\f", "x"], + [0, "x"], + ["0", "x"] + ], + valid = [ + ["xml:fail", "x"], + ["A\u00B7A", "x"], + ["a0", "x"] + ] + + for (var i = 0, il = invalid.length; i < il; i++) { + test(function() { + assert_throws_dom("INVALID_CHARACTER_ERR", function() { + document.createProcessingInstruction(invalid[i][0], invalid[i][1]) + }) + }, "Should throw an INVALID_CHARACTER_ERR for target " + + format_value(invalid[i][0]) + " and data " + + format_value(invalid[i][1]) + ".") + } + for (var i = 0, il = valid.length; i < il; ++i) { + test(function() { + var pi = document.createProcessingInstruction(valid[i][0], valid[i][1]); + assert_equals(pi.target, valid[i][0]); + assert_equals(pi.data, valid[i][1]); + assert_equals(pi.ownerDocument, document); + assert_true(pi instanceof ProcessingInstruction); + assert_true(pi instanceof Node); + }, "Should get a ProcessingInstruction for target " + + format_value(valid[i][0]) + " and data " + + format_value(valid[i][1]) + ".") + } +}) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index b0749e76c9e..d7bbc97bb46 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1740,9 +1740,13 @@ JS::NonnullGCPtr Document::create_comment(String const& data) // https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction WebIDL::ExceptionOr> Document::create_processing_instruction(String const& target, String const& data) { - // FIXME: 1. If target does not match the Name production, then throw an "InvalidCharacterError" DOMException. + // 1. If target does not match the Name production, then throw an "InvalidCharacterError" DOMException. + if (!is_valid_name(target)) + return WebIDL::InvalidCharacterError::create(realm(), "Invalid character in target name."_string); - // FIXME: 2. If data contains the string "?>", then throw an "InvalidCharacterError" DOMException. + // 2. If data contains the string "?>", then throw an "InvalidCharacterError" DOMException. + if (data.contains("?>"sv)) + return WebIDL::InvalidCharacterError::create(realm(), "String may not contain '?>'"_string); // 3. Return a new ProcessingInstruction node, with target set to target, data set to data, and node document set to this. return heap().allocate(realm(), *this, data, target);