From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- parser/htmlparser/CNavDTD.cpp | 44 + parser/htmlparser/CNavDTD.h | 32 + parser/htmlparser/CParserContext.cpp | 60 + parser/htmlparser/CParserContext.h | 60 + parser/htmlparser/moz.build | 52 + parser/htmlparser/nsElementTable.cpp | 206 ++ parser/htmlparser/nsElementTable.h | 21 + parser/htmlparser/nsExpatDriver.cpp | 1747 ++++++++++++++ parser/htmlparser/nsExpatDriver.h | 256 +++ parser/htmlparser/nsHTMLTagList.h | 204 ++ parser/htmlparser/nsHTMLTags.cpp | 167 ++ parser/htmlparser/nsHTMLTags.h | 81 + parser/htmlparser/nsIContentSink.h | 143 ++ parser/htmlparser/nsIDTD.h | 88 + parser/htmlparser/nsIExpatSink.idl | 112 + parser/htmlparser/nsIFragmentContentSink.h | 85 + parser/htmlparser/nsIHTMLContentSink.h | 96 + parser/htmlparser/nsIParser.h | 186 ++ parser/htmlparser/nsParser.cpp | 1075 +++++++++ parser/htmlparser/nsParser.h | 312 +++ parser/htmlparser/nsParserBase.h | 16 + parser/htmlparser/nsParserConstants.h | 22 + parser/htmlparser/nsParserMsgUtils.cpp | 62 + parser/htmlparser/nsParserMsgUtils.h | 28 + parser/htmlparser/nsRLBoxExpatDriver.h | 27 + parser/htmlparser/nsScanner.cpp | 331 +++ parser/htmlparser/nsScanner.h | 188 ++ parser/htmlparser/nsScannerString.cpp | 379 ++++ parser/htmlparser/nsScannerString.h | 459 ++++ parser/htmlparser/tests/crashtests/121591-1.html | 22 + parser/htmlparser/tests/crashtests/1373045-1.html | 1 + parser/htmlparser/tests/crashtests/147179-1.html | 7 + parser/htmlparser/tests/crashtests/151956-1.html | 18 + parser/htmlparser/tests/crashtests/152444-1.html | 15 + parser/htmlparser/tests/crashtests/1534346-1.html | 1 + parser/htmlparser/tests/crashtests/1547895-1.html | 10 + parser/htmlparser/tests/crashtests/1604307-1.html | 10 + parser/htmlparser/tests/crashtests/1606499-1.html | 15 + parser/htmlparser/tests/crashtests/1747514.html | 13 + parser/htmlparser/tests/crashtests/1810896-1.html | 1081 +++++++++ parser/htmlparser/tests/crashtests/185073-1.html | 15 + parser/htmlparser/tests/crashtests/1854907-1.html | 225 ++ parser/htmlparser/tests/crashtests/188474-1.html | 13 + parser/htmlparser/tests/crashtests/194329-1.html | 15 + parser/htmlparser/tests/crashtests/197052-1.html | 1 + parser/htmlparser/tests/crashtests/220542-1.html | 2 + parser/htmlparser/tests/crashtests/253979-1.html | 4 + parser/htmlparser/tests/crashtests/269095-1.html | 1 + parser/htmlparser/tests/crashtests/286733-1.html | 4 + parser/htmlparser/tests/crashtests/286733-2.html | 4 + parser/htmlparser/tests/crashtests/299036-1.html | 2 + parser/htmlparser/tests/crashtests/30885-1.html | 17 + parser/htmlparser/tests/crashtests/30956-1.html | 10 + parser/htmlparser/tests/crashtests/31392-1.html | 15 + parser/htmlparser/tests/crashtests/31694-1.html | 8 + parser/htmlparser/tests/crashtests/31940-1.html | 15 + parser/htmlparser/tests/crashtests/32613-1.html | 18 + parser/htmlparser/tests/crashtests/328751-1.html | 9 + parser/htmlparser/tests/crashtests/34168-1.html | 1 + parser/htmlparser/tests/crashtests/34168-1.xml | 6 + parser/htmlparser/tests/crashtests/408939-1.html | 139 ++ parser/htmlparser/tests/crashtests/41427-1.html | 1 + parser/htmlparser/tests/crashtests/423373-1.html | 1 + parser/htmlparser/tests/crashtests/44178-1.html | 8 + .../htmlparser/tests/crashtests/445171-1-inner.svg | 5 + parser/htmlparser/tests/crashtests/445171-1.html | 9 + parser/htmlparser/tests/crashtests/46495-1.html | 5 + parser/htmlparser/tests/crashtests/468538-1.xhtml | 15 + parser/htmlparser/tests/crashtests/50134-1.html | 8 + parser/htmlparser/tests/crashtests/502103.html | 1 + .../htmlparser/tests/crashtests/502869-iframe.html | 9 + parser/htmlparser/tests/crashtests/502869.html | 18 + parser/htmlparser/tests/crashtests/50994-1.html | 12 + parser/htmlparser/tests/crashtests/515278-1.html | 3 + .../tests/crashtests/515533-1-inner.html | 12 + parser/htmlparser/tests/crashtests/515533-1.html | 1 + parser/htmlparser/tests/crashtests/515816-1.html | 11 + parser/htmlparser/tests/crashtests/522326-1.html | 1 + parser/htmlparser/tests/crashtests/525229-1.html | 7 + parser/htmlparser/tests/crashtests/536097-1.html | 1 + .../htmlparser/tests/crashtests/555462-iframe.html | 3 + parser/htmlparser/tests/crashtests/555462.html | 21 + parser/htmlparser/tests/crashtests/563514-1.html | 10 + parser/htmlparser/tests/crashtests/574884-1.html | 1 + parser/htmlparser/tests/crashtests/574884-2.html | 1 + parser/htmlparser/tests/crashtests/58455-1.html | 15 + parser/htmlparser/tests/crashtests/591330-1.html | 284 +++ parser/htmlparser/tests/crashtests/60110-1.html | 22 + parser/htmlparser/tests/crashtests/616027-1.html | 15 + parser/htmlparser/tests/crashtests/650501-1.xhtml | 22 + parser/htmlparser/tests/crashtests/662185-1.html | 1 + parser/htmlparser/tests/crashtests/696651-1.html | 11 + parser/htmlparser/tests/crashtests/699347-1.xml | 1 + parser/htmlparser/tests/crashtests/721313-1.html | 2 + parser/htmlparser/tests/crashtests/73331-1.html | 27 + parser/htmlparser/tests/crashtests/742414-1.html | 4 + parser/htmlparser/tests/crashtests/762726-1.html | 1 + parser/htmlparser/tests/crashtests/92647-1.html | 33 + parser/htmlparser/tests/crashtests/92788-1.html | 20 + parser/htmlparser/tests/crashtests/981279-1.html | 15 + parser/htmlparser/tests/crashtests/982285-1.html | 19 + parser/htmlparser/tests/crashtests/crashtests.list | 68 + .../htmlparser/tests/crashtests/file_445171-1.html | 1 + parser/htmlparser/tests/mochitest/blue.png | Bin 0 -> 2745 bytes parser/htmlparser/tests/mochitest/broken_xml.xhtml | 7 + parser/htmlparser/tests/mochitest/browser.toml | 15 + .../tests/mochitest/browser_elementindtd.dtd | 2 + .../tests/mochitest/browser_elementindtd.js | 31 + .../tests/mochitest/browser_elementindtd.xml | 8 + .../tests/mochitest/browser_viewsource.js | 28 + .../tests/mochitest/browser_ysod_telemetry.js | 49 + .../tests/mochitest/bug_502091_iframe.html | 17 + .../mochitest/dir_bug534293/file_bug534293.sjs | 13 + .../tests/mochitest/file_async_bug1104732.sjs | 17 + .../tests/mochitest/file_base_csp_img.sjs | 18 + .../htmlparser/tests/mochitest/file_bug102699.sjs | 19 + .../tests/mochitest/file_bug534293-slow.sjs | 16 + .../htmlparser/tests/mochitest/file_bug534293.sjs | 17 + .../htmlparser/tests/mochitest/file_bug543062.sjs | 38 + .../tests/mochitest/file_bug568470-script.sjs | 17 + .../htmlparser/tests/mochitest/file_bug568470.sjs | 22 + .../tests/mochitest/file_bug594730-1.html | 3 + .../tests/mochitest/file_bug594730-2.html | 3 + .../tests/mochitest/file_bug594730-3.html | 3 + .../tests/mochitest/file_bug594730-4.html | 3 + .../tests/mochitest/file_bug594730-5.html | 3 + .../tests/mochitest/file_bug594730-6.html | 3 + .../tests/mochitest/file_bug594730-7.html | 3 + .../tests/mochitest/file_bug594730-8.html | 3 + .../tests/mochitest/file_bug594730-9.html | 5 + .../htmlparser/tests/mochitest/file_bug642908.sjs | 19 + .../htmlparser/tests/mochitest/file_bug655682.sjs | 31 + .../tests/mochitest/file_bug672453_enc_error.html | 10 + .../file_bug672453_enc_error_inherited.html | 9 + .../mochitest/file_bug672453_http_replacement.html | 1 + .../file_bug672453_http_replacement.html^headers^ | 2 + .../mochitest/file_bug672453_http_unsupported.html | 1 + .../file_bug672453_http_unsupported.html^headers^ | 2 + .../tests/mochitest/file_bug672453_late_meta.html | 1028 +++++++++ .../mochitest/file_bug672453_meta_after_head.html | 10 + .../file_bug672453_meta_non_superset.html | 1 + .../mochitest/file_bug672453_meta_replacement.html | 10 + .../mochitest/file_bug672453_meta_restart.html | 1028 +++++++++ .../file_bug672453_meta_speculation_fail.html | 10 + .../mochitest/file_bug672453_meta_unsupported.html | 1 + .../mochitest/file_bug672453_meta_userdefined.html | 1 + .../tests/mochitest/file_bug672453_meta_utf16.html | 1 + .../mochitest/file_bug672453_not_declared.html | 1 + .../tests/mochitest/file_bug672453_xml_decl.html | 10 + .../file_bug672453_xml_speculation_fail.html | 10 + .../htmlparser/tests/mochitest/file_bug688580.js | 8 + .../tests/mochitest/file_bug716579-16.html | Bin 0 -> 82 bytes .../mochitest/file_bug716579-16.html^headers^ | 1 + .../tests/mochitest/file_bug716579-16.xhtml | Bin 0 -> 214 bytes .../mochitest/file_bug716579-16.xhtml^headers^ | 1 + .../tests/mochitest/file_bug716579-8.html | 3 + .../tests/mochitest/file_bug716579-8.html^headers^ | 1 + .../tests/mochitest/file_bug716579-8.xhtml | 7 + .../mochitest/file_bug716579-8.xhtml^headers^ | 1 + .../htmlparser/tests/mochitest/file_bug717180.html | 1 + .../tests/mochitest/file_defer_bug1104732.js | 7 + .../tests/mochitest/file_img_picture_preload.html | 167 ++ .../tests/mochitest/file_img_picture_preload.sjs | 27 + .../tests/mochitest/file_viewsource.html | 18 + .../tests/mochitest/file_xml_parse_error.js | 1 + .../tests/mochitest/file_xml_parse_error.xml | 3 + .../html5_tree_construction_exceptions.js | 11 + .../mochitest/html5lib_tree_construction/README.md | 104 + .../html5lib_tree_construction/adoption01.dat | 337 +++ .../html5lib_tree_construction/adoption02.dat | 99 + .../html5lib_tree_construction/comments01.dat | 206 ++ .../html5lib_tree_construction/doctype01.dat | 424 ++++ .../html5lib_tree_construction/domjs-unsafe.dat | Bin 0 -> 9884 bytes .../html5lib_tree_construction/entities01.dat | 792 +++++++ .../html5lib_tree_construction/entities02.dat | 283 +++ .../foreign-fragment.dat | 550 +++++ .../html5lib_license.txt | 21 + .../html5lib_upstream.txt | 11 + .../html5lib_tree_construction/html5test-com.dat | 291 +++ .../html5lib_tree_construction/inbody01.dat | 54 + .../html5lib_tree_construction/isindex.dat | 49 + .../html5lib_tree_construction/main-element.dat | 44 + .../pending-spec-changes-plain-text-unsafe.dat | Bin 0 -> 816 bytes .../pending-spec-changes.dat | 46 + .../plain-text-unsafe.dat | Bin 0 -> 7925 bytes .../mochitest/html5lib_tree_construction/ruby.dat | 298 +++ .../html5lib_tree_construction/scriptdata01.dat | 352 +++ .../scripted/adoption01.dat | 15 + .../html5lib_tree_construction/scripted/ark.dat | 26 + .../scripted/webkit01.dat | 28 + .../html5lib_tree_construction/tables01.dat | 286 +++ .../html5lib_tree_construction/template.dat | 1406 ++++++++++++ .../html5lib_tree_construction/tests1.dat | 1959 ++++++++++++++++ .../html5lib_tree_construction/tests10.dat | 847 +++++++ .../html5lib_tree_construction/tests11.dat | 482 ++++ .../html5lib_tree_construction/tests12.dat | 62 + .../html5lib_tree_construction/tests14.dat | 75 + .../html5lib_tree_construction/tests15.dat | 216 ++ .../html5lib_tree_construction/tests16.dat | 2396 ++++++++++++++++++++ .../html5lib_tree_construction/tests17.dat | 180 ++ .../html5lib_tree_construction/tests18.dat | 322 +++ .../html5lib_tree_construction/tests19.dat | 1454 ++++++++++++ .../html5lib_tree_construction/tests2.dat | 821 +++++++ .../html5lib_tree_construction/tests20.dat | 516 +++++ .../html5lib_tree_construction/tests21.dat | 305 +++ .../html5lib_tree_construction/tests22.dat | 190 ++ .../html5lib_tree_construction/tests23.dat | 168 ++ .../html5lib_tree_construction/tests24.dat | 79 + .../html5lib_tree_construction/tests25.dat | 220 ++ .../html5lib_tree_construction/tests26.dat | 411 ++++ .../html5lib_tree_construction/tests3.dat | 306 +++ .../html5lib_tree_construction/tests4.dat | 58 + .../html5lib_tree_construction/tests5.dat | 197 ++ .../html5lib_tree_construction/tests6.dat | 662 ++++++ .../html5lib_tree_construction/tests7.dat | 402 ++++ .../html5lib_tree_construction/tests8.dat | 149 ++ .../html5lib_tree_construction/tests9.dat | 473 ++++ .../tests_innerHTML_1.dat | 902 ++++++++ .../html5lib_tree_construction/tricky01.dat | 334 +++ .../html5lib_tree_construction/webkit01.dat | 705 ++++++ .../html5lib_tree_construction/webkit02.dat | 116 + parser/htmlparser/tests/mochitest/invalidchar.xml | 4 + parser/htmlparser/tests/mochitest/mochitest.toml | 237 ++ .../htmlparser/tests/mochitest/parser_datreader.js | 218 ++ .../tests/mochitest/parser_web_testrunner.js | 148 ++ .../tests/mochitest/test_base_csp_img.html | 35 + .../tests/mochitest/test_base_header_csp_img.html | 32 + .../test_base_header_csp_img.html^headers^ | 1 + .../htmlparser/tests/mochitest/test_bug102699.html | 75 + .../tests/mochitest/test_bug1104732.html | 59 + .../tests/mochitest/test_bug1209658.html | 35 + .../tests/mochitest/test_bug1364399.html | 43 + .../tests/mochitest/test_bug1646140-1.html | 20 + .../tests/mochitest/test_bug1646140-2.html | 28 + .../htmlparser/tests/mochitest/test_bug174351.html | 31 + .../htmlparser/tests/mochitest/test_bug213517.html | 30 + .../tests/mochitest/test_bug339350.xhtml | 60 + .../htmlparser/tests/mochitest/test_bug358797.html | 31 + .../htmlparser/tests/mochitest/test_bug396568.html | 48 + .../htmlparser/tests/mochitest/test_bug418464.html | 43 + .../tests/mochitest/test_bug460437.xhtml | 39 + .../htmlparser/tests/mochitest/test_bug502091.html | 37 + .../htmlparser/tests/mochitest/test_bug534293.html | 22 + .../htmlparser/tests/mochitest/test_bug543062.html | 26 + .../tests/mochitest/test_bug552938-2.html | 38 + .../htmlparser/tests/mochitest/test_bug552938.html | 33 + .../tests/mochitest/test_bug563322.xhtml | 33 + .../htmlparser/tests/mochitest/test_bug566879.html | 63 + .../htmlparser/tests/mochitest/test_bug568470.html | 51 + .../htmlparser/tests/mochitest/test_bug594730.html | 32 + .../htmlparser/tests/mochitest/test_bug613662.html | 132 ++ .../tests/mochitest/test_bug613662.xhtml | 137 ++ .../htmlparser/tests/mochitest/test_bug639362.html | 28 + .../htmlparser/tests/mochitest/test_bug642908.html | 32 + .../htmlparser/tests/mochitest/test_bug645115.html | 32 + .../htmlparser/tests/mochitest/test_bug655682.html | 80 + .../htmlparser/tests/mochitest/test_bug667533.html | 28 + .../htmlparser/tests/mochitest/test_bug672453.html | 131 ++ .../htmlparser/tests/mochitest/test_bug688580.html | 64 + .../tests/mochitest/test_bug688580.xhtml | 62 + .../htmlparser/tests/mochitest/test_bug709083.html | 30 + .../htmlparser/tests/mochitest/test_bug715112.html | 49 + .../htmlparser/tests/mochitest/test_bug715739.html | 88 + .../htmlparser/tests/mochitest/test_bug716579.html | 44 + .../htmlparser/tests/mochitest/test_bug717180.html | 44 + .../tests/mochitest/test_compatmode.html | 100 + .../mochitest/test_html5_tree_construction.html | 60 + .../test_html5_tree_construction_part2.html | 60 + .../tests/mochitest/test_img_picture_preload.html | 88 + .../tests/mochitest/test_xml_mislabeled.html | 62 + .../tests/mochitest/test_xml_parse_error.html | 79 + parser/htmlparser/tests/reftest/after-1kb-ref.html | 9 + parser/htmlparser/tests/reftest/after-1kb.html | 955 ++++++++ .../tests/reftest/after-bogus-after-1kb-ref.html | 9 + .../tests/reftest/after-bogus-after-1kb.html | 933 ++++++++ .../htmlparser/tests/reftest/after-bogus-ref.html | 9 + parser/htmlparser/tests/reftest/after-bogus.html | 10 + .../reftest/after-head-after-1kb-crlf-ref.html | 9 + .../tests/reftest/after-head-after-1kb-crlf.html | 927 ++++++++ .../tests/reftest/after-head-after-1kb-ref.html | 9 + .../tests/reftest/after-head-after-1kb.html | 933 ++++++++ .../tests/reftest/after-head-in-1kb-crlf-ref.html | 9 + .../tests/reftest/after-head-in-1kb-crlf.html | 932 ++++++++ .../tests/reftest/after-head-in-1kb-ref.html | 9 + .../tests/reftest/after-head-in-1kb.html | 938 ++++++++ parser/htmlparser/tests/reftest/baseline-ref.html | 9 + parser/htmlparser/tests/reftest/baseline.html | 10 + .../htmlparser/tests/reftest/bug1153920-1-ref.html | 4 + parser/htmlparser/tests/reftest/bug1153920-1.html | 3 + .../htmlparser/tests/reftest/bug1319410-1-ref.html | 6 + parser/htmlparser/tests/reftest/bug1319410-1.html | 5 + .../htmlparser/tests/reftest/bug1636607-1-ref.html | 18 + parser/htmlparser/tests/reftest/bug1636607-1.html | 18 + .../htmlparser/tests/reftest/bug1636607-2-ref.html | 17 + parser/htmlparser/tests/reftest/bug1636607-2.html | 18 + .../htmlparser/tests/reftest/bug1650087-1-ref.html | 8 + parser/htmlparser/tests/reftest/bug1650087-1.html | 7 + .../htmlparser/tests/reftest/bug1726374-1-ref.html | 2 + parser/htmlparser/tests/reftest/bug1726374-1.html | 1 + .../htmlparser/tests/reftest/bug1749522-1-ref.txt | 3 + parser/htmlparser/tests/reftest/bug1749522-1.txt | 3 + .../htmlparser/tests/reftest/bug482921-1-ref.html | 27 + parser/htmlparser/tests/reftest/bug482921-1.html | 24 + .../htmlparser/tests/reftest/bug482921-2-ref.html | 28 + parser/htmlparser/tests/reftest/bug482921-2.xhtml | 25 + .../htmlparser/tests/reftest/bug535530-1-ref.html | 2 + parser/htmlparser/tests/reftest/bug535530-1.html | 14 + .../htmlparser/tests/reftest/bug535530-2-ref.html | 17 + parser/htmlparser/tests/reftest/bug535530-2.html | 14 + .../htmlparser/tests/reftest/bug566280-1-ref.html | 2 + parser/htmlparser/tests/reftest/bug566280-1.html | Bin 0 -> 19 bytes .../htmlparser/tests/reftest/bug569229-1-ref.xml | 2 + parser/htmlparser/tests/reftest/bug569229-1.xml | 6 + .../htmlparser/tests/reftest/bug577418-1-ref.html | 6 + parser/htmlparser/tests/reftest/bug577418-1.html | 15 + .../htmlparser/tests/reftest/bug582788-1-ref.html | 11 + parser/htmlparser/tests/reftest/bug582788-1.html | 11 + .../htmlparser/tests/reftest/bug582940-1-ref.html | 16 + parser/htmlparser/tests/reftest/bug582940-1.html | 16 + .../htmlparser/tests/reftest/bug592656-1-ref.html | 9 + parser/htmlparser/tests/reftest/bug592656-1.html | 32 + .../htmlparser/tests/reftest/bug599320-1-ref.html | 17 + parser/htmlparser/tests/reftest/bug599320-1.html | Bin 0 -> 616 bytes .../htmlparser/tests/reftest/bug608373-1-ref.html | 9 + parser/htmlparser/tests/reftest/bug608373-1.html | 14 + .../htmlparser/tests/reftest/bug659763-1-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-1.html | 9 + .../htmlparser/tests/reftest/bug659763-2-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-2.html | 9 + .../htmlparser/tests/reftest/bug659763-3-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-3.html | 9 + .../htmlparser/tests/reftest/bug659763-4-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-4.html | 9 + .../htmlparser/tests/reftest/bug659763-5-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-5.html | 9 + .../htmlparser/tests/reftest/bug659763-6-ref.html | 2 + parser/htmlparser/tests/reftest/bug659763-6.html | 9 + .../htmlparser/tests/reftest/bug673094-1-ref.html | 9 + parser/htmlparser/tests/reftest/bug673094-1.html | 9 + .../htmlparser/tests/reftest/bug696651-1-ref.html | 1 + parser/htmlparser/tests/reftest/bug696651-1.html | 2 + .../htmlparser/tests/reftest/bug696651-2-ref.html | 1 + parser/htmlparser/tests/reftest/bug696651-2.html | 6 + .../htmlparser/tests/reftest/bug696651-external.js | 1 + .../htmlparser/tests/reftest/bug700260-1-ref.html | 3 + parser/htmlparser/tests/reftest/bug700260-1.html | 3 + .../htmlparser/tests/reftest/bug704667-1-ref.html | 4 + parser/htmlparser/tests/reftest/bug704667-1.html | 1 + .../htmlparser/tests/reftest/bug731234-1-ref.html | 30 + parser/htmlparser/tests/reftest/bug731234-1.html | 27 + .../htmlparser/tests/reftest/bug820508-1-ref.html | 6 + parser/htmlparser/tests/reftest/bug820508-1.html | 6 + .../htmlparser/tests/reftest/bug910588-1-ref.html | 2 + parser/htmlparser/tests/reftest/bug910588-1.html | 1 + .../tests/reftest/document-write-ref.html | 9 + .../htmlparser/tests/reftest/document-write.html | 10 + .../htmlparser/tests/reftest/frame582940-ref.html | 51 + parser/htmlparser/tests/reftest/frame582940.html | 51 + .../tests/reftest/frame599320-1-ref.html | 15 + parser/htmlparser/tests/reftest/frame599320-1.html | 1092 +++++++++ .../htmlparser/tests/reftest/in-comment-ref.html | 9 + parser/htmlparser/tests/reftest/in-comment.html | 10 + .../in-noscript-after-template-after-1kb-ref.html | 9 + .../in-noscript-after-template-after-1kb.html | 894 ++++++++ .../reftest/in-noscript-after-template-ref.html | 9 + .../tests/reftest/in-noscript-after-template.html | 10 + .../tests/reftest/in-noscript-ncr-ref.html | 9 + .../htmlparser/tests/reftest/in-noscript-ncr.html | 10 + .../htmlparser/tests/reftest/in-noscript-ref.html | 9 + parser/htmlparser/tests/reftest/in-noscript.html | 10 + parser/htmlparser/tests/reftest/in-object-ref.html | 9 + parser/htmlparser/tests/reftest/in-object.html | 10 + parser/htmlparser/tests/reftest/in-script-ref.html | 9 + parser/htmlparser/tests/reftest/in-script.html | 10 + parser/htmlparser/tests/reftest/in-style-ref.html | 9 + parser/htmlparser/tests/reftest/in-style.html | 10 + .../reftest/in-svg-in-cdata-after-gt-ref.html | 10 + .../tests/reftest/in-svg-in-cdata-after-gt.html | 10 + .../tests/reftest/in-svg-in-cdata-ref.html | 10 + .../htmlparser/tests/reftest/in-svg-in-cdata.html | 10 + parser/htmlparser/tests/reftest/in-svg-ref.html | 10 + parser/htmlparser/tests/reftest/in-svg.html | 10 + .../tests/reftest/in-template-after-1kb-ref.html | 8 + .../tests/reftest/in-template-after-1kb.html | 1046 +++++++++ .../htmlparser/tests/reftest/in-template-ref.html | 9 + parser/htmlparser/tests/reftest/in-template.html | 10 + parser/htmlparser/tests/reftest/in-title-ref.html | 10 + parser/htmlparser/tests/reftest/in-title.html | 10 + .../tests/reftest/incomplete-xml-decl-ref.html | 2 + .../tests/reftest/incomplete-xml-decl.xml | 1 + parser/htmlparser/tests/reftest/ncr-ref.html | 9 + parser/htmlparser/tests/reftest/ncr.html | 10 + .../reftest/non-ascii-in-comment-before-ref.html | 9 + .../tests/reftest/non-ascii-in-comment-before.html | 11 + .../reftest/non-ascii-in-title-before-ref.html | 10 + .../tests/reftest/non-ascii-in-title-before.html | 11 + parser/htmlparser/tests/reftest/reftest.list | 73 + .../tests/reftest/view-source-bom-ref.html | 10 + .../htmlparser/tests/reftest/view-source-bom.html | 9 + .../tests/reftest/vs-after-head-after-1kb-ref.html | 11 + .../tests/reftest/vs-after-head-after-1kb.html | 10 + .../tests/reftest/vs-after-head-in-1kb-ref.html | 12 + .../tests/reftest/vs-after-head-in-1kb.html | 11 + .../vs-non-ascii-in-comment-before-ref.html | 12 + .../reftest/vs-non-ascii-in-comment-before.html | 11 + .../reftest/vs-non-ascii-in-comment-before.sjs | 16 + parser/htmlparser/tests/reftest/xml-1.xml | 1 + parser/htmlparser/tests/reftest/xml-ref.html | 2 + parser/htmlparser/tests/reftest/xml-trickle-1.sjs | 17 + parser/htmlparser/tests/reftest/xml-trickle-2.sjs | 17 + parser/htmlparser/tests/reftest/xml-trickle-3.sjs | 21 + parser/htmlparser/tests/reftest/xml-trickle-4.sjs | 17 + parser/htmlparser/tests/reftest/xml-trickle-5.sjs | 17 + parser/htmlparser/tests/reftest/xml-trickle-6.sjs | 21 + parser/htmlparser/tests/reftest/xml-utf-ref.html | 2 + .../tests/reftest/xml-without-tags-ref.html | 2 + .../htmlparser/tests/reftest/xml-without-tags.xml | 1 + 417 files changed, 45589 insertions(+) create mode 100644 parser/htmlparser/CNavDTD.cpp create mode 100644 parser/htmlparser/CNavDTD.h create mode 100644 parser/htmlparser/CParserContext.cpp create mode 100644 parser/htmlparser/CParserContext.h create mode 100644 parser/htmlparser/moz.build create mode 100644 parser/htmlparser/nsElementTable.cpp create mode 100644 parser/htmlparser/nsElementTable.h create mode 100644 parser/htmlparser/nsExpatDriver.cpp create mode 100644 parser/htmlparser/nsExpatDriver.h create mode 100644 parser/htmlparser/nsHTMLTagList.h create mode 100644 parser/htmlparser/nsHTMLTags.cpp create mode 100644 parser/htmlparser/nsHTMLTags.h create mode 100644 parser/htmlparser/nsIContentSink.h create mode 100644 parser/htmlparser/nsIDTD.h create mode 100644 parser/htmlparser/nsIExpatSink.idl create mode 100644 parser/htmlparser/nsIFragmentContentSink.h create mode 100644 parser/htmlparser/nsIHTMLContentSink.h create mode 100644 parser/htmlparser/nsIParser.h create mode 100644 parser/htmlparser/nsParser.cpp create mode 100644 parser/htmlparser/nsParser.h create mode 100644 parser/htmlparser/nsParserBase.h create mode 100644 parser/htmlparser/nsParserConstants.h create mode 100644 parser/htmlparser/nsParserMsgUtils.cpp create mode 100644 parser/htmlparser/nsParserMsgUtils.h create mode 100644 parser/htmlparser/nsRLBoxExpatDriver.h create mode 100644 parser/htmlparser/nsScanner.cpp create mode 100644 parser/htmlparser/nsScanner.h create mode 100644 parser/htmlparser/nsScannerString.cpp create mode 100644 parser/htmlparser/nsScannerString.h create mode 100644 parser/htmlparser/tests/crashtests/121591-1.html create mode 100644 parser/htmlparser/tests/crashtests/1373045-1.html create mode 100644 parser/htmlparser/tests/crashtests/147179-1.html create mode 100644 parser/htmlparser/tests/crashtests/151956-1.html create mode 100644 parser/htmlparser/tests/crashtests/152444-1.html create mode 100644 parser/htmlparser/tests/crashtests/1534346-1.html create mode 100644 parser/htmlparser/tests/crashtests/1547895-1.html create mode 100644 parser/htmlparser/tests/crashtests/1604307-1.html create mode 100644 parser/htmlparser/tests/crashtests/1606499-1.html create mode 100644 parser/htmlparser/tests/crashtests/1747514.html create mode 100644 parser/htmlparser/tests/crashtests/1810896-1.html create mode 100644 parser/htmlparser/tests/crashtests/185073-1.html create mode 100644 parser/htmlparser/tests/crashtests/1854907-1.html create mode 100644 parser/htmlparser/tests/crashtests/188474-1.html create mode 100644 parser/htmlparser/tests/crashtests/194329-1.html create mode 100644 parser/htmlparser/tests/crashtests/197052-1.html create mode 100644 parser/htmlparser/tests/crashtests/220542-1.html create mode 100644 parser/htmlparser/tests/crashtests/253979-1.html create mode 100644 parser/htmlparser/tests/crashtests/269095-1.html create mode 100644 parser/htmlparser/tests/crashtests/286733-1.html create mode 100644 parser/htmlparser/tests/crashtests/286733-2.html create mode 100644 parser/htmlparser/tests/crashtests/299036-1.html create mode 100644 parser/htmlparser/tests/crashtests/30885-1.html create mode 100644 parser/htmlparser/tests/crashtests/30956-1.html create mode 100644 parser/htmlparser/tests/crashtests/31392-1.html create mode 100644 parser/htmlparser/tests/crashtests/31694-1.html create mode 100644 parser/htmlparser/tests/crashtests/31940-1.html create mode 100644 parser/htmlparser/tests/crashtests/32613-1.html create mode 100644 parser/htmlparser/tests/crashtests/328751-1.html create mode 100644 parser/htmlparser/tests/crashtests/34168-1.html create mode 100644 parser/htmlparser/tests/crashtests/34168-1.xml create mode 100644 parser/htmlparser/tests/crashtests/408939-1.html create mode 100644 parser/htmlparser/tests/crashtests/41427-1.html create mode 100644 parser/htmlparser/tests/crashtests/423373-1.html create mode 100644 parser/htmlparser/tests/crashtests/44178-1.html create mode 100644 parser/htmlparser/tests/crashtests/445171-1-inner.svg create mode 100644 parser/htmlparser/tests/crashtests/445171-1.html create mode 100644 parser/htmlparser/tests/crashtests/46495-1.html create mode 100644 parser/htmlparser/tests/crashtests/468538-1.xhtml create mode 100644 parser/htmlparser/tests/crashtests/50134-1.html create mode 100644 parser/htmlparser/tests/crashtests/502103.html create mode 100644 parser/htmlparser/tests/crashtests/502869-iframe.html create mode 100644 parser/htmlparser/tests/crashtests/502869.html create mode 100644 parser/htmlparser/tests/crashtests/50994-1.html create mode 100644 parser/htmlparser/tests/crashtests/515278-1.html create mode 100644 parser/htmlparser/tests/crashtests/515533-1-inner.html create mode 100644 parser/htmlparser/tests/crashtests/515533-1.html create mode 100644 parser/htmlparser/tests/crashtests/515816-1.html create mode 100644 parser/htmlparser/tests/crashtests/522326-1.html create mode 100644 parser/htmlparser/tests/crashtests/525229-1.html create mode 100644 parser/htmlparser/tests/crashtests/536097-1.html create mode 100644 parser/htmlparser/tests/crashtests/555462-iframe.html create mode 100644 parser/htmlparser/tests/crashtests/555462.html create mode 100644 parser/htmlparser/tests/crashtests/563514-1.html create mode 100644 parser/htmlparser/tests/crashtests/574884-1.html create mode 100644 parser/htmlparser/tests/crashtests/574884-2.html create mode 100644 parser/htmlparser/tests/crashtests/58455-1.html create mode 100644 parser/htmlparser/tests/crashtests/591330-1.html create mode 100644 parser/htmlparser/tests/crashtests/60110-1.html create mode 100644 parser/htmlparser/tests/crashtests/616027-1.html create mode 100644 parser/htmlparser/tests/crashtests/650501-1.xhtml create mode 100644 parser/htmlparser/tests/crashtests/662185-1.html create mode 100644 parser/htmlparser/tests/crashtests/696651-1.html create mode 100644 parser/htmlparser/tests/crashtests/699347-1.xml create mode 100644 parser/htmlparser/tests/crashtests/721313-1.html create mode 100644 parser/htmlparser/tests/crashtests/73331-1.html create mode 100644 parser/htmlparser/tests/crashtests/742414-1.html create mode 100644 parser/htmlparser/tests/crashtests/762726-1.html create mode 100644 parser/htmlparser/tests/crashtests/92647-1.html create mode 100644 parser/htmlparser/tests/crashtests/92788-1.html create mode 100644 parser/htmlparser/tests/crashtests/981279-1.html create mode 100644 parser/htmlparser/tests/crashtests/982285-1.html create mode 100644 parser/htmlparser/tests/crashtests/crashtests.list create mode 100644 parser/htmlparser/tests/crashtests/file_445171-1.html create mode 100644 parser/htmlparser/tests/mochitest/blue.png create mode 100644 parser/htmlparser/tests/mochitest/broken_xml.xhtml create mode 100644 parser/htmlparser/tests/mochitest/browser.toml create mode 100644 parser/htmlparser/tests/mochitest/browser_elementindtd.dtd create mode 100644 parser/htmlparser/tests/mochitest/browser_elementindtd.js create mode 100644 parser/htmlparser/tests/mochitest/browser_elementindtd.xml create mode 100644 parser/htmlparser/tests/mochitest/browser_viewsource.js create mode 100644 parser/htmlparser/tests/mochitest/browser_ysod_telemetry.js create mode 100644 parser/htmlparser/tests/mochitest/bug_502091_iframe.html create mode 100644 parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_base_csp_img.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug102699.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug534293.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug543062.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug568470-script.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug568470.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-1.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-2.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-3.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-4.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-5.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-6.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-7.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-8.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug594730-9.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug642908.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug655682.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_enc_error.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_enc_error_inherited.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_after_head.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_replacement.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_speculation_fail.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_xml_decl.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug672453_xml_speculation_fail.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug688580.js create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-16.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-8.html create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml create mode 100644 parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^ create mode 100644 parser/htmlparser/tests/mochitest/file_bug717180.html create mode 100644 parser/htmlparser/tests/mochitest/file_defer_bug1104732.js create mode 100644 parser/htmlparser/tests/mochitest/file_img_picture_preload.html create mode 100644 parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs create mode 100644 parser/htmlparser/tests/mochitest/file_viewsource.html create mode 100644 parser/htmlparser/tests/mochitest/file_xml_parse_error.js create mode 100644 parser/htmlparser/tests/mochitest/file_xml_parse_error.xml create mode 100644 parser/htmlparser/tests/mochitest/html5_tree_construction_exceptions.js create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/README.md create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption02.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/comments01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/doctype01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/domjs-unsafe.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities02.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/foreign-fragment.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_license.txt create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_upstream.txt create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5test-com.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/inbody01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/isindex.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/plain-text-unsafe.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/ruby.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/scriptdata01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/adoption01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/ark.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/webkit01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tables01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/template.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests1.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests20.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests21.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests22.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests23.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests24.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests25.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests26.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests3.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests4.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests5.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests6.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests7.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests8.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests9.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests_innerHTML_1.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/tricky01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit01.dat create mode 100644 parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit02.dat create mode 100644 parser/htmlparser/tests/mochitest/invalidchar.xml create mode 100644 parser/htmlparser/tests/mochitest/mochitest.toml create mode 100644 parser/htmlparser/tests/mochitest/parser_datreader.js create mode 100644 parser/htmlparser/tests/mochitest/parser_web_testrunner.js create mode 100644 parser/htmlparser/tests/mochitest/test_base_csp_img.html create mode 100644 parser/htmlparser/tests/mochitest/test_base_header_csp_img.html create mode 100644 parser/htmlparser/tests/mochitest/test_base_header_csp_img.html^headers^ create mode 100644 parser/htmlparser/tests/mochitest/test_bug102699.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug1104732.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug1209658.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug1364399.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug1646140-1.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug1646140-2.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug174351.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug213517.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug339350.xhtml create mode 100644 parser/htmlparser/tests/mochitest/test_bug358797.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug396568.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug418464.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug460437.xhtml create mode 100644 parser/htmlparser/tests/mochitest/test_bug502091.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug534293.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug543062.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug552938-2.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug552938.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug563322.xhtml create mode 100644 parser/htmlparser/tests/mochitest/test_bug566879.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug568470.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug594730.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug613662.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug613662.xhtml create mode 100644 parser/htmlparser/tests/mochitest/test_bug639362.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug642908.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug645115.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug655682.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug667533.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug672453.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug688580.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug688580.xhtml create mode 100644 parser/htmlparser/tests/mochitest/test_bug709083.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug715112.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug715739.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug716579.html create mode 100644 parser/htmlparser/tests/mochitest/test_bug717180.html create mode 100644 parser/htmlparser/tests/mochitest/test_compatmode.html create mode 100644 parser/htmlparser/tests/mochitest/test_html5_tree_construction.html create mode 100644 parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html create mode 100644 parser/htmlparser/tests/mochitest/test_img_picture_preload.html create mode 100644 parser/htmlparser/tests/mochitest/test_xml_mislabeled.html create mode 100644 parser/htmlparser/tests/mochitest/test_xml_parse_error.html create mode 100644 parser/htmlparser/tests/reftest/after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/after-bogus-after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-bogus-after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/after-bogus-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-bogus.html create mode 100644 parser/htmlparser/tests/reftest/after-head-after-1kb-crlf-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-head-after-1kb-crlf.html create mode 100644 parser/htmlparser/tests/reftest/after-head-after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-head-after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/after-head-in-1kb-crlf-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-head-in-1kb-crlf.html create mode 100644 parser/htmlparser/tests/reftest/after-head-in-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/after-head-in-1kb.html create mode 100644 parser/htmlparser/tests/reftest/baseline-ref.html create mode 100644 parser/htmlparser/tests/reftest/baseline.html create mode 100644 parser/htmlparser/tests/reftest/bug1153920-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1153920-1.html create mode 100644 parser/htmlparser/tests/reftest/bug1319410-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1319410-1.html create mode 100644 parser/htmlparser/tests/reftest/bug1636607-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1636607-1.html create mode 100644 parser/htmlparser/tests/reftest/bug1636607-2-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1636607-2.html create mode 100644 parser/htmlparser/tests/reftest/bug1650087-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1650087-1.html create mode 100644 parser/htmlparser/tests/reftest/bug1726374-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug1726374-1.html create mode 100644 parser/htmlparser/tests/reftest/bug1749522-1-ref.txt create mode 100644 parser/htmlparser/tests/reftest/bug1749522-1.txt create mode 100644 parser/htmlparser/tests/reftest/bug482921-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug482921-1.html create mode 100644 parser/htmlparser/tests/reftest/bug482921-2-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug482921-2.xhtml create mode 100644 parser/htmlparser/tests/reftest/bug535530-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug535530-1.html create mode 100644 parser/htmlparser/tests/reftest/bug535530-2-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug535530-2.html create mode 100644 parser/htmlparser/tests/reftest/bug566280-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug566280-1.html create mode 100644 parser/htmlparser/tests/reftest/bug569229-1-ref.xml create mode 100644 parser/htmlparser/tests/reftest/bug569229-1.xml create mode 100644 parser/htmlparser/tests/reftest/bug577418-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug577418-1.html create mode 100644 parser/htmlparser/tests/reftest/bug582788-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug582788-1.html create mode 100644 parser/htmlparser/tests/reftest/bug582940-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug582940-1.html create mode 100644 parser/htmlparser/tests/reftest/bug592656-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug592656-1.html create mode 100644 parser/htmlparser/tests/reftest/bug599320-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug599320-1.html create mode 100644 parser/htmlparser/tests/reftest/bug608373-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug608373-1.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-1.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-2-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-2.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-3-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-3.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-4-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-4.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-5-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-5.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-6-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug659763-6.html create mode 100644 parser/htmlparser/tests/reftest/bug673094-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug673094-1.html create mode 100644 parser/htmlparser/tests/reftest/bug696651-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug696651-1.html create mode 100644 parser/htmlparser/tests/reftest/bug696651-2-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug696651-2.html create mode 100644 parser/htmlparser/tests/reftest/bug696651-external.js create mode 100644 parser/htmlparser/tests/reftest/bug700260-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug700260-1.html create mode 100644 parser/htmlparser/tests/reftest/bug704667-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug704667-1.html create mode 100644 parser/htmlparser/tests/reftest/bug731234-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug731234-1.html create mode 100644 parser/htmlparser/tests/reftest/bug820508-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug820508-1.html create mode 100644 parser/htmlparser/tests/reftest/bug910588-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/bug910588-1.html create mode 100644 parser/htmlparser/tests/reftest/document-write-ref.html create mode 100644 parser/htmlparser/tests/reftest/document-write.html create mode 100644 parser/htmlparser/tests/reftest/frame582940-ref.html create mode 100644 parser/htmlparser/tests/reftest/frame582940.html create mode 100644 parser/htmlparser/tests/reftest/frame599320-1-ref.html create mode 100644 parser/htmlparser/tests/reftest/frame599320-1.html create mode 100644 parser/htmlparser/tests/reftest/in-comment-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-comment.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-after-template-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-after-template.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-ncr-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-ncr.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-noscript.html create mode 100644 parser/htmlparser/tests/reftest/in-object-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-object.html create mode 100644 parser/htmlparser/tests/reftest/in-script-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-script.html create mode 100644 parser/htmlparser/tests/reftest/in-style-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-style.html create mode 100644 parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt.html create mode 100644 parser/htmlparser/tests/reftest/in-svg-in-cdata-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-svg-in-cdata.html create mode 100644 parser/htmlparser/tests/reftest/in-svg-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-svg.html create mode 100644 parser/htmlparser/tests/reftest/in-template-after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-template-after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/in-template-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-template.html create mode 100644 parser/htmlparser/tests/reftest/in-title-ref.html create mode 100644 parser/htmlparser/tests/reftest/in-title.html create mode 100644 parser/htmlparser/tests/reftest/incomplete-xml-decl-ref.html create mode 100644 parser/htmlparser/tests/reftest/incomplete-xml-decl.xml create mode 100644 parser/htmlparser/tests/reftest/ncr-ref.html create mode 100644 parser/htmlparser/tests/reftest/ncr.html create mode 100644 parser/htmlparser/tests/reftest/non-ascii-in-comment-before-ref.html create mode 100644 parser/htmlparser/tests/reftest/non-ascii-in-comment-before.html create mode 100644 parser/htmlparser/tests/reftest/non-ascii-in-title-before-ref.html create mode 100644 parser/htmlparser/tests/reftest/non-ascii-in-title-before.html create mode 100644 parser/htmlparser/tests/reftest/reftest.list create mode 100644 parser/htmlparser/tests/reftest/view-source-bom-ref.html create mode 100644 parser/htmlparser/tests/reftest/view-source-bom.html create mode 100644 parser/htmlparser/tests/reftest/vs-after-head-after-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/vs-after-head-after-1kb.html create mode 100644 parser/htmlparser/tests/reftest/vs-after-head-in-1kb-ref.html create mode 100644 parser/htmlparser/tests/reftest/vs-after-head-in-1kb.html create mode 100644 parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before-ref.html create mode 100644 parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.html create mode 100644 parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-1.xml create mode 100644 parser/htmlparser/tests/reftest/xml-ref.html create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-1.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-2.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-3.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-4.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-5.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-trickle-6.sjs create mode 100644 parser/htmlparser/tests/reftest/xml-utf-ref.html create mode 100644 parser/htmlparser/tests/reftest/xml-without-tags-ref.html create mode 100644 parser/htmlparser/tests/reftest/xml-without-tags.xml (limited to 'parser/htmlparser') diff --git a/parser/htmlparser/CNavDTD.cpp b/parser/htmlparser/CNavDTD.cpp new file mode 100644 index 0000000000..d18aacfcb2 --- /dev/null +++ b/parser/htmlparser/CNavDTD.cpp @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.h" +#include "nsISupportsImpl.h" +#include "nsIParser.h" +#include "CNavDTD.h" +#include "nsIHTMLContentSink.h" + +NS_IMPL_ISUPPORTS(CNavDTD, nsIDTD); + +CNavDTD::CNavDTD() {} + +CNavDTD::~CNavDTD() {} + +NS_IMETHODIMP +CNavDTD::BuildModel(nsIContentSink* aSink) { + // NB: It is important to throw STOPPARSING if the sink is the wrong type in + // order to make sure nsParser cleans up properly after itself. + nsCOMPtr sink = do_QueryInterface(aSink); + if (!sink) { + return NS_ERROR_HTMLPARSER_STOPPARSING; + } + + nsresult rv = sink->OpenContainer(nsIHTMLContentSink::eHTML); + NS_ENSURE_SUCCESS(rv, rv); + rv = sink->OpenContainer(nsIHTMLContentSink::eBody); + NS_ENSURE_SUCCESS(rv, rv); + + rv = sink->CloseContainer(nsIHTMLContentSink::eBody); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + rv = sink->CloseContainer(nsIHTMLContentSink::eHTML); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + return NS_OK; +} + +void CNavDTD::DidBuildModel() {} + +NS_IMETHODIMP_(void) +CNavDTD::Terminate() {} diff --git a/parser/htmlparser/CNavDTD.h b/parser/htmlparser/CNavDTD.h new file mode 100644 index 0000000000..6b4c2511a9 --- /dev/null +++ b/parser/htmlparser/CNavDTD.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef NS_NAVHTMLDTD__ +#define NS_NAVHTMLDTD__ + +#include "nsIDTD.h" +#include "nsISupports.h" +#include "nsCOMPtr.h" + +#ifdef _MSC_VER +# pragma warning(disable : 4275) +#endif + +class CNavDTD : public nsIDTD { +#ifdef _MSC_VER +# pragma warning(default : 4275) +#endif + + virtual ~CNavDTD(); + + public: + CNavDTD(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIDTD +}; + +#endif diff --git a/parser/htmlparser/CParserContext.cpp b/parser/htmlparser/CParserContext.cpp new file mode 100644 index 0000000000..d57c9855cc --- /dev/null +++ b/parser/htmlparser/CParserContext.cpp @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsAtom.h" +#include "CParserContext.h" +#include "prenv.h" +#include "nsIHTMLContentSink.h" +#include "nsMimeTypes.h" + +CParserContext::CParserContext(nsIURI* aURI, eParserCommands aCommand) + : mScanner(aURI), + mDTDMode(eDTDMode_autodetect), + mDocType(eUnknown), + mStreamListenerState(eNone), + mContextType(eCTURL), + mParserCommand(aCommand), + mMultipart(true), + mCopyUnused(false) { + MOZ_COUNT_CTOR(CParserContext); +} + +CParserContext::CParserContext(const nsAString& aBuffer, + eParserCommands aCommand, bool aLastBuffer) + : mScanner(aBuffer, !aLastBuffer), + mMimeType("application/xml"_ns), + mDTDMode(eDTDMode_full_standards), + mDocType(eXML), + mStreamListenerState(aLastBuffer ? eOnStop : eOnDataAvail), + mContextType(eCTString), + mParserCommand(aCommand), + mMultipart(!aLastBuffer), + mCopyUnused(aLastBuffer) { + MOZ_COUNT_CTOR(CParserContext); +} + +CParserContext::~CParserContext() { + // It's ok to simply ingore the PrevContext. + MOZ_COUNT_DTOR(CParserContext); +} + +void CParserContext::SetMimeType(const nsACString& aMimeType) { + mMimeType.Assign(aMimeType); + + mDocType = eUnknown; + + if (mMimeType.EqualsLiteral(TEXT_HTML)) + mDocType = eHTML_Strict; + else if (mMimeType.EqualsLiteral(TEXT_XML) || + mMimeType.EqualsLiteral(APPLICATION_XML) || + mMimeType.EqualsLiteral(APPLICATION_XHTML_XML) || + mMimeType.EqualsLiteral(IMAGE_SVG_XML) || + mMimeType.EqualsLiteral(APPLICATION_MATHML_XML) || + mMimeType.EqualsLiteral(APPLICATION_RDF_XML) || + mMimeType.EqualsLiteral(APPLICATION_WAPXHTML_XML) || + mMimeType.EqualsLiteral(TEXT_RDF)) + mDocType = eXML; +} diff --git a/parser/htmlparser/CParserContext.h b/parser/htmlparser/CParserContext.h new file mode 100644 index 0000000000..b32436795b --- /dev/null +++ b/parser/htmlparser/CParserContext.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * MODULE NOTES: + * @update gess 4/1/98 + * + */ + +#ifndef __CParserContext +#define __CParserContext + +#include "mozilla/UniquePtr.h" +#include "nsIParser.h" +#include "nsIDTD.h" +#include "nsIRequest.h" +#include "nsScanner.h" +#include "nsString.h" +#include "nsCOMPtr.h" + +class nsITokenizer; + +/** + * Note that the parser is given FULL access to all + * data in a parsercontext. Hey, that what it's for! + */ + +class CParserContext { + public: + enum eContextType { eCTURL, eCTString }; + + CParserContext(nsIURI* aURI, eParserCommands aCommand); + CParserContext(const nsAString& aBuffer, eParserCommands aCommand, + bool aLastBuffer); + + ~CParserContext(); + + void SetMimeType(const nsACString& aMimeType); + + nsCOMPtr + mRequest; // provided by necko to differnciate different input streams + // why is mRequest strongly referenced? see bug 102376. + nsScanner mScanner; + + nsCString mMimeType; + nsDTDMode mDTDMode; + + eParserDocType mDocType; + eStreamState mStreamListenerState; + eContextType mContextType; + eAutoDetectResult mAutoDetectStatus = eUnknownDetect; + eParserCommands mParserCommand; + + bool mMultipart; + bool mCopyUnused; +}; + +#endif diff --git a/parser/htmlparser/moz.build b/parser/htmlparser/moz.build new file mode 100644 index 0000000000..c5b1cc378d --- /dev/null +++ b/parser/htmlparser/moz.build @@ -0,0 +1,52 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +with Files("**"): + BUG_COMPONENT = ("Core", "XML") + +MOCHITEST_MANIFESTS += ["tests/mochitest/mochitest.toml"] +BROWSER_CHROME_MANIFESTS += ["tests/mochitest/browser.toml"] + +XPIDL_SOURCES += [ + "nsIExpatSink.idl", +] + +XPIDL_MODULE = "htmlparser" + +EXPORTS += [ + "nsElementTable.h", + "nsHTMLTagList.h", + "nsHTMLTags.h", + "nsIContentSink.h", + "nsIDTD.h", + "nsIFragmentContentSink.h", + "nsIHTMLContentSink.h", + "nsIParser.h", + "nsParserBase.h", + "nsParserConstants.h", + "nsRLBoxExpatDriver.h", + "nsScannerString.h", +] + +UNIFIED_SOURCES += [ + "CNavDTD.cpp", + "CParserContext.cpp", + "nsElementTable.cpp", + "nsExpatDriver.cpp", + "nsHTMLTags.cpp", + "nsParser.cpp", + "nsParserMsgUtils.cpp", + "nsScanner.cpp", + "nsScannerString.cpp", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" + +LOCAL_INCLUDES += [ + "!/security/rlbox", +] diff --git a/parser/htmlparser/nsElementTable.cpp b/parser/htmlparser/nsElementTable.cpp new file mode 100644 index 0000000000..f3801f0764 --- /dev/null +++ b/parser/htmlparser/nsElementTable.cpp @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsElementTable.h" + +struct HTMLElement { +#ifdef DEBUG + nsHTMLTag mTagID; +#endif + bool mIsBlock; + bool mIsContainer; +}; + +#ifdef DEBUG +# define ELEM(tag, block, container) {eHTMLTag_##tag, block, container}, +#else +# define ELEM(tag, block, container) {block, container}, +#endif + +#define ____ false // This makes the table easier to read. + +// Note that the mIsBlock field disagrees with +// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements for +// the following elements: center, details, dialog, dir, dt, figcaption, +// listing, menu, multicol, noscript, output, summary, tfoot, video. +// +// mrbkap thinks that the field values were pulled from the old HTML4 DTD and +// then got modified in mostly random ways to make the old parser's behavior +// compatible with the web. So it might make sense to change the mIsBlock +// values for the abovementioned tags at some point. +// +static const HTMLElement gHTMLElements[] = { + // clang-format off + ELEM(unknown, ____, ____) + ELEM(a, ____, true) + ELEM(abbr, ____, true) + ELEM(acronym, ____, true) + ELEM(address, true, true) + ELEM(applet, ____, true) + ELEM(area, ____, ____) + ELEM(article, true, true) + ELEM(aside, true, true) + ELEM(audio, ____, true) + ELEM(b, ____, true) + ELEM(base, ____, ____) + ELEM(basefont, ____, ____) + ELEM(bdi, ____, true) + ELEM(bdo, ____, true) + ELEM(bgsound, ____, ____) + ELEM(big, ____, true) + ELEM(blockquote, true, true) + ELEM(body, ____, true) + ELEM(br, ____, ____) + ELEM(button, ____, true) + ELEM(canvas, ____, true) + ELEM(caption, ____, true) + ELEM(center, true, true) + ELEM(cite, ____, true) + ELEM(code, ____, true) + ELEM(col, ____, ____) + ELEM(colgroup, ____, true) + ELEM(data, ____, true) + ELEM(datalist, ____, true) + ELEM(dd, ____, true) + ELEM(del, ____, true) + ELEM(details, true, true) + ELEM(dfn, ____, true) + ELEM(dialog, true, true) + ELEM(dir, true, true) + ELEM(div, true, true) + ELEM(dl, true, true) + ELEM(dt, ____, true) + ELEM(em, ____, true) + ELEM(embed, ____, ____) + ELEM(fieldset, true, true) + ELEM(figcaption, ____, true) + ELEM(figure, true, true) + ELEM(font, ____, true) + ELEM(footer, true, true) + ELEM(form, true, true) + ELEM(frame, ____, ____) + ELEM(frameset, ____, true) + ELEM(h1, true, true) + ELEM(h2, true, true) + ELEM(h3, true, true) + ELEM(h4, true, true) + ELEM(h5, true, true) + ELEM(h6, true, true) + ELEM(head, ____, true) + ELEM(header, true, true) + ELEM(hgroup, true, true) + ELEM(hr, true, ____) + ELEM(html, ____, true) + ELEM(i, ____, true) + ELEM(iframe, ____, true) + ELEM(image, ____, ____) + ELEM(img, ____, ____) + ELEM(input, ____, ____) + ELEM(ins, ____, true) + ELEM(kbd, ____, true) + ELEM(keygen, ____, ____) + ELEM(label, ____, true) + ELEM(legend, ____, true) + ELEM(li, true, true) + ELEM(link, ____, ____) + ELEM(listing, true, true) + ELEM(main, true, true) + ELEM(map, ____, true) + ELEM(mark, ____, true) + ELEM(marquee, ____, true) + ELEM(menu, true, true) + ELEM(meta, ____, ____) + ELEM(meter, ____, true) + ELEM(multicol, true, true) + ELEM(nav, true, true) + ELEM(nobr, ____, true) + ELEM(noembed, ____, true) + ELEM(noframes, ____, true) + ELEM(noscript, ____, true) + ELEM(object, ____, true) + ELEM(ol, true, true) + ELEM(optgroup, ____, true) + ELEM(option, ____, true) + ELEM(output, ____, true) + ELEM(p, true, true) + ELEM(param, ____, ____) + ELEM(picture, ____, true) + ELEM(plaintext, ____, true) + ELEM(pre, true, true) + ELEM(progress, ____, true) + ELEM(q, ____, true) + ELEM(rb, ____, true) + ELEM(rp, ____, true) + ELEM(rt, ____, true) + ELEM(rtc, ____, true) + ELEM(ruby, ____, true) + ELEM(s, ____, true) + ELEM(samp, ____, true) + ELEM(script, ____, true) + ELEM(search, true, true) + ELEM(section, true, true) + ELEM(select, ____, true) + ELEM(small, ____, true) + ELEM(slot, ____, true) + ELEM(source, ____, ____) + ELEM(span, ____, true) + ELEM(strike, ____, true) + ELEM(strong, ____, true) + ELEM(style, ____, true) + ELEM(sub, ____, true) + ELEM(summary, true, true) + ELEM(sup, ____, true) + ELEM(table, true, true) + ELEM(tbody, ____, true) + ELEM(td, ____, true) + ELEM(textarea, ____, true) + ELEM(tfoot, ____, true) + ELEM(th, ____, true) + ELEM(thead, ____, true) + ELEM(template, ____, true) + ELEM(time, ____, true) + ELEM(title, ____, true) + ELEM(tr, ____, true) + ELEM(track, ____, ____) + ELEM(tt, ____, true) + ELEM(u, ____, true) + ELEM(ul, true, true) + ELEM(var, ____, true) + ELEM(video, ____, true) + ELEM(wbr, ____, ____) + ELEM(xmp, ____, true) + ELEM(text, ____, ____) + ELEM(whitespace, ____, ____) + ELEM(newline, ____, ____) + ELEM(comment, ____, true) + ELEM(entity, ____, true) + ELEM(doctypeDecl, ____, true) + ELEM(markupDecl, ____, true) + ELEM(instruction, ____, true) + ELEM(userdefined, ____, true) + // clang-format on +}; + +#undef ELEM +#undef ____ + +bool nsHTMLElement::IsContainer(nsHTMLTag aId) { + return gHTMLElements[aId].mIsContainer; +} + +bool nsHTMLElement::IsBlock(nsHTMLTag aId) { + return gHTMLElements[aId].mIsBlock; +} + +#ifdef DEBUG +void CheckElementTable() { + for (nsHTMLTag t = eHTMLTag_unknown; t <= eHTMLTag_userdefined; + t = nsHTMLTag(t + 1)) { + MOZ_ASSERT(gHTMLElements[t].mTagID == t, + "gHTMLElements entries does match tag list."); + } +} +#endif diff --git a/parser/htmlparser/nsElementTable.h b/parser/htmlparser/nsElementTable.h new file mode 100644 index 0000000000..23edea76c7 --- /dev/null +++ b/parser/htmlparser/nsElementTable.h @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsElementTable_h +#define nsElementTable_h + +#include "nsHTMLTags.h" + +#ifdef DEBUG +void CheckElementTable(); +#endif + +struct nsHTMLElement { + static bool IsContainer(nsHTMLTag aTag); + static bool IsBlock(nsHTMLTag aTag); +}; + +#endif // nsElementTable_h diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp new file mode 100644 index 0000000000..4da2444f84 --- /dev/null +++ b/parser/htmlparser/nsExpatDriver.cpp @@ -0,0 +1,1747 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsExpatDriver.h" +#include "mozilla/fallible.h" +#include "nsCOMPtr.h" +#include "CParserContext.h" +#include "nsIExpatSink.h" +#include "nsIContentSink.h" +#include "nsIDocShell.h" +#include "nsParserMsgUtils.h" +#include "nsIURL.h" +#include "nsIUnicharInputStream.h" +#include "nsIProtocolHandler.h" +#include "nsNetUtil.h" +#include "nsString.h" +#include "nsTextFormatter.h" +#include "nsDirectoryServiceDefs.h" +#include "nsCRT.h" +#include "nsIConsoleService.h" +#include "nsIScriptError.h" +#include "nsIScriptGlobalObject.h" +#include "nsIContentPolicy.h" +#include "nsComponentManagerUtils.h" +#include "nsContentPolicyUtils.h" +#include "nsError.h" +#include "nsXPCOMCIDInternal.h" +#include "nsUnicharInputStream.h" +#include "nsContentUtils.h" +#include "mozilla/Array.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/IntegerTypeTraits.h" +#include "mozilla/NullPrincipal.h" +#include "mozilla/Telemetry.h" +#include "mozilla/TelemetryComms.h" + +#include "nsThreadUtils.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/RLBoxUtils.h" +#include "mozilla/UniquePtr.h" + +#include "mozilla/Logging.h" + +using mozilla::fallible; +using mozilla::LogLevel; +using mozilla::MakeStringSpan; +using mozilla::Maybe; +using mozilla::Unused; +using mozilla::dom::Document; + +// We only pass chunks of length sMaxChunkLength to Expat in the RLBOX sandbox. +// The RLBOX sandbox has a limited amount of memory, and we have to account for +// other memory use by Expat (including the buffering it does). +// Note that sMaxChunkLength is in number of characters. +#ifdef DEBUG +// On debug builds we set a much lower limit (1kB) to try to hit boundary +// conditions more frequently. +static const uint32_t sMaxChunkLength = 1024 / sizeof(char16_t); +#else +static const uint32_t sMaxChunkLength = (128 * 1024) / sizeof(char16_t); +#endif + +#define kExpatSeparatorChar 0xFFFF + +static const char16_t kUTF16[] = {'U', 'T', 'F', '-', '1', '6', '\0'}; + +static mozilla::LazyLogModule gExpatDriverLog("expatdriver"); + +// Use the same maximum tree depth as Chromium (see +// https://chromium.googlesource.com/chromium/src/+/f464165c1dedff1c955d3c051c5a9a1c6a0e8f6b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp#85). +static const uint16_t sMaxXMLTreeDepth = 5000; + +/***************************** RLBOX HELPERS ********************************/ +// Helpers for calling sandboxed expat functions in handlers + +#define RLBOX_EXPAT_SAFE_CALL(foo, verifier, ...) \ + aSandbox.invoke_sandbox_function(foo, self->mExpatParser, ##__VA_ARGS__) \ + .copy_and_verify(verifier) + +#define RLBOX_EXPAT_SAFE_MCALL(foo, verifier, ...) \ + Sandbox() \ + ->invoke_sandbox_function(foo, mExpatParser, ##__VA_ARGS__) \ + .copy_and_verify(verifier) + +#define RLBOX_EXPAT_CALL(foo, ...) \ + aSandbox.invoke_sandbox_function(foo, self->mExpatParser, ##__VA_ARGS__) + +#define RLBOX_EXPAT_MCALL(foo, ...) \ + Sandbox()->invoke_sandbox_function(foo, mExpatParser, ##__VA_ARGS__) + +#define RLBOX_SAFE_PRINT "Value used only for printing" +#define MOZ_RELEASE_ASSERT_TAINTED(cond, ...) \ + MOZ_RELEASE_ASSERT((cond).unverified_safe_because("Sanity check"), \ + ##__VA_ARGS__) + +/* safe_unverified is used whenever it's safe to not use a validator */ +template +static T safe_unverified(T val) { + return val; +} + +/* status_verifier is a type validator for XML_Status */ +inline enum XML_Status status_verifier(enum XML_Status s) { + MOZ_RELEASE_ASSERT(s >= XML_STATUS_ERROR && s <= XML_STATUS_SUSPENDED, + "unexpected status code"); + return s; +} + +/* error_verifier is a type validator for XML_Error */ +inline enum XML_Error error_verifier(enum XML_Error code) { + MOZ_RELEASE_ASSERT( + code >= XML_ERROR_NONE && code <= XML_ERROR_INVALID_ARGUMENT, + "unexpected XML error code"); + return code; +} + +/* We use unverified_xml_string to just expose sandbox expat strings to Firefox + * without any validation. On 64-bit we have guard pages at the sandbox + * boundary; on 32-bit we don't and a string could be used to read beyond the + * sandbox boundary. In our attacker model this is okay (the attacker can just + * Spectre). + * + * Nevertheless, we should try to add strings validators to the consumer code + * of expat whenever we have some semantics. At the very lest we should make + * sure that the strings are never written to. Bug 1693991 tracks this. + */ +static const XML_Char* unverified_xml_string(uintptr_t ptr) { + return reinterpret_cast(ptr); +} + +/* The TransferBuffer class is used to copy (or directly expose in the + * noop-sandbox case) buffers into the expat sandbox (and automatically + * when out of scope). + */ +template +using TransferBuffer = + mozilla::RLBoxTransferBufferToSandbox; + +/*************************** END RLBOX HELPERS ******************************/ + +/***************************** EXPAT CALL BACKS ******************************/ +// The callback handlers that get called from the expat parser. + +static void Driver_HandleXMLDeclaration( + rlbox_sandbox_expat& aSandbox, tainted_expat /* aUserData */, + tainted_expat aVersion, + tainted_expat aEncoding, tainted_expat aStandalone) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + + int standalone = aStandalone.copy_and_verify([&](auto a) { + // Standalone argument can be -1, 0, or 1 (see + // /parser/expat/lib/expat.h#185) + MOZ_RELEASE_ASSERT(a >= -1 && a <= 1, "Unexpected standalone parameter"); + return a; + }); + + const auto* version = aVersion.copy_and_verify_address(unverified_xml_string); + const auto* encoding = + aEncoding.copy_and_verify_address(unverified_xml_string); + driver->HandleXMLDeclaration(version, encoding, standalone); +} + +static void Driver_HandleCharacterData(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */, + tainted_expat aData, + tainted_expat aLength) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + // aData is not null terminated; even with bad length we will not span beyond + // sandbox boundary + uint32_t length = + static_cast(aLength.copy_and_verify(safe_unverified)); + const auto* data = aData.unverified_safe_pointer_because( + length, "Only care that the data is within sandbox boundary."); + driver->HandleCharacterData(data, length); +} + +static void Driver_HandleComment(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */, + tainted_expat aName) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + const auto* name = aName.copy_and_verify_address(unverified_xml_string); + driver->HandleComment(name); +} + +static void Driver_HandleProcessingInstruction( + rlbox_sandbox_expat& aSandbox, tainted_expat /* aUserData */, + tainted_expat aTarget, + tainted_expat aData) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + const auto* target = aTarget.copy_and_verify_address(unverified_xml_string); + const auto* data = aData.copy_and_verify_address(unverified_xml_string); + driver->HandleProcessingInstruction(target, data); +} + +static void Driver_HandleDefault(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */, + tainted_expat aData, + tainted_expat aLength) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + // aData is not null terminated; even with bad length we will not span + // beyond sandbox boundary + uint32_t length = + static_cast(aLength.copy_and_verify(safe_unverified)); + const auto* data = aData.unverified_safe_pointer_because( + length, "Only care that the data is within sandbox boundary."); + driver->HandleDefault(data, length); +} + +static void Driver_HandleStartCdataSection( + rlbox_sandbox_expat& aSandbox, tainted_expat /* aUserData */) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + driver->HandleStartCdataSection(); +} + +static void Driver_HandleEndCdataSection(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + driver->HandleEndCdataSection(); +} + +static void Driver_HandleStartDoctypeDecl( + rlbox_sandbox_expat& aSandbox, tainted_expat /* aUserData */, + tainted_expat aDoctypeName, + tainted_expat aSysid, + tainted_expat aPubid, + tainted_expat aHasInternalSubset) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + const auto* doctypeName = + aDoctypeName.copy_and_verify_address(unverified_xml_string); + const auto* sysid = aSysid.copy_and_verify_address(unverified_xml_string); + const auto* pubid = aPubid.copy_and_verify_address(unverified_xml_string); + bool hasInternalSubset = + !!(aHasInternalSubset.copy_and_verify(safe_unverified)); + driver->HandleStartDoctypeDecl(doctypeName, sysid, pubid, hasInternalSubset); +} + +static void Driver_HandleEndDoctypeDecl(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + driver->HandleEndDoctypeDecl(); +} + +static tainted_expat Driver_HandleExternalEntityRef( + rlbox_sandbox_expat& aSandbox, tainted_expat /* aParser */, + tainted_expat aOpenEntityNames, + tainted_expat aBase, + tainted_expat aSystemId, + tainted_expat aPublicId) { + nsExpatDriver* driver = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(driver); + + const auto* openEntityNames = + aOpenEntityNames.copy_and_verify_address(unverified_xml_string); + const auto* base = aBase.copy_and_verify_address(unverified_xml_string); + const auto* systemId = + aSystemId.copy_and_verify_address(unverified_xml_string); + const auto* publicId = + aPublicId.copy_and_verify_address(unverified_xml_string); + return driver->HandleExternalEntityRef(openEntityNames, base, systemId, + publicId); +} + +/***************************** END CALL BACKS ********************************/ + +/***************************** CATALOG UTILS *********************************/ + +// Initially added for bug 113400 to switch from the remote "XHTML 1.0 plus +// MathML 2.0" DTD to the the lightweight customized version that Mozilla uses. +// Since Mozilla is not validating, no need to fetch a *huge* file at each +// click. +// XXX The cleanest solution here would be to fix Bug 98413: Implement XML +// Catalogs. +struct nsCatalogData { + const char* mPublicID; + const char* mLocalDTD; + const char* mAgentSheet; +}; + +// The order of this table is guestimated to be in the optimum order +static const nsCatalogData kCatalogTable[] = { + {"-//W3C//DTD XHTML 1.0 Transitional//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML 1.1//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML 1.0 Strict//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML 1.0 Frameset//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML Basic 1.0//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN", "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN", + "htmlmathml-f.ent", nullptr}, + {"-//W3C//DTD MathML 2.0//EN", "htmlmathml-f.ent", nullptr}, + {"-//WAPFORUM//DTD XHTML Mobile 1.0//EN", "htmlmathml-f.ent", nullptr}, + {nullptr, nullptr, nullptr}}; + +static const nsCatalogData* LookupCatalogData(const char16_t* aPublicID) { + nsDependentString publicID(aPublicID); + + // linear search for now since the number of entries is going to + // be negligible, and the fix for bug 98413 would get rid of this + // code anyway + const nsCatalogData* data = kCatalogTable; + while (data->mPublicID) { + if (publicID.EqualsASCII(data->mPublicID)) { + return data; + } + ++data; + } + + return nullptr; +} + +// This function provides a resource URI to a local DTD +// in resource://gre/res/dtd/ which may or may not exist. +// If aCatalogData is provided, it is used to remap the +// DTD instead of taking the filename from the URI. aDTD +// may be null in some cases that are relying on +// aCatalogData working for them. +static void GetLocalDTDURI(const nsCatalogData* aCatalogData, nsIURI* aDTD, + nsIURI** aResult) { + nsAutoCString fileName; + if (aCatalogData) { + // remap the DTD to a known local DTD + fileName.Assign(aCatalogData->mLocalDTD); + } + + if (fileName.IsEmpty()) { + // Try to see if the user has installed the DTD file -- we extract the + // filename.ext of the DTD here. Hence, for any DTD for which we have + // no predefined mapping, users just have to copy the DTD file to our + // special DTD directory and it will be picked. + nsCOMPtr dtdURL = do_QueryInterface(aDTD); + if (!dtdURL) { + // Not a URL with a filename, or maybe it was null. Either way, nothing + // else we can do here. + return; + } + + dtdURL->GetFileName(fileName); + if (fileName.IsEmpty()) { + return; + } + } + + nsAutoCString respath("resource://gre/res/dtd/"); + respath += fileName; + NS_NewURI(aResult, respath); +} + +/***************************** END CATALOG UTILS *****************************/ + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsExpatDriver) + NS_INTERFACE_MAP_ENTRY(nsIDTD) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsExpatDriver) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver) + +NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink) + +nsExpatDriver::nsExpatDriver() + : mExpatParser(nullptr), + mInCData(false), + mInInternalSubset(false), + mInExternalDTD(false), + mMadeFinalCallToExpat(false), + mInParser(false), + mInternalState(NS_OK), + mExpatBuffered(0), + mTagDepth(0), + mCatalogData(nullptr), + mInnerWindowID(0) {} + +nsExpatDriver::~nsExpatDriver() { Destroy(); } + +void nsExpatDriver::Destroy() { + if (mSandboxPoolData) { + SandboxData()->DetachDriver(); + if (mExpatParser) { + RLBOX_EXPAT_MCALL(MOZ_XML_ParserFree); + } + } + mSandboxPoolData.reset(); + mURIs.Clear(); + mExpatParser = nullptr; +} + +// The AllocAttrs class is used to speed up copying attributes from the +// sandboxed expat by fast allocating attributes on the stack and only falling +// back to malloc when we need to allocate lots of attributes. +class MOZ_STACK_CLASS AllocAttrs { +#define NUM_STACK_SLOTS 16 + public: + const char16_t** Init(size_t size) { + if (size <= NUM_STACK_SLOTS) { + return mInlineArr; + } + mHeapPtr = mozilla::MakeUnique(size); + return mHeapPtr.get(); + } + + private: + const char16_t* mInlineArr[NUM_STACK_SLOTS]; + mozilla::UniquePtr mHeapPtr; +#undef NUM_STACK_SLOTS +}; + +/* static */ +void nsExpatDriver::HandleStartElement(rlbox_sandbox_expat& aSandbox, + tainted_expat /* aUserData */, + tainted_expat aName, + tainted_expat aAttrs) { + nsExpatDriver* self = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(self && self->mSink); + + const auto* name = aName.copy_and_verify_address(unverified_xml_string); + + // Calculate the total number of elements in aAttrs. + // XML_GetSpecifiedAttributeCount will only give us the number of specified + // attrs (twice that number, actually), so we have to check for default + // attrs ourselves. + tainted_expat count = + RLBOX_EXPAT_CALL(MOZ_XML_GetSpecifiedAttributeCount); + MOZ_RELEASE_ASSERT_TAINTED(count >= 0, "Unexpected attribute count"); + + tainted_expat attrArrayLengthTainted; + for (attrArrayLengthTainted = rlbox::sandbox_static_cast(count); + (aAttrs[attrArrayLengthTainted] != nullptr) + .unverified_safe_because("Bad length is checked later"); + attrArrayLengthTainted += 2) { + // Just looping till we find out what the length is + } + + uint32_t attrArrayLength = + attrArrayLengthTainted.copy_and_verify([&](uint64_t value) { + // A malicious length could result in an overflow when we allocate + // aAttrs and then access elements of the array. + MOZ_RELEASE_ASSERT(value < UINT32_MAX, "Overflow attempt"); + return value; + }); + + // Copy tainted aAttrs from sandbox + AllocAttrs allocAttrs; + const char16_t** attrs = allocAttrs.Init(attrArrayLength + 1); + if (NS_WARN_IF(!aAttrs || !attrs)) { + self->MaybeStopParser(NS_ERROR_OUT_OF_MEMORY); + return; + } + + for (uint32_t i = 0; i < attrArrayLength; i++) { + attrs[i] = aAttrs[i].copy_and_verify_address(unverified_xml_string); + } + attrs[attrArrayLength] = nullptr; + + if (self->mSink) { + // We store the tagdepth in a PRUint16, so make sure the limit fits in a + // PRUint16. + static_assert( + sMaxXMLTreeDepth <= + std::numeric_limits::max()); + + if (++self->mTagDepth > sMaxXMLTreeDepth) { + self->MaybeStopParser(NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP); + return; + } + + nsresult rv = self->mSink->HandleStartElement( + name, attrs, attrArrayLength, + RLBOX_EXPAT_SAFE_CALL(MOZ_XML_GetCurrentLineNumber, + safe_unverified), + RLBOX_EXPAT_SAFE_CALL(MOZ_XML_GetCurrentColumnNumber, + safe_unverified)); + self->MaybeStopParser(rv); + } +} + +/* static */ +void nsExpatDriver::HandleStartElementForSystemPrincipal( + rlbox_sandbox_expat& aSandbox, tainted_expat aUserData, + tainted_expat aName, + tainted_expat aAttrs) { + nsExpatDriver* self = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(self); + if (!RLBOX_EXPAT_SAFE_CALL(MOZ_XML_ProcessingEntityValue, + safe_unverified)) { + HandleStartElement(aSandbox, aUserData, aName, aAttrs); + } else { + nsCOMPtr doc = + do_QueryInterface(self->mOriginalSink->GetTarget()); + + // Adjust the column number so that it is one based rather than zero + // based. + tainted_expat colNumber = + RLBOX_EXPAT_CALL(MOZ_XML_GetCurrentColumnNumber) + 1; + tainted_expat lineNumber = + RLBOX_EXPAT_CALL(MOZ_XML_GetCurrentLineNumber); + + int32_t nameSpaceID; + RefPtr prefix, localName; + const auto* name = aName.copy_and_verify_address(unverified_xml_string); + nsContentUtils::SplitExpatName(name, getter_AddRefs(prefix), + getter_AddRefs(localName), &nameSpaceID); + + nsAutoString error; + error.AppendLiteral("Ignoring element <"); + if (prefix) { + error.Append(prefix->GetUTF16String()); + error.Append(':'); + } + error.Append(localName->GetUTF16String()); + error.AppendLiteral("> created from entity value."); + + nsContentUtils::ReportToConsoleNonLocalized( + error, nsIScriptError::warningFlag, "XML Document"_ns, doc, nullptr, + u""_ns, lineNumber.unverified_safe_because(RLBOX_SAFE_PRINT), + colNumber.unverified_safe_because(RLBOX_SAFE_PRINT)); + } +} + +/* static */ +void nsExpatDriver::HandleEndElement(rlbox_sandbox_expat& aSandbox, + tainted_expat aUserData, + tainted_expat aName) { + nsExpatDriver* self = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(self); + const auto* name = aName.copy_and_verify_address(unverified_xml_string); + + NS_ASSERTION(self->mSink, "content sink not found!"); + NS_ASSERTION(self->mInternalState != NS_ERROR_HTMLPARSER_BLOCK, + "Shouldn't block from HandleStartElement."); + + if (self->mSink && self->mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { + nsresult rv = self->mSink->HandleEndElement(name); + --self->mTagDepth; + self->MaybeStopParser(rv); + } +} + +/* static */ +void nsExpatDriver::HandleEndElementForSystemPrincipal( + rlbox_sandbox_expat& aSandbox, tainted_expat aUserData, + tainted_expat aName) { + nsExpatDriver* self = static_cast(aSandbox.sandbox_storage); + MOZ_ASSERT(self); + if (!RLBOX_EXPAT_SAFE_CALL(MOZ_XML_ProcessingEntityValue, + safe_unverified)) { + HandleEndElement(aSandbox, aUserData, aName); + } +} + +nsresult nsExpatDriver::HandleCharacterData(const char16_t* aValue, + const uint32_t aLength) { + NS_ASSERTION(mSink, "content sink not found!"); + + if (mInCData) { + if (!mCDataText.Append(aValue, aLength, fallible)) { + MaybeStopParser(NS_ERROR_OUT_OF_MEMORY); + } + } else if (mSink) { + nsresult rv = mSink->HandleCharacterData(aValue, aLength); + MaybeStopParser(rv); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleComment(const char16_t* aValue) { + NS_ASSERTION(mSink, "content sink not found!"); + + if (mInExternalDTD) { + // Ignore comments from external DTDs + return NS_OK; + } + + if (mInInternalSubset) { + mInternalSubset.AppendLiteral(""); + } else if (mSink) { + nsresult rv = mSink->HandleComment(aValue); + MaybeStopParser(rv); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleProcessingInstruction(const char16_t* aTarget, + const char16_t* aData) { + NS_ASSERTION(mSink, "content sink not found!"); + + if (mInExternalDTD) { + // Ignore PIs in external DTDs for now. Eventually we want to + // pass them to the sink in a way that doesn't put them in the DOM + return NS_OK; + } + + if (mInInternalSubset) { + mInternalSubset.AppendLiteral(""); + } else if (mSink) { + nsresult rv = mSink->HandleProcessingInstruction(aTarget, aData); + MaybeStopParser(rv); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleXMLDeclaration(const char16_t* aVersion, + const char16_t* aEncoding, + int32_t aStandalone) { + if (mSink) { + nsresult rv = mSink->HandleXMLDeclaration(aVersion, aEncoding, aStandalone); + MaybeStopParser(rv); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleDefault(const char16_t* aValue, + const uint32_t aLength) { + NS_ASSERTION(mSink, "content sink not found!"); + + if (mInExternalDTD) { + // Ignore newlines in external DTDs + return NS_OK; + } + + if (mInInternalSubset) { + mInternalSubset.Append(aValue, aLength); + } else if (mSink) { + uint32_t i; + nsresult rv = mInternalState; + for (i = 0; i < aLength && NS_SUCCEEDED(rv); ++i) { + if (aValue[i] == '\n' || aValue[i] == '\r') { + rv = mSink->HandleCharacterData(&aValue[i], 1); + } + } + MaybeStopParser(rv); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleStartCdataSection() { + mInCData = true; + + return NS_OK; +} + +nsresult nsExpatDriver::HandleEndCdataSection() { + NS_ASSERTION(mSink, "content sink not found!"); + + mInCData = false; + if (mSink) { + nsresult rv = + mSink->HandleCDataSection(mCDataText.get(), mCDataText.Length()); + MaybeStopParser(rv); + } + mCDataText.Truncate(); + + return NS_OK; +} + +nsresult nsExpatDriver::HandleStartDoctypeDecl(const char16_t* aDoctypeName, + const char16_t* aSysid, + const char16_t* aPubid, + bool aHasInternalSubset) { + mDoctypeName = aDoctypeName; + mSystemID = aSysid; + mPublicID = aPubid; + + if (aHasInternalSubset) { + // Consuming a huge internal subset translates to numerous + // allocations. In an effort to avoid too many allocations + // setting mInternalSubset's capacity to be 1K ( just a guesstimate! ). + mInInternalSubset = true; + mInternalSubset.SetCapacity(1024); + } else { + // Distinguish missing internal subset from an empty one + mInternalSubset.SetIsVoid(true); + } + + return NS_OK; +} + +nsresult nsExpatDriver::HandleEndDoctypeDecl() { + NS_ASSERTION(mSink, "content sink not found!"); + + mInInternalSubset = false; + + if (mSink) { + // let the sink know any additional knowledge that we have about the + // document (currently, from bug 124570, we only expect to pass additional + // agent sheets needed to layout the XML vocabulary of the document) + nsCOMPtr data; +#if 0 + if (mCatalogData && mCatalogData->mAgentSheet) { + NS_NewURI(getter_AddRefs(data), mCatalogData->mAgentSheet); + } +#endif + + // The unused support for "catalog style sheets" was removed. It doesn't + // look like we'll ever fix bug 98413 either. + MOZ_ASSERT(!mCatalogData || !mCatalogData->mAgentSheet, + "Need to add back support for catalog style sheets"); + + // Note: mInternalSubset already doesn't include the [] around it. + nsresult rv = mSink->HandleDoctypeDecl(mInternalSubset, mDoctypeName, + mSystemID, mPublicID, data); + MaybeStopParser(rv); + } + + mInternalSubset.Truncate(); + + return NS_OK; +} + +// Wrapper class for passing the sandbox data and parser as a closure to +// ExternalDTDStreamReaderFunc. +class RLBoxExpatClosure { + public: + RLBoxExpatClosure(RLBoxExpatSandboxData* aSbxData, + tainted_expat aExpatParser) + : mSbxData(aSbxData), mExpatParser(aExpatParser){}; + inline rlbox_sandbox_expat* Sandbox() const { return mSbxData->Sandbox(); }; + inline tainted_expat Parser() const { return mExpatParser; }; + + private: + RLBoxExpatSandboxData* mSbxData; + tainted_expat mExpatParser; +}; + +static nsresult ExternalDTDStreamReaderFunc(nsIUnicharInputStream* aIn, + void* aClosure, + const char16_t* aFromSegment, + uint32_t aToOffset, uint32_t aCount, + uint32_t* aWriteCount) { + MOZ_ASSERT(aClosure && aFromSegment && aWriteCount); + + *aWriteCount = 0; + + // Get sandbox and parser + auto* closure = reinterpret_cast(aClosure); + MOZ_ASSERT(closure); + + // Transfer segment into the sandbox + auto fromSegment = + TransferBuffer(closure->Sandbox(), aFromSegment, aCount); + NS_ENSURE_TRUE(*fromSegment, NS_ERROR_OUT_OF_MEMORY); + + // Pass the buffer to expat for parsing. + if (closure->Sandbox() + ->invoke_sandbox_function( + MOZ_XML_Parse, closure->Parser(), + rlbox::sandbox_reinterpret_cast(*fromSegment), + aCount * sizeof(char16_t), 0) + .copy_and_verify(status_verifier) == XML_STATUS_OK) { + *aWriteCount = aCount; + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +int nsExpatDriver::HandleExternalEntityRef(const char16_t* openEntityNames, + const char16_t* base, + const char16_t* systemId, + const char16_t* publicId) { + if (mInInternalSubset && !mInExternalDTD && openEntityNames) { + mInternalSubset.Append(char16_t('%')); + mInternalSubset.Append(nsDependentString(openEntityNames)); + mInternalSubset.Append(char16_t(';')); + } + + nsCOMPtr baseURI = GetBaseURI(base); + NS_ENSURE_TRUE(baseURI, 1); + + // Load the external entity into a buffer. + nsCOMPtr in; + nsCOMPtr absURI; + nsresult rv = OpenInputStreamFromExternalDTD( + publicId, systemId, baseURI, getter_AddRefs(in), getter_AddRefs(absURI)); + if (NS_FAILED(rv)) { +#ifdef DEBUG + nsCString message("Failed to open external DTD: publicId \""); + AppendUTF16toUTF8(MakeStringSpan(publicId), message); + message += "\" systemId \""; + AppendUTF16toUTF8(MakeStringSpan(systemId), message); + message += "\" base \""; + message.Append(baseURI->GetSpecOrDefault()); + message += "\" URL \""; + if (absURI) { + message.Append(absURI->GetSpecOrDefault()); + } + message += "\""; + NS_WARNING(message.get()); +#endif + return 1; + } + + nsCOMPtr uniIn; + rv = NS_NewUnicharInputStream(in, getter_AddRefs(uniIn)); + NS_ENSURE_SUCCESS(rv, 1); + + int result = 1; + if (uniIn) { + auto utf16 = TransferBuffer( + Sandbox(), kUTF16, nsCharTraits::length(kUTF16) + 1); + NS_ENSURE_TRUE(*utf16, 1); + tainted_expat entParser; + entParser = + RLBOX_EXPAT_MCALL(MOZ_XML_ExternalEntityParserCreate, nullptr, *utf16); + if (entParser) { + auto baseURI = GetExpatBaseURI(absURI); + auto url = TransferBuffer(Sandbox(), &baseURI[0], + ArrayLength(baseURI)); + NS_ENSURE_TRUE(*url, 1); + Sandbox()->invoke_sandbox_function(MOZ_XML_SetBase, entParser, *url); + + mInExternalDTD = true; + + bool inParser = mInParser; // Save in-parser status + mInParser = true; + + RLBoxExpatClosure closure(SandboxData(), entParser); + uint32_t totalRead; + do { + rv = uniIn->ReadSegments(ExternalDTDStreamReaderFunc, &closure, + uint32_t(-1), &totalRead); + } while (NS_SUCCEEDED(rv) && totalRead > 0); + + result = + Sandbox() + ->invoke_sandbox_function(MOZ_XML_Parse, entParser, nullptr, 0, 1) + .copy_and_verify(status_verifier); + + mInParser = inParser; // Restore in-parser status + mInExternalDTD = false; + + Sandbox()->invoke_sandbox_function(MOZ_XML_ParserFree, entParser); + } + } + + return result; +} + +nsresult nsExpatDriver::OpenInputStreamFromExternalDTD(const char16_t* aFPIStr, + const char16_t* aURLStr, + nsIURI* aBaseURI, + nsIInputStream** aStream, + nsIURI** aAbsURI) { + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURLStr), + nullptr, aBaseURI); + // Even if the URI is malformed (most likely because we have a + // non-hierarchical base URI and a relative DTD URI, with the latter + // being the normal XHTML DTD case), we can try to see whether we + // have catalog data for aFPIStr. + if (NS_WARN_IF(NS_FAILED(rv) && rv != NS_ERROR_MALFORMED_URI)) { + return rv; + } + + // make sure the URI, if we have one, is allowed to be loaded in sync + bool isUIResource = false; + if (uri) { + rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE, + &isUIResource); + NS_ENSURE_SUCCESS(rv, rv); + } + + nsCOMPtr localURI; + if (!isUIResource) { + // Check to see if we can map the DTD to a known local DTD, or if a DTD + // file of the same name exists in the special DTD directory + if (aFPIStr) { + // see if the Formal Public Identifier (FPI) maps to a catalog entry + mCatalogData = LookupCatalogData(aFPIStr); + GetLocalDTDURI(mCatalogData, uri, getter_AddRefs(localURI)); + } + if (!localURI) { + return NS_ERROR_NOT_IMPLEMENTED; + } + } + + nsCOMPtr channel; + if (localURI) { + localURI.swap(uri); + rv = NS_NewChannel(getter_AddRefs(channel), uri, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_DTD); + NS_ENSURE_SUCCESS(rv, rv); + } else { + NS_ASSERTION( + mSink == nsCOMPtr(do_QueryInterface(mOriginalSink)), + "In nsExpatDriver::OpenInputStreamFromExternalDTD: " + "mOriginalSink not the same object as mSink?"); + nsContentPolicyType policyType = nsIContentPolicy::TYPE_INTERNAL_DTD; + if (mOriginalSink) { + nsCOMPtr doc; + doc = do_QueryInterface(mOriginalSink->GetTarget()); + if (doc) { + if (doc->SkipDTDSecurityChecks()) { + policyType = nsIContentPolicy::TYPE_INTERNAL_FORCE_ALLOWED_DTD; + } + rv = NS_NewChannel( + getter_AddRefs(channel), uri, doc, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT | + nsILoadInfo::SEC_ALLOW_CHROME, + policyType); + NS_ENSURE_SUCCESS(rv, rv); + } + } + if (!channel) { + nsCOMPtr nullPrincipal = + mozilla::NullPrincipal::CreateWithoutOriginAttributes(); + rv = NS_NewChannel( + getter_AddRefs(channel), uri, nullPrincipal, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT | + nsILoadInfo::SEC_ALLOW_CHROME, + policyType); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + uri.forget(aAbsURI); + + channel->SetContentType("application/xml"_ns); + return channel->Open(aStream); +} + +static nsresult CreateErrorText(const char16_t* aDescription, + const char16_t* aSourceURL, + tainted_expat aLineNumber, + tainted_expat aColNumber, + nsString& aErrorString, bool spoofEnglish) { + aErrorString.Truncate(); + + nsAutoString msg; + nsresult rv = nsParserMsgUtils::GetLocalizedStringByName( + spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES, + "XMLParsingError", msg); + NS_ENSURE_SUCCESS(rv, rv); + + // XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$u, Column %4$u: + nsTextFormatter::ssprintf( + aErrorString, msg.get(), aDescription, aSourceURL, + aLineNumber.unverified_safe_because(RLBOX_SAFE_PRINT), + aColNumber.unverified_safe_because(RLBOX_SAFE_PRINT)); + return NS_OK; +} + +static nsresult AppendErrorPointer(tainted_expat aColNumber, + const char16_t* aSourceLine, + size_t aSourceLineLength, + nsString& aSourceString) { + aSourceString.Append(char16_t('\n')); + + MOZ_RELEASE_ASSERT_TAINTED(aColNumber != static_cast(0), + "Unexpected value of column"); + + // Last character will be '^'. + XML_Size last = + (aColNumber - 1).copy_and_verify([&](XML_Size val) -> XML_Size { + if (val > aSourceLineLength) { + // Unexpected value of last column, just return a safe value + return 0; + } + return val; + }); + + XML_Size i; + uint32_t minuses = 0; + for (i = 0; i < last; ++i) { + if (aSourceLine[i] == '\t') { + // Since this uses |white-space: pre;| a tab stop equals 8 spaces. + uint32_t add = 8 - (minuses % 8); + aSourceString.AppendASCII("--------", add); + minuses += add; + } else { + aSourceString.Append(char16_t('-')); + ++minuses; + } + } + aSourceString.Append(char16_t('^')); + + return NS_OK; +} + +nsresult nsExpatDriver::HandleError() { + int32_t code = + RLBOX_EXPAT_MCALL(MOZ_XML_GetErrorCode).copy_and_verify(error_verifier); + + // Map Expat error code to an error string + // XXX Deal with error returns. + nsAutoString description; + nsCOMPtr doc; + if (mOriginalSink) { + doc = do_QueryInterface(mOriginalSink->GetTarget()); + } + + bool spoofEnglish = + nsContentUtils::SpoofLocaleEnglish() && (!doc || !doc->AllowsL10n()); + nsParserMsgUtils::GetLocalizedStringByID( + spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES, code, + description); + + if (code == XML_ERROR_TAG_MISMATCH) { + /** + * Expat can send the following: + * localName + * namespaceURIlocalName + * namespaceURIlocalNameprefix + * + * and we use 0xFFFF for the . + * + */ + + const char16_t* mismatch = + RLBOX_EXPAT_MCALL(MOZ_XML_GetMismatchedTag) + .copy_and_verify_address(unverified_xml_string); + const char16_t* uriEnd = nullptr; + const char16_t* nameEnd = nullptr; + const char16_t* pos; + for (pos = mismatch; *pos; ++pos) { + if (*pos == kExpatSeparatorChar) { + if (uriEnd) { + nameEnd = pos; + } else { + uriEnd = pos; + } + } + } + + nsAutoString tagName; + if (uriEnd && nameEnd) { + // We have a prefix. + tagName.Append(nameEnd + 1, pos - nameEnd - 1); + tagName.Append(char16_t(':')); + } + const char16_t* nameStart = uriEnd ? uriEnd + 1 : mismatch; + tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart); + + nsAutoString msg; + nsParserMsgUtils::GetLocalizedStringByName( + spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES, + "Expected", msg); + + // . Expected: . + nsAutoString message; + nsTextFormatter::ssprintf(message, msg.get(), tagName.get()); + description.Append(message); + } + + // Adjust the column number so that it is one based rather than zero based. + tainted_expat colNumber = + RLBOX_EXPAT_MCALL(MOZ_XML_GetCurrentColumnNumber) + 1; + tainted_expat lineNumber = + RLBOX_EXPAT_MCALL(MOZ_XML_GetCurrentLineNumber); + + // Copy out the two character bufer that holds the expatBase + const std::unique_ptr expatBase = + RLBOX_EXPAT_MCALL(MOZ_XML_GetBase) + .copy_and_verify_range( + [](std::unique_ptr val) { + // No additional checks needed as this is sent to GetBaseURI + // which checks its inputs + return val; + }, + ExpatBaseURI::Length); + nsAutoString uri; + nsCOMPtr baseURI; + if (expatBase && (baseURI = GetBaseURI(expatBase.get()))) { + // Let's ignore if this fails, we're already reporting a parse error. + Unused << CopyUTF8toUTF16(baseURI->GetSpecOrDefault(), uri, fallible); + } + nsAutoString errorText; + CreateErrorText(description.get(), uri.get(), lineNumber, colNumber, + errorText, spoofEnglish); + + nsAutoString sourceText(mLastLine); + AppendErrorPointer(colNumber, mLastLine.get(), mLastLine.Length(), + sourceText); + + if (doc && nsContentUtils::IsChromeDoc(doc)) { + nsCString path = doc->GetDocumentURI()->GetSpecOrDefault(); + nsCOMPtr container = doc->GetContainer(); + nsCOMPtr docShell = do_QueryInterface(container); + nsCString docShellDestroyed("unknown"_ns); + if (docShell) { + bool destroyed = false; + docShell->IsBeingDestroyed(&destroyed); + docShellDestroyed.Assign(destroyed ? "true"_ns : "false"_ns); + } + + mozilla::Maybe> extra = + mozilla::Some>({ + mozilla::Telemetry::EventExtraEntry{"error_code"_ns, + nsPrintfCString("%u", code)}, + mozilla::Telemetry::EventExtraEntry{ + "location"_ns, + nsPrintfCString( + "%lu:%lu", + lineNumber.unverified_safe_because(RLBOX_SAFE_PRINT), + colNumber.unverified_safe_because(RLBOX_SAFE_PRINT))}, + mozilla::Telemetry::EventExtraEntry{ + "last_line"_ns, NS_ConvertUTF16toUTF8(mLastLine)}, + mozilla::Telemetry::EventExtraEntry{ + "last_line_len"_ns, nsPrintfCString("%zu", mLastLine.Length())}, + mozilla::Telemetry::EventExtraEntry{ + "hidden"_ns, doc->Hidden() ? "true"_ns : "false"_ns}, + mozilla::Telemetry::EventExtraEntry{"destroyed"_ns, + docShellDestroyed}, + }); + + mozilla::Telemetry::SetEventRecordingEnabled("ysod"_ns, true); + mozilla::Telemetry::RecordEvent( + mozilla::Telemetry::EventID::Ysod_Shown_Ysod, mozilla::Some(path), + extra); + } + + // Try to create and initialize the script error. + nsCOMPtr serr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); + nsresult rv = NS_ERROR_FAILURE; + if (serr) { + rv = serr->InitWithSourceURI( + errorText, mURIs.SafeElementAt(0), mLastLine, + lineNumber.unverified_safe_because(RLBOX_SAFE_PRINT), + colNumber.unverified_safe_because(RLBOX_SAFE_PRINT), + nsIScriptError::errorFlag, "malformed-xml", mInnerWindowID); + } + + // If it didn't initialize, we can't do any logging. + bool shouldReportError = NS_SUCCEEDED(rv); + + // mSink might be null here if our parser was terminated. + if (mSink && shouldReportError) { + rv = mSink->ReportError(errorText.get(), sourceText.get(), serr, + &shouldReportError); + if (NS_FAILED(rv)) { + shouldReportError = true; + } + } + + // mOriginalSink might be null here if our parser was terminated. + if (mOriginalSink) { + nsCOMPtr doc = do_QueryInterface(mOriginalSink->GetTarget()); + if (doc && doc->SuppressParserErrorConsoleMessages()) { + shouldReportError = false; + } + } + + if (shouldReportError) { + nsCOMPtr cs(do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + if (cs) { + cs->LogMessage(serr); + } + } + + return NS_ERROR_HTMLPARSER_STOPPARSING; +} + +// Because we need to allocate a buffer in the RLBOX sandbox, and copy the data +// to it for Expat to parse, we are limited in size by the memory available in +// the RLBOX sandbox. nsExpatDriver::ChunkAndParseBuffer divides the buffer into +// chunks of sMaxChunkLength characters or less, and passes them to +// nsExpatDriver::ParseBuffer. That should ensure that we almost never run out +// of memory in the sandbox. +void nsExpatDriver::ChunkAndParseBuffer(const char16_t* aBuffer, + uint32_t aLength, bool aIsFinal, + uint32_t* aPassedToExpat, + uint32_t* aConsumed, + XML_Size* aLastLineLength) { + *aConsumed = 0; + *aLastLineLength = 0; + + uint32_t remainder = aLength; + while (remainder > sMaxChunkLength) { + ParseChunk(aBuffer, sMaxChunkLength, ChunkOrBufferIsFinal::None, aConsumed, + aLastLineLength); + aBuffer += sMaxChunkLength; + remainder -= sMaxChunkLength; + if (NS_FAILED(mInternalState)) { + // Stop parsing if there's an error (including if we're blocked or + // interrupted). + *aPassedToExpat = aLength - remainder; + return; + } + } + + ParseChunk(aBuffer, remainder, + aIsFinal ? ChunkOrBufferIsFinal::FinalChunkAndBuffer + : ChunkOrBufferIsFinal::FinalChunk, + aConsumed, aLastLineLength); + *aPassedToExpat = aLength; +} + +void nsExpatDriver::ParseChunk(const char16_t* aBuffer, uint32_t aLength, + ChunkOrBufferIsFinal aIsFinal, + uint32_t* aConsumed, XML_Size* aLastLineLength) { + NS_ASSERTION((aBuffer && aLength != 0) || (!aBuffer && aLength == 0), "?"); + NS_ASSERTION(mInternalState != NS_OK || + (aIsFinal == ChunkOrBufferIsFinal::FinalChunkAndBuffer) || + aBuffer, + "Useless call, we won't call Expat"); + MOZ_ASSERT(!BlockedOrInterrupted() || !aBuffer, + "Non-null buffer when resuming"); + MOZ_ASSERT(mExpatParser); + + auto parserBytesBefore_verifier = [&](auto parserBytesBefore) { + MOZ_RELEASE_ASSERT(parserBytesBefore >= 0, "Unexpected value"); + MOZ_RELEASE_ASSERT(parserBytesBefore % sizeof(char16_t) == 0, + "Consumed part of a char16_t?"); + return parserBytesBefore; + }; + int32_t parserBytesBefore = RLBOX_EXPAT_SAFE_MCALL( + XML_GetCurrentByteIndex, parserBytesBefore_verifier); + + if (mInternalState != NS_OK && !BlockedOrInterrupted()) { + return; + } + + XML_Status status; + bool inParser = mInParser; // Save in-parser status + mInParser = true; + Maybe> buffer; + if (BlockedOrInterrupted()) { + mInternalState = NS_OK; // Resume in case we're blocked. + status = RLBOX_EXPAT_SAFE_MCALL(MOZ_XML_ResumeParser, status_verifier); + } else { + buffer.emplace(Sandbox(), aBuffer, aLength); + MOZ_RELEASE_ASSERT(!aBuffer || !!*buffer.ref(), + "Chunking should avoid OOM in ParseBuffer"); + + status = RLBOX_EXPAT_SAFE_MCALL( + MOZ_XML_Parse, status_verifier, + rlbox::sandbox_reinterpret_cast(*buffer.ref()), + aLength * sizeof(char16_t), + aIsFinal == ChunkOrBufferIsFinal::FinalChunkAndBuffer); + } + mInParser = inParser; // Restore in-parser status + + auto parserBytesConsumed_verifier = [&](auto parserBytesConsumed) { + MOZ_RELEASE_ASSERT(parserBytesConsumed >= 0, "Unexpected value"); + MOZ_RELEASE_ASSERT(parserBytesConsumed >= parserBytesBefore, + "How'd this happen?"); + MOZ_RELEASE_ASSERT(parserBytesConsumed % sizeof(char16_t) == 0, + "Consumed part of a char16_t?"); + return parserBytesConsumed; + }; + int32_t parserBytesConsumed = RLBOX_EXPAT_SAFE_MCALL( + XML_GetCurrentByteIndex, parserBytesConsumed_verifier); + + // Consumed something. + *aConsumed += (parserBytesConsumed - parserBytesBefore) / sizeof(char16_t); + + NS_ASSERTION(status != XML_STATUS_SUSPENDED || BlockedOrInterrupted(), + "Inconsistent expat suspension state."); + + if (status == XML_STATUS_ERROR) { + mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING; + } + + if (*aConsumed > 0 && + (aIsFinal != ChunkOrBufferIsFinal::None || NS_FAILED(mInternalState))) { + *aLastLineLength = RLBOX_EXPAT_SAFE_MCALL(MOZ_XML_GetCurrentColumnNumber, + safe_unverified); + } +} + +nsresult nsExpatDriver::ResumeParse(nsScanner& aScanner, bool aIsFinalChunk) { + // We keep the scanner pointing to the position where Expat will start + // parsing. + nsScannerIterator currentExpatPosition; + aScanner.CurrentPosition(currentExpatPosition); + + // This is the start of the first buffer that we need to pass to Expat. + nsScannerIterator start = currentExpatPosition; + start.advance(mExpatBuffered); + + // This is the end of the last buffer (at this point, more data could come in + // later). + nsScannerIterator end; + aScanner.EndReading(end); + + MOZ_LOG(gExpatDriverLog, LogLevel::Debug, + ("Remaining in expat's buffer: %i, remaining in scanner: %zu.", + mExpatBuffered, Distance(start, end))); + + // We want to call Expat if we have more buffers, or if we know there won't + // be more buffers (and so we want to flush the remaining data), or if we're + // currently blocked and there's data in Expat's buffer. + while (start != end || (aIsFinalChunk && !mMadeFinalCallToExpat) || + (BlockedOrInterrupted() && mExpatBuffered > 0)) { + bool noMoreBuffers = start == end && aIsFinalChunk; + bool blocked = BlockedOrInterrupted(); + + const char16_t* buffer; + uint32_t length; + if (blocked || noMoreBuffers) { + // If we're blocked we just resume Expat so we don't need a buffer, if + // there aren't any more buffers we pass a null buffer to Expat. + buffer = nullptr; + length = 0; + + if (blocked) { + MOZ_LOG( + gExpatDriverLog, LogLevel::Debug, + ("Resuming Expat, will parse data remaining in Expat's " + "buffer.\nContent of Expat's buffer:\n-----\n%s\n-----\n", + NS_ConvertUTF16toUTF8(currentExpatPosition.get(), mExpatBuffered) + .get())); + } else { + NS_ASSERTION(mExpatBuffered == Distance(currentExpatPosition, end), + "Didn't pass all the data to Expat?"); + MOZ_LOG( + gExpatDriverLog, LogLevel::Debug, + ("Last call to Expat, will parse data remaining in Expat's " + "buffer.\nContent of Expat's buffer:\n-----\n%s\n-----\n", + NS_ConvertUTF16toUTF8(currentExpatPosition.get(), mExpatBuffered) + .get())); + } + } else { + buffer = start.get(); + length = uint32_t(start.size_forward()); + + MOZ_LOG(gExpatDriverLog, LogLevel::Debug, + ("Calling Expat, will parse data remaining in Expat's buffer and " + "new data.\nContent of Expat's buffer:\n-----\n%s\n-----\nNew " + "data:\n-----\n%s\n-----\n", + NS_ConvertUTF16toUTF8(currentExpatPosition.get(), mExpatBuffered) + .get(), + NS_ConvertUTF16toUTF8(start.get(), length).get())); + } + + uint32_t passedToExpat; + uint32_t consumed; + XML_Size lastLineLength; + ChunkAndParseBuffer(buffer, length, noMoreBuffers, &passedToExpat, + &consumed, &lastLineLength); + MOZ_ASSERT_IF(passedToExpat != length, NS_FAILED(mInternalState)); + MOZ_ASSERT(consumed <= passedToExpat + mExpatBuffered); + if (consumed > 0) { + nsScannerIterator oldExpatPosition = currentExpatPosition; + currentExpatPosition.advance(consumed); + + // We consumed some data, we want to store the last line of data that + // was consumed in case we run into an error (to show the line in which + // the error occurred). + + if (lastLineLength <= consumed) { + // The length of the last line was less than what expat consumed, so + // there was at least one line break in the consumed data. Store the + // last line until the point where we stopped parsing. + nsScannerIterator startLastLine = currentExpatPosition; + startLastLine.advance(-((ptrdiff_t)lastLineLength)); + if (!CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine)) { + return (mInternalState = NS_ERROR_OUT_OF_MEMORY); + } + } else { + // There was no line break in the consumed data, append the consumed + // data. + if (!AppendUnicodeTo(oldExpatPosition, currentExpatPosition, + mLastLine)) { + return (mInternalState = NS_ERROR_OUT_OF_MEMORY); + } + } + } + + mExpatBuffered += passedToExpat - consumed; + + if (BlockedOrInterrupted()) { + MOZ_LOG(gExpatDriverLog, LogLevel::Debug, + ("Blocked or interrupted parser (probably for loading linked " + "stylesheets or scripts).")); + + aScanner.SetPosition(currentExpatPosition, true); + aScanner.Mark(); + + return mInternalState; + } + + if (noMoreBuffers && mExpatBuffered == 0) { + mMadeFinalCallToExpat = true; + } + + if (NS_FAILED(mInternalState)) { + if (RLBOX_EXPAT_SAFE_MCALL(MOZ_XML_GetErrorCode, error_verifier) != + XML_ERROR_NONE) { + NS_ASSERTION(mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING, + "Unexpected error"); + + // Look for the next newline after the last one we consumed + nsScannerIterator lastLine = currentExpatPosition; + while (lastLine != end) { + length = uint32_t(lastLine.size_forward()); + uint32_t endOffset = 0; + const char16_t* buffer = lastLine.get(); + while (endOffset < length && buffer[endOffset] != '\n' && + buffer[endOffset] != '\r') { + ++endOffset; + } + mLastLine.Append(Substring(buffer, buffer + endOffset)); + if (endOffset < length) { + // We found a newline. + break; + } + + lastLine.advance(length); + } + + HandleError(); + } + + return mInternalState; + } + + // Either we have more buffers, or we were blocked (and we'll flush in the + // next iteration), or we should have emptied Expat's buffer. + NS_ASSERTION(!noMoreBuffers || blocked || + (mExpatBuffered == 0 && currentExpatPosition == end), + "Unreachable data left in Expat's buffer"); + + start.advance(length); + + // It's possible for start to have passed end if we received more data + // (e.g. if we spun the event loop in an inline script). Reload end now + // to compensate. + aScanner.EndReading(end); + } + + aScanner.SetPosition(currentExpatPosition, true); + aScanner.Mark(); + + MOZ_LOG(gExpatDriverLog, LogLevel::Debug, + ("Remaining in expat's buffer: %i, remaining in scanner: %zu.", + mExpatBuffered, Distance(currentExpatPosition, end))); + + return NS_SUCCEEDED(mInternalState) ? NS_ERROR_HTMLPARSER_EOF : NS_OK; +} + +mozilla::UniquePtr +RLBoxExpatSandboxPool::CreateSandboxData(uint64_t aSize) { + // Create expat sandbox + auto sandbox = mozilla::MakeUnique(); + +#ifdef MOZ_WASM_SANDBOXING_EXPAT + const w2c_mem_capacity capacity = + get_valid_wasm2c_memory_capacity(aSize, true /* 32-bit wasm memory*/); + bool create_ok = sandbox->create_sandbox(/* infallible = */ false, &capacity); +#else + bool create_ok = sandbox->create_sandbox(); +#endif + + NS_ENSURE_TRUE(create_ok, nullptr); + + mozilla::UniquePtr sbxData = + mozilla::MakeUnique(aSize); + + // Register callbacks common to both system and non-system principals + sbxData->mHandleXMLDeclaration = + sandbox->register_callback(Driver_HandleXMLDeclaration); + sbxData->mHandleCharacterData = + sandbox->register_callback(Driver_HandleCharacterData); + sbxData->mHandleProcessingInstruction = + sandbox->register_callback(Driver_HandleProcessingInstruction); + sbxData->mHandleDefault = sandbox->register_callback(Driver_HandleDefault); + sbxData->mHandleExternalEntityRef = + sandbox->register_callback(Driver_HandleExternalEntityRef); + sbxData->mHandleComment = sandbox->register_callback(Driver_HandleComment); + sbxData->mHandleStartCdataSection = + sandbox->register_callback(Driver_HandleStartCdataSection); + sbxData->mHandleEndCdataSection = + sandbox->register_callback(Driver_HandleEndCdataSection); + sbxData->mHandleStartDoctypeDecl = + sandbox->register_callback(Driver_HandleStartDoctypeDecl); + sbxData->mHandleEndDoctypeDecl = + sandbox->register_callback(Driver_HandleEndDoctypeDecl); + + sbxData->mSandbox = std::move(sandbox); + + return sbxData; +} + +mozilla::StaticRefPtr RLBoxExpatSandboxPool::sSingleton; + +void RLBoxExpatSandboxPool::Initialize(size_t aDelaySeconds) { + mozilla::AssertIsOnMainThread(); + RLBoxExpatSandboxPool::sSingleton = new RLBoxExpatSandboxPool(aDelaySeconds); + ClearOnShutdown(&RLBoxExpatSandboxPool::sSingleton); +} + +void RLBoxExpatSandboxData::AttachDriver(bool aIsSystemPrincipal, + void* aDriver) { + MOZ_ASSERT(!mSandbox->sandbox_storage); + MOZ_ASSERT(mHandleStartElement.is_unregistered()); + MOZ_ASSERT(mHandleEndElement.is_unregistered()); + + if (aIsSystemPrincipal) { + mHandleStartElement = mSandbox->register_callback( + nsExpatDriver::HandleStartElementForSystemPrincipal); + mHandleEndElement = mSandbox->register_callback( + nsExpatDriver::HandleEndElementForSystemPrincipal); + } else { + mHandleStartElement = + mSandbox->register_callback(nsExpatDriver::HandleStartElement); + mHandleEndElement = + mSandbox->register_callback(nsExpatDriver::HandleEndElement); + } + + mSandbox->sandbox_storage = aDriver; +} + +void RLBoxExpatSandboxData::DetachDriver() { + mSandbox->sandbox_storage = nullptr; + mHandleStartElement.unregister(); + mHandleEndElement.unregister(); +} + +RLBoxExpatSandboxData::~RLBoxExpatSandboxData() { + MOZ_ASSERT(mSandbox); + + // DetachDriver should always be called before a sandbox goes back into the + // pool, and thus before it's freed. + MOZ_ASSERT(!mSandbox->sandbox_storage); + MOZ_ASSERT(mHandleStartElement.is_unregistered()); + MOZ_ASSERT(mHandleEndElement.is_unregistered()); + + // Unregister callbacks + mHandleXMLDeclaration.unregister(); + mHandleCharacterData.unregister(); + mHandleProcessingInstruction.unregister(); + mHandleDefault.unregister(); + mHandleExternalEntityRef.unregister(); + mHandleComment.unregister(); + mHandleStartCdataSection.unregister(); + mHandleEndCdataSection.unregister(); + mHandleStartDoctypeDecl.unregister(); + mHandleEndDoctypeDecl.unregister(); + // Destroy sandbox + mSandbox->destroy_sandbox(); + MOZ_COUNT_DTOR(RLBoxExpatSandboxData); +} + +nsresult nsExpatDriver::Initialize(nsIURI* aURI, nsIContentSink* aSink) { + mSink = do_QueryInterface(aSink); + if (!mSink) { + NS_ERROR("nsExpatDriver didn't get an nsIExpatSink"); + // Make sure future calls to us bail out as needed + mInternalState = NS_ERROR_UNEXPECTED; + return mInternalState; + } + + mOriginalSink = aSink; + + static const char16_t kExpatSeparator[] = {kExpatSeparatorChar, '\0'}; + + // Get the doc if any + nsCOMPtr doc = do_QueryInterface(mOriginalSink->GetTarget()); + if (doc) { + nsCOMPtr win = doc->GetWindow(); + nsCOMPtr inner; + if (win) { + inner = win->GetCurrentInnerWindow(); + } else { + bool aHasHadScriptHandlingObject; + nsIScriptGlobalObject* global = + doc->GetScriptHandlingObject(aHasHadScriptHandlingObject); + if (global) { + inner = do_QueryInterface(global); + } + } + if (inner) { + mInnerWindowID = inner->WindowID(); + } + } + + // Create sandbox + // + // We have to make sure the sandbox is large enough. We unscientifically + // request two MB. Note that the parsing itself is chunked so as not to + // require a large sandbox. + static const uint64_t minSandboxSize = 2 * 1024 * 1024; + MOZ_ASSERT(!mSandboxPoolData); + mSandboxPoolData = + RLBoxExpatSandboxPool::sSingleton->PopOrCreate(minSandboxSize); + NS_ENSURE_TRUE(mSandboxPoolData, NS_ERROR_OUT_OF_MEMORY); + + MOZ_ASSERT(SandboxData()); + + SandboxData()->AttachDriver(doc && doc->NodePrincipal()->IsSystemPrincipal(), + static_cast(this)); + + // Create expat parser. + // We need to copy the encoding and namespace separator into the sandbox. + // For the noop sandbox we pass in the memsuite; for the Wasm sandbox, we + // pass in nullptr to let expat use the standard library memory suite. + auto expatSeparator = TransferBuffer( + Sandbox(), kExpatSeparator, + nsCharTraits::length(kExpatSeparator) + 1); + MOZ_RELEASE_ASSERT(*expatSeparator); + auto utf16 = TransferBuffer( + Sandbox(), kUTF16, nsCharTraits::length(kUTF16) + 1); + MOZ_RELEASE_ASSERT(*utf16); + mExpatParser = Sandbox()->invoke_sandbox_function( + MOZ_XML_ParserCreate_MM, *utf16, nullptr, *expatSeparator); + NS_ENSURE_TRUE(mExpatParser, NS_ERROR_FAILURE); + + RLBOX_EXPAT_MCALL(MOZ_XML_SetReturnNSTriplet, XML_TRUE); + +#ifdef XML_DTD + RLBOX_EXPAT_MCALL(MOZ_XML_SetParamEntityParsing, + XML_PARAM_ENTITY_PARSING_ALWAYS); +#endif + + auto baseURI = GetExpatBaseURI(aURI); + auto uri = + TransferBuffer(Sandbox(), &baseURI[0], ArrayLength(baseURI)); + RLBOX_EXPAT_MCALL(MOZ_XML_SetBase, *uri); + + // Set up the callbacks + RLBOX_EXPAT_MCALL(MOZ_XML_SetXmlDeclHandler, + SandboxData()->mHandleXMLDeclaration); + RLBOX_EXPAT_MCALL(MOZ_XML_SetElementHandler, + SandboxData()->mHandleStartElement, + SandboxData()->mHandleEndElement); + RLBOX_EXPAT_MCALL(MOZ_XML_SetCharacterDataHandler, + SandboxData()->mHandleCharacterData); + RLBOX_EXPAT_MCALL(MOZ_XML_SetProcessingInstructionHandler, + SandboxData()->mHandleProcessingInstruction); + RLBOX_EXPAT_MCALL(MOZ_XML_SetDefaultHandlerExpand, + SandboxData()->mHandleDefault); + RLBOX_EXPAT_MCALL(MOZ_XML_SetExternalEntityRefHandler, + SandboxData()->mHandleExternalEntityRef); + RLBOX_EXPAT_MCALL(MOZ_XML_SetCommentHandler, SandboxData()->mHandleComment); + RLBOX_EXPAT_MCALL(MOZ_XML_SetCdataSectionHandler, + SandboxData()->mHandleStartCdataSection, + SandboxData()->mHandleEndCdataSection); + + RLBOX_EXPAT_MCALL(MOZ_XML_SetParamEntityParsing, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); + RLBOX_EXPAT_MCALL(MOZ_XML_SetDoctypeDeclHandler, + SandboxData()->mHandleStartDoctypeDecl, + SandboxData()->mHandleEndDoctypeDecl); + + return mInternalState; +} + +NS_IMETHODIMP +nsExpatDriver::BuildModel(nsIContentSink* aSink) { return mInternalState; } + +void nsExpatDriver::DidBuildModel() { + if (!mInParser) { + // Because nsExpatDriver is cycle-collected, it gets destroyed + // asynchronously. We want to eagerly release the sandbox back into the + // pool so that it can be reused immediately, unless this is a reentrant + // call (which we track with mInParser). + Destroy(); + } + mOriginalSink = nullptr; + mSink = nullptr; +} + +NS_IMETHODIMP_(void) +nsExpatDriver::Terminate() { + // XXX - not sure what happens to the unparsed data. + if (mExpatParser) { + RLBOX_EXPAT_MCALL(MOZ_XML_StopParser, XML_FALSE); + } + mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING; +} + +/*************************** Unused methods **********************************/ + +void nsExpatDriver::MaybeStopParser(nsresult aState) { + if (NS_FAILED(aState)) { + // If we had a failure we want to override NS_ERROR_HTMLPARSER_INTERRUPTED + // and we want to override NS_ERROR_HTMLPARSER_BLOCK but not with + // NS_ERROR_HTMLPARSER_INTERRUPTED. + if (NS_SUCCEEDED(mInternalState) || + mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED || + (mInternalState == NS_ERROR_HTMLPARSER_BLOCK && + aState != NS_ERROR_HTMLPARSER_INTERRUPTED)) { + mInternalState = (aState == NS_ERROR_HTMLPARSER_INTERRUPTED || + aState == NS_ERROR_HTMLPARSER_BLOCK) + ? aState + : NS_ERROR_HTMLPARSER_STOPPARSING; + } + + // If we get an error then we need to stop Expat (by calling XML_StopParser + // with false as the last argument). If the parser should be blocked or + // interrupted we need to pause Expat (by calling XML_StopParser with + // true as the last argument). + + // Note that due to Bug 1742913, we need to explicitly cast the parameter to + // an int so that the value is correctly zero extended. + int resumable = BlockedOrInterrupted(); + RLBOX_EXPAT_MCALL(MOZ_XML_StopParser, resumable); + } else if (NS_SUCCEEDED(mInternalState)) { + // Only clobber mInternalState with the success code if we didn't block or + // interrupt before. + mInternalState = aState; + } +} + +nsExpatDriver::ExpatBaseURI nsExpatDriver::GetExpatBaseURI(nsIURI* aURI) { + mURIs.AppendElement(aURI); + + MOZ_RELEASE_ASSERT(mURIs.Length() <= std::numeric_limits::max()); + + return ExpatBaseURI(static_cast(mURIs.Length()), XML_T('\0')); +} + +nsIURI* nsExpatDriver::GetBaseURI(const XML_Char* aBase) const { + MOZ_ASSERT(aBase[0] != '\0' && aBase[1] == '\0'); + + if (aBase[0] == '\0' || aBase[1] != '\0') { + return nullptr; + } + + uint32_t index = aBase[0] - 1; + MOZ_ASSERT(index < mURIs.Length()); + + return mURIs.SafeElementAt(index); +} + +inline RLBoxExpatSandboxData* nsExpatDriver::SandboxData() const { + return reinterpret_cast( + mSandboxPoolData->SandboxData()); +} + +inline rlbox_sandbox_expat* nsExpatDriver::Sandbox() const { + return SandboxData()->Sandbox(); +} diff --git a/parser/htmlparser/nsExpatDriver.h b/parser/htmlparser/nsExpatDriver.h new file mode 100644 index 0000000000..b07ba72b6b --- /dev/null +++ b/parser/htmlparser/nsExpatDriver.h @@ -0,0 +1,256 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef NS_EXPAT_DRIVER__ +#define NS_EXPAT_DRIVER__ + +#include "expat_config.h" +#include "expat.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsIDTD.h" +#include "nsIInputStream.h" +#include "nsIParser.h" +#include "nsCycleCollectionParticipant.h" +#include "nsScanner.h" + +#include "rlbox_expat.h" +#include "nsRLBoxExpatDriver.h" +#include "mozilla/UniquePtr.h" + +class nsIExpatSink; +struct nsCatalogData; +class RLBoxExpatSandboxData; +namespace mozilla { +template +class Array; +} + +class nsExpatDriver : public nsIDTD { + virtual ~nsExpatDriver(); + + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL + NS_DECL_NSIDTD + NS_DECL_CYCLE_COLLECTION_CLASS(nsExpatDriver) + + nsExpatDriver(); + + nsresult Initialize(nsIURI* aURI, nsIContentSink* aSink); + + nsresult ResumeParse(nsScanner& aScanner, bool aIsFinalChunk); + + int HandleExternalEntityRef(const char16_t* aOpenEntityNames, + const char16_t* aBase, const char16_t* aSystemId, + const char16_t* aPublicId); + static void HandleStartElement(rlbox_sandbox_expat& aSandbox, + tainted_expat aUserData, + tainted_expat aName, + tainted_expat aAtts); + static void HandleStartElementForSystemPrincipal( + rlbox_sandbox_expat& aSandbox, tainted_expat aUserData, + tainted_expat aName, + tainted_expat aAtts); + static void HandleEndElement(rlbox_sandbox_expat& aSandbox, + tainted_expat aUserData, + tainted_expat aName); + static void HandleEndElementForSystemPrincipal( + rlbox_sandbox_expat& aSandbox, tainted_expat aUserData, + tainted_expat aName); + nsresult HandleCharacterData(const char16_t* aCData, const uint32_t aLength); + nsresult HandleComment(const char16_t* aName); + nsresult HandleProcessingInstruction(const char16_t* aTarget, + const char16_t* aData); + nsresult HandleXMLDeclaration(const char16_t* aVersion, + const char16_t* aEncoding, int32_t aStandalone); + nsresult HandleDefault(const char16_t* aData, const uint32_t aLength); + nsresult HandleStartCdataSection(); + nsresult HandleEndCdataSection(); + nsresult HandleStartDoctypeDecl(const char16_t* aDoctypeName, + const char16_t* aSysid, + const char16_t* aPubid, + bool aHasInternalSubset); + nsresult HandleEndDoctypeDecl(); + + private: + // Load up an external stream to get external entity information + nsresult OpenInputStreamFromExternalDTD(const char16_t* aFPIStr, + const char16_t* aURLStr, + nsIURI* aBaseURI, + nsIInputStream** aStream, + nsIURI** aAbsURI); + + enum class ChunkOrBufferIsFinal { + None, + FinalChunk, + FinalChunkAndBuffer, + }; + + /** + * Pass a buffer to Expat. If Expat is blocked aBuffer should be null and + * aLength should be 0. The result of the call will be stored in + * mInternalState. Expat will parse as much of the buffer as it can and store + * the rest in its internal buffer. + * + * @param aBuffer the buffer to pass to Expat. May be null. + * @param aLength the length of the buffer to pass to Expat (in number of + * char16_t's). Must be 0 if aBuffer is null and > 0 if + * aBuffer is not null. + * @param aIsFinal whether this is the last chunk in a row passed to + * ParseChunk, and if so whether it's the last chunk and + * buffer passed to ParseChunk (meaning there will be no more + * calls to ParseChunk for the document being parsed). + * @param aConsumed [out] the number of PRUnichars that Expat consumed. This + * doesn't include the PRUnichars that Expat stored in + * its buffer but didn't parse yet. + * @param aLastLineLength [out] the length of the last line that Expat has + * consumed. This will only be computed if + * aIsFinal is not None or mInternalState is set + * to a failure. + */ + void ParseChunk(const char16_t* aBuffer, uint32_t aLength, + ChunkOrBufferIsFinal aIsFinal, uint32_t* aConsumed, + XML_Size* aLastLineLength); + /** + * Wrapper for ParseBuffer. If the buffer is too large to be copied into the + * sandbox all at once, splits it into chunks and invokes ParseBuffer in a + * loop. + * + * @param aBuffer the buffer to pass to Expat. May be null. + * @param aLength the length of the buffer to pass to Expat (in number of + * char16_t's). Must be 0 if aBuffer is null and > 0 if + * aBuffer is not null. + * @param aIsFinal whether there will definitely not be any more new buffers + * passed in to ParseBuffer + * @param aConsumed [out] the number of PRUnichars that Expat consumed. This + * doesn't include the PRUnichars that Expat stored in + * its buffer but didn't parse yet. + * @param aLastLineLength [out] the length of the last line that Expat has + * consumed. + */ + void ChunkAndParseBuffer(const char16_t* aBuffer, uint32_t aLength, + bool aIsFinal, uint32_t* aPassedToExpat, + uint32_t* aConsumed, XML_Size* aLastLineLength); + + nsresult HandleError(); + + void MaybeStopParser(nsresult aState); + + bool BlockedOrInterrupted() { + return mInternalState == NS_ERROR_HTMLPARSER_BLOCK || + mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED; + } + + // Expat allows us to set the base URI for entities. It doesn't use the base + // URI itself, but just passes it along to all the entity handlers (just the + // external entity reference handler for us). It does expect the base URI as a + // null-terminated string, with the same character type as the parsed buffers + // (char16_t in our case). Because nsIURI stores a UTF-8 string we have to do + // a conversion to UTF-16 for Expat. We also RLBox the Expat parser, so we + // also do 2 copies (into RLBox sandbox, and Expat does a copy into its pool). + // Most of the time this base URI is unused (the external entity handler is + // rarely called), but when it is we also convert it back to a nsIURI, so we + // convert the string back to UTF-8. + // + // We'd rather not do any of these conversions and copies, so we use a (hacky) + // workaround. We store all base URIs in an array of nsIURIs. Instead of + // passing the real URI to Expat as a string, we pass it a null-terminated + // 2-character buffer. The first character of that buffer stores the index of + // the corresponding nsIURI in the array (incremented with 1 because 0 is used + // to terminate a string). The entity handler can then use the index from the + // base URI that Expat passes it to look up the right nsIURI from the array. + // + // GetExpatBaseURI pushes the nsIURI to the array, and creates the + // two-character buffer for it. + // + // GetBaseURI looks up the right nsIURI in the array, based on the index from + // the two-character buffer. + using ExpatBaseURI = mozilla::Array; + ExpatBaseURI GetExpatBaseURI(nsIURI* aURI); + nsIURI* GetBaseURI(const XML_Char* aBase) const; + + RLBoxExpatSandboxData* SandboxData() const; + rlbox_sandbox_expat* Sandbox() const; + + // Destroy expat parser and return sandbox to pool + void Destroy(); + + mozilla::UniquePtr mSandboxPoolData; + tainted_expat mExpatParser; + + nsString mLastLine; + nsString mCDataText; + // Various parts of a doctype + nsString mDoctypeName; + nsString mSystemID; + nsString mPublicID; + nsString mInternalSubset; + bool mInCData; + bool mInInternalSubset; + bool mInExternalDTD; + bool mMadeFinalCallToExpat; + + // Used to track if we're in the parser. + bool mInParser; + + nsresult mInternalState; + + // The length of the data in Expat's buffer (in number of PRUnichars). + uint32_t mExpatBuffered; + + uint16_t mTagDepth; + + // These sinks all refer the same conceptual object. mOriginalSink is + // identical with the nsIContentSink* passed to WillBuildModel, and exists + // only to avoid QI-ing back to nsIContentSink*. + nsCOMPtr mOriginalSink; + nsCOMPtr mSink; + + const nsCatalogData* mCatalogData; // weak + nsTArray> mURIs; + + // Used for error reporting. + uint64_t mInnerWindowID; +}; + +class RLBoxExpatSandboxData : public mozilla::RLBoxSandboxDataBase { + friend class RLBoxExpatSandboxPool; + friend class nsExpatDriver; + + public: + explicit RLBoxExpatSandboxData(uint64_t aSize) + : mozilla::RLBoxSandboxDataBase(aSize) { + MOZ_COUNT_CTOR(RLBoxExpatSandboxData); + } + ~RLBoxExpatSandboxData(); + rlbox_sandbox_expat* Sandbox() const { return mSandbox.get(); } + // After getting a sandbox from the pool we need to register the + // Handle{Start,End}Element callbacks and associate the driver with the + // sandbox. + void AttachDriver(bool IsSystemPrincipal, void* aDriver); + void DetachDriver(); + + private: + mozilla::UniquePtr mSandbox; + // Common expat callbacks that persist across calls to {Attach,Detach}Driver, + // and consequently across sandbox reuses. + sandbox_callback_expat mHandleXMLDeclaration; + sandbox_callback_expat mHandleCharacterData; + sandbox_callback_expat + mHandleProcessingInstruction; + sandbox_callback_expat mHandleDefault; + sandbox_callback_expat mHandleExternalEntityRef; + sandbox_callback_expat mHandleComment; + sandbox_callback_expat mHandleStartCdataSection; + sandbox_callback_expat mHandleEndCdataSection; + sandbox_callback_expat mHandleStartDoctypeDecl; + sandbox_callback_expat mHandleEndDoctypeDecl; + // Expat callbacks specific to each driver, and thus (re)set across sandbox + // reuses. + sandbox_callback_expat mHandleStartElement; + sandbox_callback_expat mHandleEndElement; +}; + +#endif diff --git a/parser/htmlparser/nsHTMLTagList.h b/parser/htmlparser/nsHTMLTagList.h new file mode 100644 index 0000000000..5179a6887e --- /dev/null +++ b/parser/htmlparser/nsHTMLTagList.h @@ -0,0 +1,204 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// IWYU pragma: private, include "nsHTMLTags.h" + +/****** + + This file contains the list of all HTML tags. + See nsHTMLTags.h for access to the enum values for tags. + + It is designed to be used as input to various places that will define the + HTML_TAG macro in useful ways through the magic of C preprocessing. + Additionally, it is consumed by the self-regeneration code in + ElementName.java from which nsHtml5ElementName.cpp/h is translated. + See parser/html/java/README.txt. + + If you edit this list, you need to re-run ElementName.java + self-regeneration and the HTML parser Java to C++ translation. + + All entries must be enclosed in the macro HTML_TAG which will have cruel + and unusual things done to it. + + It is recommended (but not strictly necessary) to keep all entries + in alphabetical order. + + The first argument to HTML_TAG is the tag name. The second argument is the + "creator" method of the form NS_New$TAGNAMEElement, that will be used by + nsHTMLContentSink.cpp to create a content object for a tag of that + type. Use NOTUSED, if the particular tag has a non-standard creator. + The third argument is the interface name specified for this element + in the HTML specification. It can be empty if the relevant interface name + is "HTMLElement". + + The HTML_OTHER macro is for values in the nsHTMLTag enum that are + not strictly tags. + + Entries *must* use only lowercase characters. + + Don't forget to update /editor/libeditor/HTMLEditUtils.cpp as well. + + ** Break these invariants and bad things will happen. ** + + ******/ + +#pragma push_macro("small") +#undef small + +#define HTML_HTMLELEMENT_TAG(_tag) HTML_TAG(_tag, , ) + +HTML_TAG(a, Anchor, Anchor) +HTML_HTMLELEMENT_TAG(abbr) +HTML_HTMLELEMENT_TAG(acronym) +HTML_HTMLELEMENT_TAG(address) +HTML_TAG(applet, Unknown, Unknown) +HTML_TAG(area, Area, Area) +HTML_HTMLELEMENT_TAG(article) +HTML_HTMLELEMENT_TAG(aside) +HTML_TAG(audio, Audio, Audio) +HTML_HTMLELEMENT_TAG(b) +HTML_TAG(base, Shared, Base) +HTML_HTMLELEMENT_TAG(basefont) +HTML_HTMLELEMENT_TAG(bdi) +HTML_HTMLELEMENT_TAG(bdo) +HTML_TAG(bgsound, Unknown, Unknown) +HTML_HTMLELEMENT_TAG(big) +HTML_TAG(blockquote, Shared, Quote) +HTML_TAG(body, Body, Body) +HTML_TAG(br, BR, BR) +HTML_TAG(button, Button, Button) +HTML_TAG(canvas, Canvas, Canvas) +HTML_TAG(caption, TableCaption, TableCaption) +HTML_HTMLELEMENT_TAG(center) +HTML_HTMLELEMENT_TAG(cite) +HTML_HTMLELEMENT_TAG(code) +HTML_TAG(col, TableCol, TableCol) +HTML_TAG(colgroup, TableCol, TableCol) +HTML_TAG(data, Data, Data) +HTML_TAG(datalist, DataList, DataList) +HTML_HTMLELEMENT_TAG(dd) +HTML_TAG(del, Mod, Mod) +HTML_TAG(details, Details, Details) +HTML_HTMLELEMENT_TAG(dfn) +HTML_TAG(dialog, Dialog, Dialog) +HTML_TAG(dir, Shared, Directory) +HTML_TAG(div, Div, Div) +HTML_TAG(dl, SharedList, DList) +HTML_HTMLELEMENT_TAG(dt) +HTML_HTMLELEMENT_TAG(em) +HTML_TAG(embed, Embed, Embed) +HTML_TAG(fieldset, FieldSet, FieldSet) +HTML_HTMLELEMENT_TAG(figcaption) +HTML_HTMLELEMENT_TAG(figure) +HTML_TAG(font, Font, Font) +HTML_HTMLELEMENT_TAG(footer) +HTML_TAG(form, Form, Form) +HTML_TAG(frame, Frame, Frame) +HTML_TAG(frameset, FrameSet, FrameSet) +HTML_TAG(h1, Heading, Heading) +HTML_TAG(h2, Heading, Heading) +HTML_TAG(h3, Heading, Heading) +HTML_TAG(h4, Heading, Heading) +HTML_TAG(h5, Heading, Heading) +HTML_TAG(h6, Heading, Heading) +HTML_TAG(head, Shared, Head) +HTML_HTMLELEMENT_TAG(header) +HTML_HTMLELEMENT_TAG(hgroup) +HTML_TAG(hr, HR, HR) +HTML_TAG(html, Shared, Html) +HTML_HTMLELEMENT_TAG(i) +HTML_TAG(iframe, IFrame, IFrame) +HTML_HTMLELEMENT_TAG(image) +HTML_TAG(img, Image, Image) +HTML_TAG(input, Input, Input) +HTML_TAG(ins, Mod, Mod) +HTML_HTMLELEMENT_TAG(kbd) +HTML_TAG(keygen, Unknown, Unknown) +HTML_TAG(label, Label, Label) +HTML_TAG(legend, Legend, Legend) +HTML_TAG(li, LI, LI) +HTML_TAG(link, Link, Link) +HTML_TAG(listing, Pre, Pre) +HTML_HTMLELEMENT_TAG(main) +HTML_TAG(map, Map, Map) +HTML_HTMLELEMENT_TAG(mark) +HTML_TAG(marquee, Marquee, Marquee) +HTML_TAG(menu, Menu, Menu) +HTML_TAG(meta, Meta, Meta) +HTML_TAG(meter, Meter, Meter) +HTML_TAG(multicol, Unknown, Unknown) +HTML_HTMLELEMENT_TAG(nav) +HTML_HTMLELEMENT_TAG(nobr) +HTML_HTMLELEMENT_TAG(noembed) +HTML_HTMLELEMENT_TAG(noframes) +HTML_HTMLELEMENT_TAG(noscript) +HTML_TAG(object, Object, Object) +HTML_TAG(ol, SharedList, OList) +HTML_TAG(optgroup, OptGroup, OptGroup) +HTML_TAG(option, Option, Option) +HTML_TAG(output, Output, Output) +HTML_TAG(p, Paragraph, Paragraph) +HTML_TAG(param, Shared, Param) +HTML_TAG(picture, Picture, Picture) +HTML_HTMLELEMENT_TAG(plaintext) +HTML_TAG(pre, Pre, Pre) +HTML_TAG(progress, Progress, Progress) +HTML_TAG(q, Shared, Quote) +HTML_HTMLELEMENT_TAG(rb) +HTML_HTMLELEMENT_TAG(rp) +HTML_HTMLELEMENT_TAG(rt) +HTML_HTMLELEMENT_TAG(rtc) +HTML_HTMLELEMENT_TAG(ruby) +HTML_HTMLELEMENT_TAG(s) +HTML_HTMLELEMENT_TAG(samp) +HTML_TAG(script, Script, Script) +HTML_HTMLELEMENT_TAG(search) +HTML_HTMLELEMENT_TAG(section) +HTML_TAG(select, Select, Select) +HTML_HTMLELEMENT_TAG(small) +HTML_TAG(slot, Slot, Slot) +HTML_TAG(source, Source, Source) +HTML_TAG(span, Span, Span) +HTML_HTMLELEMENT_TAG(strike) +HTML_HTMLELEMENT_TAG(strong) +HTML_TAG(style, Style, Style) +HTML_HTMLELEMENT_TAG(sub) +HTML_TAG(summary, Summary, ) +HTML_HTMLELEMENT_TAG(sup) +HTML_TAG(table, Table, Table) +HTML_TAG(tbody, TableSection, TableSection) +HTML_TAG(td, TableCell, TableCell) +HTML_TAG(textarea, TextArea, TextArea) +HTML_TAG(tfoot, TableSection, TableSection) +HTML_TAG(th, TableCell, TableCell) +HTML_TAG(thead, TableSection, TableSection) +HTML_TAG(template, Template, Template) +HTML_TAG(time, Time, Time) +HTML_TAG(title, Title, Title) +HTML_TAG(tr, TableRow, TableRow) +HTML_TAG(track, Track, Track) +HTML_HTMLELEMENT_TAG(tt) +HTML_HTMLELEMENT_TAG(u) +HTML_TAG(ul, SharedList, UList) +HTML_HTMLELEMENT_TAG(var) +HTML_TAG(video, Video, Video) +HTML_HTMLELEMENT_TAG(wbr) +HTML_TAG(xmp, Pre, Pre) + +/* These are not for tags. But they will be included in the nsHTMLTag + enum anyway */ + +HTML_OTHER(text) +HTML_OTHER(whitespace) +HTML_OTHER(newline) +HTML_OTHER(comment) +HTML_OTHER(entity) +HTML_OTHER(doctypeDecl) +HTML_OTHER(markupDecl) +HTML_OTHER(instruction) + +#undef HTML_HTMLELEMENT_TAG + +#pragma pop_macro("small") diff --git a/parser/htmlparser/nsHTMLTags.cpp b/parser/htmlparser/nsHTMLTags.cpp new file mode 100644 index 0000000000..ec3c4f322d --- /dev/null +++ b/parser/htmlparser/nsHTMLTags.cpp @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsHTMLTags.h" +#include "nsCRT.h" +#include "nsElementTable.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsUnicharUtils.h" +#include "mozilla/HashFunctions.h" +#include + +using namespace mozilla; + +// static array of unicode tag names +#define HTML_TAG(_tag, _classname, _interfacename) (u"" #_tag), +#define HTML_OTHER(_tag) +const char16_t* const nsHTMLTags::sTagNames[] = { +#include "nsHTMLTagList.h" +}; +#undef HTML_TAG +#undef HTML_OTHER + +int32_t nsHTMLTags::gTableRefCount; +nsHTMLTags::TagStringHash* nsHTMLTags::gTagTable; +nsHTMLTags::TagAtomHash* nsHTMLTags::gTagAtomTable; + +#define NS_HTMLTAG_NAME_MAX_LENGTH 10 + +// static +nsresult nsHTMLTags::AddRefTable(void) { + if (gTableRefCount++ == 0) { + NS_ASSERTION(!gTagTable && !gTagAtomTable, "pre existing hash!"); + + gTagTable = new TagStringHash(64); + gTagAtomTable = new TagAtomHash(64); + + // Fill in gTagTable with the above static char16_t strings as + // keys and the value of the corresponding enum as the value in + // the table. + + for (int32_t i = 0; i < NS_HTML_TAG_MAX; ++i) { + const char16_t* tagName = sTagNames[i]; + const nsHTMLTag tagValue = static_cast(i + 1); + + // We use AssignLiteral here to avoid a string copy. This is okay + // because this is truly static data. + nsString tmp; + tmp.AssignLiteral(tagName, nsString::char_traits::length(tagName)); + gTagTable->InsertOrUpdate(tmp, tagValue); + + // All the HTML tag names are static atoms within nsGkAtoms, and they are + // registered before this code is reached. + nsStaticAtom* atom = NS_GetStaticAtom(tmp); + MOZ_ASSERT(atom); + gTagAtomTable->InsertOrUpdate(atom, tagValue); + } + +#ifdef DEBUG + // Check all tagNames are lowercase, and that NS_HTMLTAG_NAME_MAX_LENGTH is + // correct. + uint32_t maxTagNameLength = 0; + for (int i = 0; i < NS_HTML_TAG_MAX; ++i) { + const char16_t* tagName = sTagNames[i]; + + nsAutoString lowerTagName(tagName); + ToLowerCase(lowerTagName); + MOZ_ASSERT(lowerTagName.Equals(tagName)); + + maxTagNameLength = std::max(NS_strlen(tagName), maxTagNameLength); + } + + MOZ_ASSERT(maxTagNameLength == NS_HTMLTAG_NAME_MAX_LENGTH); + + CheckElementTable(); + TestTagTable(); +#endif + } + + return NS_OK; +} + +// static +void nsHTMLTags::ReleaseTable(void) { + if (0 == --gTableRefCount) { + delete gTagTable; + delete gTagAtomTable; + gTagTable = nullptr; + gTagAtomTable = nullptr; + } +} + +// static +nsHTMLTag nsHTMLTags::StringTagToId(const nsAString& aTagName) { + uint32_t length = aTagName.Length(); + + if (length > NS_HTMLTAG_NAME_MAX_LENGTH) { + return eHTMLTag_userdefined; + } + + // Setup a stack allocated string buffer with the appropriate length. + nsAutoString lowerCase; + lowerCase.SetLength(length); + + // Operate on the raw buffers to avoid bounds checks. + auto src = aTagName.BeginReading(); + auto dst = lowerCase.BeginWriting(); + + // Fast lowercasing-while-copying of ASCII characters into a + // nsString buffer. + + for (uint32_t i = 0; i < length; i++) { + char16_t c = src[i]; + + if (c <= 'Z' && c >= 'A') { + c |= 0x20; // Lowercase the ASCII character. + } + + dst[i] = c; // Copy ASCII character. + } + + return CaseSensitiveStringTagToId(lowerCase); +} + +#ifdef DEBUG +void nsHTMLTags::TestTagTable() { + const char16_t* tag; + nsHTMLTag id; + RefPtr atom; + + nsHTMLTags::AddRefTable(); + // Make sure we can find everything we are supposed to + for (int i = 0; i < NS_HTML_TAG_MAX; ++i) { + tag = sTagNames[i]; + const nsAString& tagString = nsDependentString(tag); + id = StringTagToId(tagString); + NS_ASSERTION(id != eHTMLTag_userdefined, "can't find tag id"); + + nsAutoString uname(tagString); + ToUpperCase(uname); + NS_ASSERTION(id == StringTagToId(uname), "wrong id"); + + NS_ASSERTION(id == CaseSensitiveStringTagToId(tagString), "wrong id"); + + atom = NS_Atomize(tag); + NS_ASSERTION(id == CaseSensitiveAtomTagToId(atom), "wrong id"); + } + + // Make sure we don't find things that aren't there + id = StringTagToId(u"@"_ns); + NS_ASSERTION(id == eHTMLTag_userdefined, "found @"); + id = StringTagToId(u"zzzzz"_ns); + NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz"); + + atom = NS_Atomize("@"); + id = CaseSensitiveAtomTagToId(atom); + NS_ASSERTION(id == eHTMLTag_userdefined, "found @"); + atom = NS_Atomize("zzzzz"); + id = CaseSensitiveAtomTagToId(atom); + NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz"); + + ReleaseTable(); +} + +#endif // DEBUG diff --git a/parser/htmlparser/nsHTMLTags.h b/parser/htmlparser/nsHTMLTags.h new file mode 100644 index 0000000000..2e2f80e6aa --- /dev/null +++ b/parser/htmlparser/nsHTMLTags.h @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsHTMLTags_h___ +#define nsHTMLTags_h___ + +#include "nsAtomHashKeys.h" +#include "nsString.h" +#include "nsTHashMap.h" +#include "nsHashKeys.h" + +/* + Declare the enum list using the magic of preprocessing + enum values are "eHTMLTag_foo" (where foo is the tag) + + To change the list of tags, see nsHTMLTagList.h + + These enum values are used as the index of array in various places. + If we change the structure of the enum by adding entries to it or removing + entries from it _directly_, not via nsHTMLTagList.h, don't forget to update + dom/bindings/BindingUtils.cpp and dom/html/nsHTMLContentSink.cpp as well. + */ +#define HTML_TAG(_tag, _classname, _interfacename) eHTMLTag_##_tag, +#define HTML_OTHER(_tag) eHTMLTag_##_tag, +enum nsHTMLTag { + /* this enum must be first and must be zero */ + eHTMLTag_unknown = 0, +#include "nsHTMLTagList.h" + + /* can't be moved into nsHTMLTagList since gcc3.4 doesn't like a + comma at the end of enum list*/ + eHTMLTag_userdefined +}; +#undef HTML_TAG +#undef HTML_OTHER + +// All tags before eHTMLTag_text are HTML tags +#define NS_HTML_TAG_MAX int32_t(eHTMLTag_text - 1) + +class nsHTMLTags { + public: + using TagStringHash = nsTHashMap; + // Can be weak, because we know these are always static, see AddRefTable. + using TagAtomHash = nsTHashMap; + + static nsresult AddRefTable(void); + static void ReleaseTable(void); + + // Functions for converting string or atom to id + static nsHTMLTag StringTagToId(const nsAString& aTagName); + static nsHTMLTag AtomTagToId(nsAtom* aTagName) { + return StringTagToId(nsDependentAtomString(aTagName)); + } + + static nsHTMLTag CaseSensitiveStringTagToId(const nsAString& aTagName) { + NS_ASSERTION(gTagTable, "no lookup table, needs addref"); + + return gTagTable->MaybeGet(aTagName).valueOr(eHTMLTag_userdefined); + } + static nsHTMLTag CaseSensitiveAtomTagToId(nsAtom* aTagName) { + NS_ASSERTION(gTagAtomTable, "no lookup table, needs addref"); + NS_ASSERTION(aTagName, "null tagname!"); + + return gTagAtomTable->MaybeGet(aTagName).valueOr(eHTMLTag_userdefined); + } + +#ifdef DEBUG + static void TestTagTable(); +#endif + + private: + static const char16_t* const sTagNames[]; + + static int32_t gTableRefCount; + static TagStringHash* gTagTable; + static TagAtomHash* gTagAtomTable; +}; + +#endif /* nsHTMLTags_h___ */ diff --git a/parser/htmlparser/nsIContentSink.h b/parser/htmlparser/nsIContentSink.h new file mode 100644 index 0000000000..aa77c192c7 --- /dev/null +++ b/parser/htmlparser/nsIContentSink.h @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsIContentSink_h___ +#define nsIContentSink_h___ + +/** + * MODULE NOTES: + * @update gess 4/1/98 + * + * This pure virtual interface is used as the "glue" that connects the parsing + * process to the content model construction process. + * + * The icontentsink interface is a very lightweight wrapper that represents the + * content-sink model building process. There is another one that you may care + * about more, which is the IHTMLContentSink interface. (See that file for + * details). + */ +#include "nsISupports.h" +#include "nsString.h" +#include "mozilla/FlushType.h" +#include "mozilla/NotNull.h" +#include "nsIDTD.h" + +class nsParserBase; +namespace mozilla { +class Encoding; +} + +#define NS_ICONTENT_SINK_IID \ + { \ + 0xcf9a7cbb, 0xfcbc, 0x4e13, { \ + 0x8e, 0xf5, 0x18, 0xef, 0x2d, 0x3d, 0x58, 0x29 \ + } \ + } + +class nsIContentSink : public nsISupports { + protected: + using Encoding = mozilla::Encoding; + template + using NotNull = mozilla::NotNull; + + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID) + + /** + * This method is called by the parser when it is entered from + * the event loop. The content sink wants to know how long the + * parser has been active since we last processed events on the + * main event loop and this call calibrates that measurement. + */ + NS_IMETHOD WillParse(void) = 0; + + /** + * This method gets called when the parser begins the process + * of building the content model via the content sink. + * + * Default implementation provided since the sink should have the option of + * doing nothing in response to this call. + * + * @update 5/7/98 gess + */ + NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) { return NS_OK; } + + /** + * This method gets called when the parser concludes the process + * of building the content model via the content sink. + * + * Default implementation provided since the sink should have the option of + * doing nothing in response to this call. + * + * @update 5/7/98 gess + */ + NS_IMETHOD DidBuildModel(bool aTerminated) { return NS_OK; } + + /** + * This method gets called when the parser gets i/o blocked, + * and wants to notify the sink that it may be a while before + * more data is available. + * + * @update 5/7/98 gess + */ + NS_IMETHOD WillInterrupt(void) = 0; + + /** + * This method gets called when the parser i/o gets unblocked, + * and we're about to start dumping content again to the sink. + */ + virtual void WillResume() = 0; + + /** + * This method returns nullptr unless `this` can + * be cast as nsHtml5TreeOpExecutor. + */ + virtual nsIContentSink* AsExecutor() { return nullptr; } + + /** + * This method gets called by the parser so that the content + * sink can retain a reference to the parser. The expectation + * is that the content sink will drop the reference when it + * gets the DidBuildModel notification i.e. when parsing is done. + */ + NS_IMETHOD SetParser(nsParserBase* aParser) = 0; + + /** + * Flush content so that the content model is in sync with the state + * of the sink. + * + * @param aType the type of flush to perform + */ + virtual void FlushPendingNotifications(mozilla::FlushType aType) = 0; + + /** + * Set the document character set. This should be passed on to the + * document itself. + */ + virtual void SetDocumentCharset(NotNull aEncoding) = 0; + + /** + * Returns the target object (often a document object) into which + * the content built by this content sink is being added, if any + * (IOW, may return null). + */ + virtual nsISupports* GetTarget() = 0; + + /** + * Returns true if there's currently script executing that we need to hold + * parsing for. + */ + virtual bool IsScriptExecuting() { return false; } + + /** + * Posts a runnable that continues parsing. + */ + virtual void ContinueInterruptedParsingAsync() {} + + virtual void InitialTranslationCompleted() {} +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentSink, NS_ICONTENT_SINK_IID) + +#endif /* nsIContentSink_h___ */ diff --git a/parser/htmlparser/nsIDTD.h b/parser/htmlparser/nsIDTD.h new file mode 100644 index 0000000000..67f7af4ec2 --- /dev/null +++ b/parser/htmlparser/nsIDTD.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsIDTD_h___ +#define nsIDTD_h___ + +/** + * MODULE NOTES: + * @update gess 7/20/98 + * + * This interface defines standard interface for DTD's. Note that this + * isn't HTML specific. DTD's have several functions within the parser + * system: + * 1) To coordinate the consumption of an input stream via the + * parser + * 2) To serve as proxy to represent the containment rules of the + * underlying document + * 3) To offer autodetection services to the parser (mainly for doc + * conversion) + * */ + +#include "nsISupports.h" +#include "nsString.h" + +#define NS_IDTD_IID \ + { \ + 0x3de05873, 0xefa7, 0x410d, { \ + 0xa4, 0x61, 0x80, 0x33, 0xaf, 0xd9, 0xe3, 0x26 \ + } \ + } + +enum eAutoDetectResult { + eUnknownDetect, + ePrimaryDetect, +}; + +enum nsDTDMode { + eDTDMode_quirks, // pre 4.0 versions + eDTDMode_full_standards, + eDTDMode_autodetect +}; + +class nsIContentSink; +class CParserContext; + +class nsIDTD : public nsISupports { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDTD_IID) + + /** + * Called by the parser after the parsing process has concluded + */ + virtual void DidBuildModel() = 0; + + /** + * Called (possibly repeatedly) by the parser to parse tokens and construct + * the document model via the sink provided to WillBuildModel. + * + * @param aCountLines - informs the DTD whether to count newlines + * (not wanted, e.g., when handling document.write) + * @param aCharsetPtr - address of an nsCString containing the charset + * that the DTD should use (pointer in case the DTD + * opts to ignore this parameter) + */ + NS_IMETHOD BuildModel(nsIContentSink* aSink) = 0; + + /** + * Use this id you want to stop the building content model + * --------------[ Sets DTD to STOP mode ]---------------- + * It's recommended to use this method in accordance with + * the parser's terminate() method. + * + * @update harishd 07/22/99 + * @param + * @return + */ + NS_IMETHOD_(void) Terminate() = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIDTD, NS_IDTD_IID) + +#define NS_DECL_NSIDTD \ + void DidBuildModel() override; \ + NS_IMETHOD BuildModel(nsIContentSink* aSink) override; \ + NS_IMETHOD_(void) Terminate() override; +#endif /* nsIDTD_h___ */ diff --git a/parser/htmlparser/nsIExpatSink.idl b/parser/htmlparser/nsIExpatSink.idl new file mode 100644 index 0000000000..56ca099fee --- /dev/null +++ b/parser/htmlparser/nsIExpatSink.idl @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +interface nsIScriptError; + +/** + * This interface should be implemented by any content sink that wants + * to get output from expat and do something with it; in other words, + * by any sink that handles some sort of XML dialect. + */ + +[scriptable, uuid(01f681af-0f22-4725-a914-0d396114daf0)] +interface nsIExpatSink : nsISupports +{ + /** + * Called to handle the opening tag of an element. + * @param aName the fully qualified tagname of the element + * @param aAtts the array of attribute names and values. There are + * aAttsCount/2 names and aAttsCount/2 values, so the total number of + * elements in the array is aAttsCount. The names and values + * alternate. Thus, if we number attributes starting with 0, + * aAtts[2*k] is the name of the k-th attribute and aAtts[2*k+1] is + * the value of that attribute Both explicitly specified attributes + * and attributes that are defined to have default values in a DTD are + * present in aAtts. + * @param aAttsCount the number of elements in aAtts. + * @param aLineNumber the line number of the start tag in the data stream. + * @param aColumnNumber the 0-origin column number of the start tag in the + * data stream. + */ + void HandleStartElement(in wstring aName, + [array, size_is(aAttsCount)] in wstring aAtts, + in unsigned long aAttsCount, + in unsigned long aLineNumber, + in unsigned long aColumnNumber); + + /** + * Called to handle the closing tag of an element. + * @param aName the fully qualified tagname of the element + */ + void HandleEndElement(in wstring aName); + + /** + * Called to handle a comment + * @param aCommentText the text of the comment (not including the + * "") + */ + void HandleComment(in wstring aCommentText); + + /** + * Called to handle a CDATA section + * @param aData the text in the CDATA section. This is null-terminated. + * @param aLength the length of the aData string + */ + void HandleCDataSection([size_is(aLength)] in wstring aData, + in unsigned long aLength); + + /** + * Called to handle the doctype declaration + */ + void HandleDoctypeDecl(in AString aSubset, + in AString aName, + in AString aSystemId, + in AString aPublicId, + in nsISupports aCatalogData); + + /** + * Called to handle character data. Note that this does NOT get + * called for the contents of CDATA sections. + * @param aData the data to handle. aData is NOT NULL-TERMINATED. + * @param aLength the length of the aData string + */ + void HandleCharacterData([size_is(aLength)] in wstring aData, + in unsigned long aLength); + + /** + * Called to handle a processing instruction + * @param aTarget the PI target (e.g. xml-stylesheet) + * @param aData all the rest of the data in the PI + */ + void HandleProcessingInstruction(in wstring aTarget, + in wstring aData); + + /** + * Handle the XML Declaration. + * + * @param aVersion The version string, can be null if not specified. + * @param aEncoding The encoding string, can be null if not specified. + * @param aStandalone -1, 0, or 1 indicating respectively that there was no + * standalone parameter in the declaration, that it was + * given as no, or that it was given as yes. + */ + void HandleXMLDeclaration(in wstring aVersion, + in wstring aEncoding, + in long aStandalone); + + /** + * Ask the content sink if the expat driver should log an error to the console. + * + * @param aErrorText Error message to pass to content sink. + * @param aSourceText Source text of the document we're parsing. + * @param aError Script error object with line number & column number + * + * @retval True if the expat driver should report the error. + */ + boolean ReportError(in wstring aErrorText, + in wstring aSourceText, + in nsIScriptError aError); +}; diff --git a/parser/htmlparser/nsIFragmentContentSink.h b/parser/htmlparser/nsIFragmentContentSink.h new file mode 100644 index 0000000000..351963cfa3 --- /dev/null +++ b/parser/htmlparser/nsIFragmentContentSink.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsIFragmentContentSink_h___ +#define nsIFragmentContentSink_h___ + +#include "nsISupports.h" + +namespace mozilla { +namespace dom { +class Document; +class DocumentFragment; +} // namespace dom +} // namespace mozilla + +#define NS_I_FRAGMENT_CONTENT_SINK_IID \ + { \ + 0x1a8ce30b, 0x63fc, 0x441a, { \ + 0xa3, 0xaa, 0xf7, 0x16, 0xc0, 0xfe, 0x96, 0x69 \ + } \ + } + +/** + * The fragment sink allows a client to parse a fragment of sink, possibly + * surrounded in context. Also see nsParser::ParseFragment(). + * Note: once you've parsed a fragment, the fragment sink must be re-set on + * the parser in order to parse another fragment. + */ +class nsIFragmentContentSink : public nsISupports { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_I_FRAGMENT_CONTENT_SINK_IID) + /** + * This method is used to obtain the fragment created by + * a fragment content sink and to release resources held by the parser. + * + * The sink drops its reference to the fragment. + */ + NS_IMETHOD FinishFragmentParsing(mozilla::dom::DocumentFragment** aFragment) = + 0; + + /** + * This method is used to set the target document for this fragment + * sink. This document's nodeinfo manager will be used to create + * the content objects. This MUST be called before the sink is used. + * + * @param aDocument the document the new nodes will belong to + * (should not be null) + */ + NS_IMETHOD SetTargetDocument(mozilla::dom::Document*) = 0; + + /** + * This method is used to indicate to the sink that we're done building + * the context and should start paying attention to the incoming content + */ + NS_IMETHOD WillBuildContent() = 0; + + /** + * This method is used to indicate to the sink that we're done building + * The real content. This is useful if you want to parse additional context + * (such as an end context). + */ + NS_IMETHOD DidBuildContent() = 0; + + /** + * This method is a total hack to help with parsing fragments. It is called to + * tell the fragment sink that a container from the context will be delivered + * after the call to WillBuildContent(). This is only relevent for HTML + * fragments that use nsHTMLTokenizer/CNavDTD. + */ + NS_IMETHOD IgnoreFirstContainer() = 0; + + /** + * Sets whether scripts elements are marked as unexecutable. + */ + NS_IMETHOD SetPreventScriptExecution(bool aPreventScriptExecution) = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIFragmentContentSink, + NS_I_FRAGMENT_CONTENT_SINK_IID) + +nsresult NS_NewXMLFragmentContentSink( + nsIFragmentContentSink** aInstancePtrResult); + +#endif diff --git a/parser/htmlparser/nsIHTMLContentSink.h b/parser/htmlparser/nsIHTMLContentSink.h new file mode 100644 index 0000000000..3e81d5d770 --- /dev/null +++ b/parser/htmlparser/nsIHTMLContentSink.h @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsIHTMLContentSink_h___ +#define nsIHTMLContentSink_h___ + +/** + * This interface is OBSOLETE and in the process of being REMOVED. + * Do NOT implement! + * + * This file declares the concrete HTMLContentSink class. + * This class is used during the parsing process as the + * primary interface between the parser and the content + * model. + * + * After the tokenizer completes, the parser iterates over + * the known token list. As the parser identifies valid + * elements, it calls the contentsink interface to notify + * the content model that a new node or child node is being + * created and added to the content model. + * + * The HTMLContentSink interface assumes 4 underlying + * containers: HTML, HEAD, BODY and FRAMESET. Before + * accessing any these, the parser will call the appropriate + * OpennsIHTMLContentSink method: OpenHTML,OpenHead,OpenBody,OpenFrameSet; + * likewise, the ClosensIHTMLContentSink version will be called when the + * parser is done with a given section. + * + * IMPORTANT: The parser may Open each container more than + * once! This is due to the irregular nature of HTML files. + * For example, it is possible to encounter plain text at + * the start of an HTML document (that precedes the HTML tag). + * Such text is treated as if it were part of the body. + * In such cases, the parser will Open the body, pass the text- + * node in and then Close the body. The body will likely be + * re-Opened later when the actual tag has been seen. + * + * Containers within the body are Opened and Closed + * using the OpenContainer(...) and CloseContainer(...) calls. + * It is assumed that the document or contentSink is + * maintaining its state to manage where new content should + * be added to the underlying document. + * + * NOTE: OpenHTML() and OpenBody() may get called multiple times + * in the same document. That's fine, and it doesn't mean + * that we have multiple bodies or HTML's. + * + * NOTE: I haven't figured out how sub-documents (non-frames) + * are going to be handled. Stay tuned. + */ +#include "nsIContentSink.h" +#include "nsHTMLTags.h" + +#define NS_IHTML_CONTENT_SINK_IID \ + { \ + 0xefc5af86, 0x5cfd, 0x4918, { \ + 0x9d, 0xd3, 0x5f, 0x7a, 0xb2, 0x88, 0xb2, 0x68 \ + } \ + } + +/** + * This interface is OBSOLETE and in the process of being REMOVED. + * Do NOT implement! + */ +class nsIHTMLContentSink : public nsIContentSink { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTML_CONTENT_SINK_IID) + + enum ElementType { eHTML, eBody }; + + /** + * This method is used to open a generic container in the sink. + * + * @update 4/1/98 gess + */ + NS_IMETHOD OpenContainer(ElementType aNodeType) = 0; + + /** + * This method gets called by the parser when a close + * container tag has been consumed and needs to be closed. + * + * @param aTag - The tag to be closed. + */ + NS_IMETHOD CloseContainer(ElementType aTag) = 0; + + /** + * This method returns true if there are more than one + * pending style sheets, false otherwise. + */ + virtual bool WaitForPendingSheets() = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLContentSink, NS_IHTML_CONTENT_SINK_IID) + +#endif /* nsIHTMLContentSink_h___ */ diff --git a/parser/htmlparser/nsIParser.h b/parser/htmlparser/nsIParser.h new file mode 100644 index 0000000000..8cf3940ffb --- /dev/null +++ b/parser/htmlparser/nsIParser.h @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef NS_IPARSER___ +#define NS_IPARSER___ + +/** + * This GECKO-INTERNAL interface is on track to being REMOVED (or refactored + * to the point of being near-unrecognizable). + * + * Please DO NOT #include this file in comm-central code, in your XULRunner + * app or binary extensions. + * + * Please DO NOT #include this into new files even inside Gecko. It is more + * likely than not that #including this header is the wrong thing to do. + */ + +#include "nsISupports.h" +#include "nsIStreamListener.h" +#include "nsIDTD.h" +#include "nsString.h" +#include "nsTArray.h" +#include "nsAtom.h" +#include "nsParserBase.h" +#include "mozilla/NotNull.h" + +#define NS_IPARSER_IID \ + { \ + 0x2c4ad90a, 0x740e, 0x4212, { \ + 0xba, 0x3f, 0xfe, 0xac, 0xda, 0x4b, 0x92, 0x9e \ + } \ + } + +class nsIContentSink; +class nsIRequestObserver; +class nsIURI; +class nsIChannel; +namespace mozilla { +class Encoding; +} + +enum eParserCommands { eViewNormal, eViewSource, eViewFragment, eViewErrors }; + +enum eParserDocType { eUnknown = 0, eXML, eHTML_Quirks, eHTML_Strict }; + +enum eStreamState { eNone, eOnStart, eOnDataAvail, eOnStop }; + +/** + * This GECKO-INTERNAL interface is on track to being REMOVED (or refactored + * to the point of being near-unrecognizable). + * + * Please DO NOT #include this file in comm-central code, in your XULRunner + * app or binary extensions. + * + * Please DO NOT #include this into new files even inside Gecko. It is more + * likely than not that #including this header is the wrong thing to do. + */ +class nsIParser : public nsParserBase { + protected: + using Encoding = mozilla::Encoding; + template + using NotNull = mozilla::NotNull; + + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSER_IID) + + /** + * Select given content sink into parser for parser output + * @update gess5/11/98 + * @param aSink is the new sink to be used by parser + * @return + */ + NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) = 0; + + /** + * retrieve the sink set into the parser + * @update gess5/11/98 + * @return current sink + */ + NS_IMETHOD_(nsIContentSink*) GetContentSink(void) = 0; + + /** + * Call this method once you've created a parser, and want to instruct it + * about the command which caused the parser to be constructed. For example, + * this allows us to select a DTD which can do, say, view-source. + * + * @update gess 3/25/98 + * @param aCommand -- ptrs to string that contains command + * @return nada + */ + NS_IMETHOD_(void) GetCommand(nsCString& aCommand) = 0; + NS_IMETHOD_(void) SetCommand(const char* aCommand) = 0; + NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) = 0; + + /** + * Call this method once you've created a parser, and want to instruct it + * about what charset to load + * + * @update ftang 4/23/99 + * @param aCharset- the charest of a document + * @param aCharsetSource- the soure of the chares + * @param aForceAutoDetection- whether Repair Text Encoding menu item was + * invoked + * @return nada + */ + virtual void SetDocumentCharset(NotNull aCharset, + int32_t aSource, + bool aForceAutoDetection = false) = 0; + + /** + * Get the nsIStreamListener for this parser + */ + virtual nsIStreamListener* GetStreamListener() = 0; + + /************************************************************************** + * Parse methods always begin with an input source, and perform + * conversions until you wind up being emitted to the given contentsink + * (which may or may not be a proxy for the NGLayout content model). + ************************************************************************/ + + // Call this method to resume the parser from an unblocked state. + // This can happen, for example, if parsing was interrupted and then the + // consumer needed to restart the parser without waiting for more data. + // This also happens after loading scripts, which unblock the parser in + // order to process the output of document.write() and then need to + // continue on with the page load on an enabled parser. + NS_IMETHOD ContinueInterruptedParsing() = 0; + + // Stops parsing temporarily. + NS_IMETHOD_(void) BlockParser() = 0; + + // Open up the parser for tokenization, building up content + // model..etc. However, this method does not resume parsing + // automatically. It's the callers' responsibility to restart + // the parsing engine. + NS_IMETHOD_(void) UnblockParser() = 0; + + /** + * Asynchronously continues parsing. + */ + NS_IMETHOD_(void) ContinueInterruptedParsingAsync() = 0; + + NS_IMETHOD_(bool) IsParserEnabled() override = 0; + NS_IMETHOD_(bool) IsComplete() = 0; + + NS_IMETHOD Parse(nsIURI* aURL) = 0; + + NS_IMETHOD Terminate(void) = 0; + + /** + * True if the insertion point (per HTML5) is defined. + */ + virtual bool IsInsertionPointDefined() = 0; + + /** + * Call immediately before starting to evaluate a parser-inserted script or + * in general when the spec says to increment the script nesting level. + */ + virtual void IncrementScriptNestingLevel() = 0; + + /** + * Call immediately after having evaluated a parser-inserted script or + * generally want to restore to the state before the last + * IncrementScriptNestingLevel call. + */ + virtual void DecrementScriptNestingLevel() = 0; + + /** + * True if this is an HTML5 parser whose script nesting level (in + * the sense of + * ) + * is nonzero. + */ + virtual bool HasNonzeroScriptNestingLevel() const = 0; + + /** + * True if this is a script-created HTML5 parser. + */ + virtual bool IsScriptCreated() = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIParser, NS_IPARSER_IID) + +#endif diff --git a/parser/htmlparser/nsParser.cpp b/parser/htmlparser/nsParser.cpp new file mode 100644 index 0000000000..04d02e2084 --- /dev/null +++ b/parser/htmlparser/nsParser.cpp @@ -0,0 +1,1075 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsAtom.h" +#include "nsParser.h" +#include "nsString.h" +#include "nsCRT.h" +#include "nsScanner.h" +#include "plstr.h" +#include "nsIChannel.h" +#include "nsIInputStream.h" +#include "CNavDTD.h" +#include "prenv.h" +#include "prlock.h" +#include "prcvar.h" +#include "nsReadableUtils.h" +#include "nsCOMPtr.h" +#include "nsExpatDriver.h" +#include "nsIFragmentContentSink.h" +#include "nsStreamUtils.h" +#include "nsXPCOMCIDInternal.h" +#include "nsMimeTypes.h" +#include "nsCharsetSource.h" +#include "nsThreadUtils.h" +#include "nsIHTMLContentSink.h" + +#include "mozilla/BinarySearch.h" +#include "mozilla/CondVar.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/Encoding.h" +#include "mozilla/Mutex.h" + +using namespace mozilla; + +#define NS_PARSER_FLAG_PENDING_CONTINUE_EVENT 0x00000001 +#define NS_PARSER_FLAG_CAN_TOKENIZE 0x00000002 + +//-------------- Begin ParseContinue Event Definition ------------------------ +/* +The parser can be explicitly interrupted by passing a return value of +NS_ERROR_HTMLPARSER_INTERRUPTED from BuildModel on the DTD. This will cause +the parser to stop processing and allow the application to return to the event +loop. The data which was left at the time of interruption will be processed +the next time OnDataAvailable is called. If the parser has received its final +chunk of data then OnDataAvailable will no longer be called by the networking +module, so the parser will schedule a nsParserContinueEvent which will call +the parser to process the remaining data after returning to the event loop. +If the parser is interrupted while processing the remaining data it will +schedule another ParseContinueEvent. The processing of data followed by +scheduling of the continue events will proceed until either: + + 1) All of the remaining data can be processed without interrupting + 2) The parser has been cancelled. + + +This capability is currently used in CNavDTD and nsHTMLContentSink. The +nsHTMLContentSink is notified by CNavDTD when a chunk of tokens is going to be +processed and when each token is processed. The nsHTML content sink records +the time when the chunk has started processing and will return +NS_ERROR_HTMLPARSER_INTERRUPTED if the token processing time has exceeded a +threshold called max tokenizing processing time. This allows the content sink +to limit how much data is processed in a single chunk which in turn gates how +much time is spent away from the event loop. Processing smaller chunks of data +also reduces the time spent in subsequent reflows. + +This capability is most apparent when loading large documents. If the maximum +token processing time is set small enough the application will remain +responsive during document load. + +A side-effect of this capability is that document load is not complete when +the last chunk of data is passed to OnDataAvailable since the parser may have +been interrupted when the last chunk of data arrived. The document is complete +when all of the document has been tokenized and there aren't any pending +nsParserContinueEvents. This can cause problems if the application assumes +that it can monitor the load requests to determine when the document load has +been completed. This is what happens in Mozilla. The document is considered +completely loaded when all of the load requests have been satisfied. To delay +the document load until all of the parsing has been completed the +nsHTMLContentSink adds a dummy parser load request which is not removed until +the nsHTMLContentSink's DidBuildModel is called. The CNavDTD will not call +DidBuildModel until the final chunk of data has been passed to the parser +through the OnDataAvailable and there aren't any pending +nsParserContineEvents. + +Currently the parser is ignores requests to be interrupted during the +processing of script. This is because a document.write followed by JavaScript +calls to manipulate the DOM may fail if the parser was interrupted during the +document.write. + +For more details @see bugzilla bug 76722 +*/ + +class nsParserContinueEvent : public Runnable { + public: + RefPtr mParser; + + explicit nsParserContinueEvent(nsParser* aParser) + : mozilla::Runnable("nsParserContinueEvent"), mParser(aParser) {} + + NS_IMETHOD Run() override { + mParser->HandleParserContinueEvent(this); + return NS_OK; + } +}; + +//-------------- End ParseContinue Event Definition ------------------------ + +/** + * default constructor + */ +nsParser::nsParser() : mCharset(WINDOWS_1252_ENCODING) { Initialize(); } + +nsParser::~nsParser() { Cleanup(); } + +void nsParser::Initialize() { + mContinueEvent = nullptr; + mCharsetSource = kCharsetUninitialized; + mCharset = WINDOWS_1252_ENCODING; + mInternalState = NS_OK; + mStreamStatus = NS_OK; + mCommand = eViewNormal; + mBlocked = 0; + mFlags = NS_PARSER_FLAG_CAN_TOKENIZE; + + mProcessingNetworkData = false; + mIsAboutBlank = false; +} + +void nsParser::Cleanup() { + // It should not be possible for this flag to be set when we are getting + // destroyed since this flag implies a pending nsParserContinueEvent, which + // has an owning reference to |this|. + NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad"); +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(nsParser) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsParser) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDTD) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mSink) + NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsParser) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDTD) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSink) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsParser) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsParser) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsParser) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(nsIParser) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParser) +NS_INTERFACE_MAP_END + +// The parser continue event is posted only if +// all of the data to parse has been passed to ::OnDataAvailable +// and the parser has been interrupted by the content sink +// because the processing of tokens took too long. + +nsresult nsParser::PostContinueEvent() { + if (!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT)) { + // If this flag isn't set, then there shouldn't be a live continue event! + NS_ASSERTION(!mContinueEvent, "bad"); + + // This creates a reference cycle between this and the event that is + // broken when the event fires. + nsCOMPtr event = new nsParserContinueEvent(this); + if (NS_FAILED(NS_DispatchToCurrentThread(event))) { + NS_WARNING("failed to dispatch parser continuation event"); + } else { + mFlags |= NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; + mContinueEvent = event; + } + } + return NS_OK; +} + +NS_IMETHODIMP_(void) +nsParser::GetCommand(nsCString& aCommand) { aCommand = mCommandStr; } + +/** + * Call this method once you've created a parser, and want to instruct it + * about the command which caused the parser to be constructed. For example, + * this allows us to select a DTD which can do, say, view-source. + * + * @param aCommand the command string to set + */ +NS_IMETHODIMP_(void) +nsParser::SetCommand(const char* aCommand) { + mCommandStr.Assign(aCommand); + if (mCommandStr.EqualsLiteral("view-source")) { + mCommand = eViewSource; + } else if (mCommandStr.EqualsLiteral("view-fragment")) { + mCommand = eViewFragment; + } else { + mCommand = eViewNormal; + } +} + +/** + * Call this method once you've created a parser, and want to instruct it + * about the command which caused the parser to be constructed. For example, + * this allows us to select a DTD which can do, say, view-source. + * + * @param aParserCommand the command to set + */ +NS_IMETHODIMP_(void) +nsParser::SetCommand(eParserCommands aParserCommand) { + mCommand = aParserCommand; +} + +/** + * Call this method once you've created a parser, and want to instruct it + * about what charset to load + * + * @param aCharset- the charset of a document + * @param aCharsetSource- the source of the charset + */ +void nsParser::SetDocumentCharset(NotNull aCharset, + int32_t aCharsetSource, + bool aForceAutoDetection) { + mCharset = aCharset; + mCharsetSource = aCharsetSource; + if (mParserContext) { + mParserContext->mScanner.SetDocumentCharset(aCharset, aCharsetSource); + } +} + +void nsParser::SetSinkCharset(NotNull aCharset) { + if (mSink) { + mSink->SetDocumentCharset(aCharset); + } +} + +/** + * This method gets called in order to set the content + * sink for this parser to dump nodes to. + * + * @param nsIContentSink interface for node receiver + */ +NS_IMETHODIMP_(void) +nsParser::SetContentSink(nsIContentSink* aSink) { + MOZ_ASSERT(aSink, "sink cannot be null!"); + mSink = aSink; + + if (mSink) { + mSink->SetParser(this); + nsCOMPtr htmlSink = do_QueryInterface(mSink); + if (htmlSink) { + mIsAboutBlank = true; + } + } +} + +/** + * retrieve the sink set into the parser + * @return current sink + */ +NS_IMETHODIMP_(nsIContentSink*) +nsParser::GetContentSink() { return mSink; } + +//////////////////////////////////////////////////////////////////////// + +/** + * This gets called just prior to the model actually + * being constructed. It's important to make this the + * last thing that happens right before parsing, so we + * can delay until the last moment the resolution of + * which DTD to use (unless of course we're assigned one). + */ +nsresult nsParser::WillBuildModel() { + if (!mParserContext) return NS_ERROR_HTMLPARSER_INVALIDPARSERCONTEXT; + + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + if (eUnknownDetect != mParserContext->mAutoDetectStatus) return NS_OK; + + if (eDTDMode_autodetect == mParserContext->mDTDMode) { + if (mIsAboutBlank) { + mParserContext->mDTDMode = eDTDMode_quirks; + mParserContext->mDocType = eHTML_Quirks; + } else { + mParserContext->mDTDMode = eDTDMode_full_standards; + mParserContext->mDocType = eXML; + } + } // else XML fragment with nested parser context + + // We always find a DTD. + mParserContext->mAutoDetectStatus = ePrimaryDetect; + + // Quick check for view source. + MOZ_ASSERT(mParserContext->mParserCommand != eViewSource, + "The old parser is not supposed to be used for View Source " + "anymore."); + + // Now see if we're parsing XML or HTML (which, as far as we're concerned, + // simply means "not XML"). + if (mParserContext->mDocType == eXML) { + RefPtr expat = new nsExpatDriver(); + nsresult rv = expat->Initialize(mParserContext->mScanner.GetURI(), mSink); + NS_ENSURE_SUCCESS(rv, rv); + + mDTD = expat.forget(); + } else { + mDTD = new CNavDTD(); + } + + return mSink->WillBuildModel(mParserContext->mDTDMode); +} + +/** + * This gets called when the parser is done with its input. + */ +void nsParser::DidBuildModel() { + if (IsComplete() && mParserContext) { + // Let sink know if we're about to end load because we've been terminated. + // In that case we don't want it to run deferred scripts. + bool terminated = mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING; + if (mDTD && mSink) { + mDTD->DidBuildModel(); + mSink->DidBuildModel(terminated); + } + + // Ref. to bug 61462. + mParserContext->mRequest = nullptr; + } +} + +/** + * Call this when you want to *force* the parser to terminate the + * parsing process altogether. This is binary -- so once you terminate + * you can't resume without restarting altogether. + */ +NS_IMETHODIMP +nsParser::Terminate(void) { + // We should only call DidBuildModel once, so don't do anything if this is + // the second time that Terminate has been called. + if (mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING) { + return NS_OK; + } + + nsresult result = NS_OK; + // XXX - [ until we figure out a way to break parser-sink circularity ] + // Hack - Hold a reference until we are completely done... + nsCOMPtr kungFuDeathGrip(this); + mInternalState = result = NS_ERROR_HTMLPARSER_STOPPARSING; + + // @see bug 108049 + // If NS_PARSER_FLAG_PENDING_CONTINUE_EVENT is set then reset it so + // DidBuildModel will call DidBuildModel on the DTD. Note: The IsComplete() + // call inside of DidBuildModel looks at the pendingContinueEvents flag. + if (mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT) { + NS_ASSERTION(mContinueEvent, "mContinueEvent is null"); + // Revoke the pending continue parsing event + mContinueEvent = nullptr; + mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; + } + + if (mDTD) { + mDTD->Terminate(); + DidBuildModel(); + } else if (mSink) { + // We have no parser context or no DTD yet (so we got terminated before we + // got any data). Manually break the reference cycle with the sink. + result = mSink->DidBuildModel(true); + NS_ENSURE_SUCCESS(result, result); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsParser::ContinueInterruptedParsing() { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + // If there are scripts executing, then the content sink is jumping the gun + // (probably due to a synchronous XMLHttpRequest) and will re-enable us + // later, see bug 460706. + if (!IsOkToProcessNetworkData()) { + return NS_OK; + } + + // If the stream has already finished, there's a good chance + // that we might start closing things down when the parser + // is reenabled. To make sure that we're not deleted across + // the reenabling process, hold a reference to ourselves. + nsresult result = NS_OK; + nsCOMPtr kungFuDeathGrip(this); + nsCOMPtr sinkDeathGrip(mSink); + +#ifdef DEBUG + if (mBlocked) { + NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser."); + } +#endif + + bool isFinalChunk = + mParserContext && mParserContext->mStreamListenerState == eOnStop; + + mProcessingNetworkData = true; + if (sinkDeathGrip) { + sinkDeathGrip->WillParse(); + } + result = ResumeParse(true, isFinalChunk); // Ref. bug 57999 + mProcessingNetworkData = false; + + if (result != NS_OK) { + result = mInternalState; + } + + return result; +} + +/** + * Stops parsing temporarily. That is, it will prevent the + * parser from building up content model while scripts + * are being loaded (either an external script from a web + * page, or any number of extension content scripts). + */ +NS_IMETHODIMP_(void) +nsParser::BlockParser() { mBlocked++; } + +/** + * Open up the parser for tokenization, building up content + * model..etc. However, this method does not resume parsing + * automatically. It's the callers' responsibility to restart + * the parsing engine. + */ +NS_IMETHODIMP_(void) +nsParser::UnblockParser() { + MOZ_DIAGNOSTIC_ASSERT(mBlocked > 0); + if (MOZ_LIKELY(mBlocked > 0)) { + mBlocked--; + } +} + +NS_IMETHODIMP_(void) +nsParser::ContinueInterruptedParsingAsync() { + MOZ_ASSERT(mSink); + if (MOZ_LIKELY(mSink)) { + mSink->ContinueInterruptedParsingAsync(); + } +} + +/** + * Call this to query whether the parser is enabled or not. + */ +NS_IMETHODIMP_(bool) +nsParser::IsParserEnabled() { return !mBlocked; } + +/** + * Call this to query whether the parser thinks it's done with parsing. + */ +NS_IMETHODIMP_(bool) +nsParser::IsComplete() { + return !(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT); +} + +void nsParser::HandleParserContinueEvent(nsParserContinueEvent* ev) { + // Ignore any revoked continue events... + if (mContinueEvent != ev) return; + + mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT; + mContinueEvent = nullptr; + + NS_ASSERTION(IsOkToProcessNetworkData(), + "Interrupted in the middle of a script?"); + ContinueInterruptedParsing(); +} + +bool nsParser::IsInsertionPointDefined() { return false; } + +void nsParser::IncrementScriptNestingLevel() {} + +void nsParser::DecrementScriptNestingLevel() {} + +bool nsParser::HasNonzeroScriptNestingLevel() const { return false; } + +bool nsParser::IsScriptCreated() { return false; } + +/** + * This is the main controlling routine in the parsing process. + * Note that it may get called multiple times for the same scanner, + * since this is a pushed based system, and all the tokens may + * not have been consumed by the scanner during a given invocation + * of this method. + */ +NS_IMETHODIMP +nsParser::Parse(nsIURI* aURL) { + MOZ_ASSERT(aURL, "Error: Null URL given"); + + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + if (!aURL) { + return NS_ERROR_HTMLPARSER_BADURL; + } + + MOZ_ASSERT(!mParserContext, "We expect mParserContext to be null."); + + mParserContext = MakeUnique(aURL, mCommand); + + return NS_OK; +} + +/** + * Used by XML fragment parsing below. + * + * @param aSourceBuffer contains a string-full of real content + */ +nsresult nsParser::Parse(const nsAString& aSourceBuffer, bool aLastCall) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + // Don't bother if we're never going to parse this. + if (mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING) { + return NS_OK; + } + + if (!aLastCall && aSourceBuffer.IsEmpty()) { + // Nothing is being passed to the parser so return + // immediately. mUnusedInput will get processed when + // some data is actually passed in. + // But if this is the last call, make sure to finish up + // stuff correctly. + return NS_OK; + } + + // Maintain a reference to ourselves so we don't go away + // till we're completely done. + nsCOMPtr kungFuDeathGrip(this); + + if (!mParserContext) { + // Only make a new context if we don't have one. + mParserContext = + MakeUnique(mUnusedInput, mCommand, aLastCall); + + mUnusedInput.Truncate(); + } else if (aLastCall) { + // Set stream listener state to eOnStop, on the final context - Fix + // 68160, to guarantee DidBuildModel() call - Fix 36148 + mParserContext->mStreamListenerState = eOnStop; + mParserContext->mScanner.SetIncremental(false); + } + + mParserContext->mScanner.Append(aSourceBuffer); + return ResumeParse(false, false, false); +} + +nsresult nsParser::ParseFragment(const nsAString& aSourceBuffer, + nsTArray& aTagStack) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + nsresult result = NS_OK; + nsAutoString theContext; + uint32_t theCount = aTagStack.Length(); + uint32_t theIndex = 0; + + for (theIndex = 0; theIndex < theCount; theIndex++) { + theContext.Append('<'); + theContext.Append(aTagStack[theCount - theIndex - 1]); + theContext.Append('>'); + } + + if (theCount == 0) { + // Ensure that the buffer is not empty. Because none of the DTDs care + // about leading whitespace, this doesn't change the result. + theContext.Assign(' '); + } + + // First, parse the context to build up the DTD's tag stack. Note that we + // pass false for the aLastCall parameter. + result = Parse(theContext, false); + if (NS_FAILED(result)) { + return result; + } + + if (!mSink) { + // Parse must have failed in the XML case and so the sink was killed. + return NS_ERROR_HTMLPARSER_STOPPARSING; + } + + nsCOMPtr fragSink = do_QueryInterface(mSink); + NS_ASSERTION(fragSink, "ParseFragment requires a fragment content sink"); + + fragSink->WillBuildContent(); + // Now, parse the actual content. Note that this is the last call + // for HTML content, but for XML, we will want to build and parse + // the end tags. However, if tagStack is empty, it's the last call + // for XML as well. + if (theCount == 0) { + result = Parse(aSourceBuffer, true); + fragSink->DidBuildContent(); + } else { + // Add an end tag chunk, so expat will read the whole source buffer, + // and not worry about ']]' etc. + result = Parse(aSourceBuffer + u"DidBuildContent(); + + if (NS_SUCCEEDED(result)) { + nsAutoString endContext; + for (theIndex = 0; theIndex < theCount; theIndex++) { + // we already added an end tag chunk above + if (theIndex > 0) { + endContext.AppendLiteral("'); + } + + result = Parse(endContext, true); + } + } + + mParserContext.reset(); + + return result; +} + +/** + * This routine is called to cause the parser to continue parsing its + * underlying stream. This call allows the parse process to happen in + * chunks, such as when the content is push based, and we need to parse in + * pieces. + * + * An interesting change in how the parser gets used has led us to add extra + * processing to this method. The case occurs when the parser is blocked in + * one context, and gets a parse(string) call in another context. In this + * case, the parserContexts are linked. No problem. + * + * The problem is that Parse(string) assumes that it can proceed unabated, + * but if the parser is already blocked that assumption is false. So we + * needed to add a mechanism here to allow the parser to continue to process + * (the pop and free) contexts until 1) it get's blocked again; 2) it runs + * out of contexts. + * + * + * @param allowItertion : set to true if non-script resumption is requested + * @param aIsFinalChunk : tells us when the last chunk of data is provided. + * @return error code -- 0 if ok, non-zero if error. + */ +nsresult nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk, + bool aCanInterrupt) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + nsresult result = NS_OK; + + if (!mBlocked && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { + result = WillBuildModel(); + if (NS_FAILED(result)) { + mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE; + return result; + } + + if (mDTD) { + mSink->WillResume(); + bool theIterationIsOk = true; + + while (result == NS_OK && theIterationIsOk) { + if (!mUnusedInput.IsEmpty()) { + // -- Ref: Bug# 22485 -- + // Insert the unused input into the source buffer + // as if it was read from the input stream. + // Adding UngetReadable() per vidur!! + mParserContext->mScanner.UngetReadable(mUnusedInput); + mUnusedInput.Truncate(0); + } + + // Only allow parsing to be interrupted in the subsequent call to + // build model. + nsresult theTokenizerResult; + if (mFlags & NS_PARSER_FLAG_CAN_TOKENIZE) { + mParserContext->mScanner.Mark(); + if (mParserContext->mDocType == eXML && + mParserContext->mParserCommand != eViewSource) { + nsExpatDriver* expat = static_cast(mDTD.get()); + theTokenizerResult = + expat->ResumeParse(mParserContext->mScanner, aIsFinalChunk); + if (NS_FAILED(theTokenizerResult)) { + mParserContext->mScanner.RewindToMark(); + if (NS_ERROR_HTMLPARSER_STOPPARSING == theTokenizerResult) { + theTokenizerResult = Terminate(); + mSink = nullptr; + } + } + } else { + // Nothing to do for non-XML. Note that this should only be + // about:blank at this point, we're also checking for view-source + // above, but that shouldn't end up here anymore. + theTokenizerResult = NS_ERROR_HTMLPARSER_EOF; + } + } else { + theTokenizerResult = NS_OK; + } + + result = mDTD->BuildModel(mSink); + if (result == NS_ERROR_HTMLPARSER_INTERRUPTED && aIsFinalChunk) { + PostContinueEvent(); + } + + theIterationIsOk = theTokenizerResult != NS_ERROR_HTMLPARSER_EOF && + result != NS_ERROR_HTMLPARSER_INTERRUPTED; + + // Make sure not to stop parsing too early. Therefore, before shutting + // down the parser, it's important to check whether the input buffer + // has been scanned to completion (theTokenizerResult should be kEOF). + // kEOF -> End of buffer. + + // If we're told the parser has been blocked, we disable all further + // parsing (and cache any data coming in) until the parser is + // re-enabled. + if (NS_ERROR_HTMLPARSER_BLOCK == result) { + mSink->WillInterrupt(); + return NS_OK; + } + if (NS_ERROR_HTMLPARSER_STOPPARSING == result) { + // Note: Parser Terminate() calls DidBuildModel. + if (mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { + DidBuildModel(); + mInternalState = result; + } + + return NS_OK; + } + if (((NS_OK == result && + theTokenizerResult == NS_ERROR_HTMLPARSER_EOF) || + result == NS_ERROR_HTMLPARSER_INTERRUPTED) && + mParserContext->mStreamListenerState == eOnStop) { + DidBuildModel(); + return NS_OK; + } + + if (theTokenizerResult == NS_ERROR_HTMLPARSER_EOF || + result == NS_ERROR_HTMLPARSER_INTERRUPTED) { + result = (result == NS_ERROR_HTMLPARSER_INTERRUPTED) ? NS_OK : result; + mSink->WillInterrupt(); + } + } + } else { + mInternalState = result = NS_ERROR_HTMLPARSER_UNRESOLVEDDTD; + } + } + + return (result == NS_ERROR_HTMLPARSER_INTERRUPTED) ? NS_OK : result; +} + +/******************************************************************* + These methods are used to talk to the netlib system... + *******************************************************************/ + +nsresult nsParser::OnStartRequest(nsIRequest* request) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + MOZ_ASSERT(eNone == mParserContext->mStreamListenerState, + "Parser's nsIStreamListener API was not setup " + "correctly in constructor."); + + mParserContext->mStreamListenerState = eOnStart; + mParserContext->mAutoDetectStatus = eUnknownDetect; + mParserContext->mRequest = request; + + mDTD = nullptr; + + nsresult rv; + nsAutoCString contentType; + nsCOMPtr channel = do_QueryInterface(request); + if (channel) { + rv = channel->GetContentType(contentType); + if (NS_SUCCEEDED(rv)) { + mParserContext->SetMimeType(contentType); + } + } + + rv = NS_OK; + + return rv; +} + +static bool ExtractCharsetFromXmlDeclaration(const unsigned char* aBytes, + int32_t aLen, + nsCString& oCharset) { + // This code is rather pointless to have. Might as well reuse expat as + // seen in nsHtml5StreamParser. -- hsivonen + oCharset.Truncate(); + if ((aLen >= 5) && ('<' == aBytes[0]) && ('?' == aBytes[1]) && + ('x' == aBytes[2]) && ('m' == aBytes[3]) && ('l' == aBytes[4])) { + int32_t i; + bool versionFound = false, encodingFound = false; + for (i = 6; i < aLen && !encodingFound; ++i) { + // end of XML declaration? + if ((((char*)aBytes)[i] == '?') && ((i + 1) < aLen) && + (((char*)aBytes)[i + 1] == '>')) { + break; + } + // Version is required. + if (!versionFound) { + // Want to avoid string comparisons, hence looking for 'n' + // and only if found check the string leading to it. Not + // foolproof, but fast. + // The shortest string allowed before this is (strlen==13): + // = 12) && + (0 == strncmp("versio", (char*)(aBytes + i - 6), 6))) { + // Fast forward through version + char q = 0; + for (++i; i < aLen; ++i) { + char qi = ((char*)aBytes)[i]; + if (qi == '\'' || qi == '"') { + if (q && q == qi) { + // ending quote + versionFound = true; + break; + } else { + // Starting quote + q = qi; + } + } + } + } + } else { + // encoding must follow version + // Want to avoid string comparisons, hence looking for 'g' + // and only if found check the string leading to it. Not + // foolproof, but fast. + // The shortest allowed string before this (strlen==26): + // = 25) && + (0 == strncmp("encodin", (char*)(aBytes + i - 7), 7))) { + int32_t encStart = 0; + char q = 0; + for (++i; i < aLen; ++i) { + char qi = ((char*)aBytes)[i]; + if (qi == '\'' || qi == '"') { + if (q && q == qi) { + int32_t count = i - encStart; + // encoding value is invalid if it is UTF-16 + if (count > 0 && + PL_strncasecmp("UTF-16", (char*)(aBytes + encStart), + count)) { + oCharset.Assign((char*)(aBytes + encStart), count); + } + encodingFound = true; + break; + } else { + encStart = i + 1; + q = qi; + } + } + } + } + } // if (!versionFound) + } // for + } + return !oCharset.IsEmpty(); +} + +inline char GetNextChar(nsACString::const_iterator& aStart, + nsACString::const_iterator& aEnd) { + NS_ASSERTION(aStart != aEnd, "end of buffer"); + return (++aStart != aEnd) ? *aStart : '\0'; +} + +static nsresult NoOpParserWriteFunc(nsIInputStream* in, void* closure, + const char* fromRawSegment, + uint32_t toOffset, uint32_t count, + uint32_t* writeCount) { + *writeCount = count; + return NS_OK; +} + +typedef struct { + bool mNeedCharsetCheck; + nsParser* mParser; + nsScanner* mScanner; + nsIRequest* mRequest; +} ParserWriteStruct; + +/* + * This function is invoked as a result of a call to a stream's + * ReadSegments() method. It is called for each contiguous buffer + * of data in the underlying stream or pipe. Using ReadSegments + * allows us to avoid copying data to read out of the stream. + */ +static nsresult ParserWriteFunc(nsIInputStream* in, void* closure, + const char* fromRawSegment, uint32_t toOffset, + uint32_t count, uint32_t* writeCount) { + nsresult result; + ParserWriteStruct* pws = static_cast(closure); + const unsigned char* buf = + reinterpret_cast(fromRawSegment); + uint32_t theNumRead = count; + + if (!pws) { + return NS_ERROR_FAILURE; + } + + if (pws->mNeedCharsetCheck) { + pws->mNeedCharsetCheck = false; + int32_t source; + auto preferred = pws->mParser->GetDocumentCharset(source); + + // This code was bogus when I found it. It expects the BOM or the XML + // declaration to be entirely in the first network buffer. -- hsivonen + const Encoding* encoding; + std::tie(encoding, std::ignore) = Encoding::ForBOM(Span(buf, count)); + if (encoding) { + // The decoder will swallow the BOM. The UTF-16 will re-sniff for + // endianness. The value of preferred is now "UTF-8", "UTF-16LE" + // or "UTF-16BE". + preferred = WrapNotNull(encoding); + source = kCharsetFromByteOrderMark; + } else if (source < kCharsetFromChannel) { + nsAutoCString declCharset; + + if (ExtractCharsetFromXmlDeclaration(buf, count, declCharset)) { + encoding = Encoding::ForLabel(declCharset); + if (encoding) { + preferred = WrapNotNull(encoding); + source = kCharsetFromMetaTag; + } + } + } + + pws->mParser->SetDocumentCharset(preferred, source, false); + pws->mParser->SetSinkCharset(preferred); + } + + result = pws->mScanner->Append(fromRawSegment, theNumRead); + if (NS_SUCCEEDED(result)) { + *writeCount = count; + } + + return result; +} + +nsresult nsParser::OnDataAvailable(nsIRequest* request, + nsIInputStream* pIStream, + uint64_t sourceOffset, uint32_t aLength) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + MOZ_ASSERT((eOnStart == mParserContext->mStreamListenerState || + eOnDataAvail == mParserContext->mStreamListenerState), + "Error: OnStartRequest() must be called before OnDataAvailable()"); + MOZ_ASSERT(NS_InputStreamIsBuffered(pIStream), + "Must have a buffered input stream"); + + nsresult rv = NS_OK; + + if (mIsAboutBlank) { + MOZ_ASSERT(false, "Must not get OnDataAvailable for about:blank"); + // ... but if an extension tries to feed us data for about:blank in a + // release build, silently ignore the data. + uint32_t totalRead; + rv = pIStream->ReadSegments(NoOpParserWriteFunc, nullptr, aLength, + &totalRead); + return rv; + } + + if (mParserContext->mRequest == request) { + mParserContext->mStreamListenerState = eOnDataAvail; + + uint32_t totalRead; + ParserWriteStruct pws; + pws.mNeedCharsetCheck = true; + pws.mParser = this; + pws.mScanner = &mParserContext->mScanner; + pws.mRequest = request; + + rv = pIStream->ReadSegments(ParserWriteFunc, &pws, aLength, &totalRead); + if (NS_FAILED(rv)) { + return rv; + } + + if (IsOkToProcessNetworkData()) { + nsCOMPtr kungFuDeathGrip(this); + nsCOMPtr sinkDeathGrip(mSink); + mProcessingNetworkData = true; + if (sinkDeathGrip) { + sinkDeathGrip->WillParse(); + } + rv = ResumeParse(); + mProcessingNetworkData = false; + } + } else { + rv = NS_ERROR_UNEXPECTED; + } + + return rv; +} + +/** + * This is called by the networking library once the last block of data + * has been collected from the net. + */ +nsresult nsParser::OnStopRequest(nsIRequest* request, nsresult status) { + if (mInternalState == NS_ERROR_OUT_OF_MEMORY) { + // Checking NS_ERROR_OUT_OF_MEMORY instead of NS_FAILED + // to avoid introducing unintentional changes to behavior. + return mInternalState; + } + + nsresult rv = NS_OK; + + if (mParserContext->mRequest == request) { + mParserContext->mStreamListenerState = eOnStop; + mParserContext->mScanner.SetIncremental(false); + } + + mStreamStatus = status; + + if (IsOkToProcessNetworkData() && NS_SUCCEEDED(rv)) { + mProcessingNetworkData = true; + if (mSink) { + mSink->WillParse(); + } + rv = ResumeParse(true, true); + mProcessingNetworkData = false; + } + + // If the parser isn't enabled, we don't finish parsing till + // it is reenabled. + + return rv; +} + +/** + * Get this as nsIStreamListener + */ +nsIStreamListener* nsParser::GetStreamListener() { return this; } diff --git a/parser/htmlparser/nsParser.h b/parser/htmlparser/nsParser.h new file mode 100644 index 0000000000..95782e954b --- /dev/null +++ b/parser/htmlparser/nsParser.h @@ -0,0 +1,312 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * MODULE NOTES: + * + * This class does two primary jobs: + * 1) It iterates the tokens provided during the + * tokenization process, identifing where elements + * begin and end (doing validation and normalization). + * 2) It controls and coordinates with an instance of + * the IContentSink interface, to coordinate the + * the production of the content model. + * + * The basic operation of this class assumes that an HTML + * document is non-normalized. Therefore, we don't process + * the document in a normalized way. Don't bother to look + * for methods like: doHead() or doBody(). + * + * Instead, in order to be backward compatible, we must + * scan the set of tokens and perform this basic set of + * operations: + * 1) Determine the token type (easy, since the tokens know) + * 2) Determine the appropriate section of the HTML document + * each token belongs in (HTML,HEAD,BODY,FRAMESET). + * 3) Insert content into our document (via the sink) into + * the correct section. + * 4) In the case of tags that belong in the BODY, we must + * ensure that our underlying document state reflects + * the appropriate context for our tag. + * + * For example,if we see a , we must ensure our + * document contains a table into which the row can + * be placed. This may result in "implicit containers" + * created to ensure a well-formed document. + * + */ + +#ifndef NS_PARSER__ +#define NS_PARSER__ + +#include "nsIParser.h" +#include "nsDeque.h" +#include "CParserContext.h" +#include "nsHTMLTags.h" +#include "nsIContentSink.h" +#include "nsCOMArray.h" +#include "nsCycleCollectionParticipant.h" +#include "nsWeakReference.h" +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" + +class nsIDTD; +class nsIRunnable; + +#ifdef _MSC_VER +# pragma warning(disable : 4275) +#endif + +class nsParser final : public nsIParser, + public nsIStreamListener, + public nsSupportsWeakReference { + /** + * Destructor + * @update gess5/11/98 + */ + virtual ~nsParser(); + + public: + /** + * Called on module init + */ + static nsresult Init(); + + /** + * Called on module shutdown + */ + static void Shutdown(); + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsParser, nsIParser) + + /** + * default constructor + * @update gess5/11/98 + */ + nsParser(); + + /** + * Select given content sink into parser for parser output + * @update gess5/11/98 + * @param aSink is the new sink to be used by parser + * @return old sink, or nullptr + */ + NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) override; + + /** + * retrive the sink set into the parser + * @update gess5/11/98 + * @param aSink is the new sink to be used by parser + * @return old sink, or nullptr + */ + NS_IMETHOD_(nsIContentSink*) GetContentSink(void) override; + + /** + * Call this method once you've created a parser, and want to instruct it + * about the command which caused the parser to be constructed. For example, + * this allows us to select a DTD which can do, say, view-source. + * + * @update gess 3/25/98 + * @param aCommand -- ptrs to string that contains command + * @return nada + */ + NS_IMETHOD_(void) GetCommand(nsCString& aCommand) override; + NS_IMETHOD_(void) SetCommand(const char* aCommand) override; + NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override; + + /** + * Call this method once you've created a parser, and want to instruct it + * about what charset to load + * + * @update ftang 4/23/99 + * @param aCharset- the charset of a document + * @param aCharsetSource- the source of the charset + * @param aChannelHadCharset- ignored + * @return nada + */ + virtual void SetDocumentCharset(NotNull aCharset, + int32_t aSource, + bool aForceAutoDetection) override; + + NotNull GetDocumentCharset(int32_t& aSource) { + aSource = mCharsetSource; + return mCharset; + } + + /** + * Cause parser to parse input from given URL + */ + NS_IMETHOD Parse(nsIURI* aURL) override; + + /** + * This method gets called when you want to parse a fragment of XML surrounded + * by the context |aTagStack|. It requires that the parser have been given a + * fragment content sink. + * + * @param aSourceBuffer The XML that hasn't been parsed yet. + * @param aTagStack The context of the source buffer. + */ + nsresult ParseFragment(const nsAString& aSourceBuffer, + nsTArray& aTagStack); + + NS_IMETHOD ContinueInterruptedParsing() override; + NS_IMETHOD_(void) BlockParser() override; + NS_IMETHOD_(void) UnblockParser() override; + NS_IMETHOD_(void) ContinueInterruptedParsingAsync() override; + NS_IMETHOD Terminate(void) override; + + /** + * Call this to query whether the parser is enabled or not. + * + * @update vidur 4/12/99 + * @return current state + */ + NS_IMETHOD_(bool) IsParserEnabled() override; + + /** + * Call this to query whether the parser thinks it's done with parsing. + * + * @update rickg 5/12/01 + * @return complete state + */ + NS_IMETHOD_(bool) IsComplete() override; + + /** + * This method gets called (automatically) during incremental parsing + * @update gess5/11/98 + * @return TRUE if all went well, otherwise FALSE + */ + virtual nsresult ResumeParse(bool allowIteration = true, + bool aIsFinalChunk = false, + bool aCanInterrupt = true); + + //********************************************* + // These methods are callback methods used by + // net lib to let us know about our inputstream. + //********************************************* + // nsIRequestObserver methods: + NS_DECL_NSIREQUESTOBSERVER + + // nsIStreamListener methods: + NS_DECL_NSISTREAMLISTENER + + /** + * Get the nsIStreamListener for this parser + */ + virtual nsIStreamListener* GetStreamListener() override; + + void SetSinkCharset(NotNull aCharset); + + /** + * Return true. + */ + virtual bool IsInsertionPointDefined() override; + + /** + * No-op. + */ + void IncrementScriptNestingLevel() final; + + /** + * No-op. + */ + void DecrementScriptNestingLevel() final; + + bool HasNonzeroScriptNestingLevel() const final; + + /** + * Always false. + */ + virtual bool IsScriptCreated() override; + + /** + * This is called when the final chunk has been + * passed to the parser and the content sink has + * interrupted token processing. It schedules + * a ParserContinue PL_Event which will ask the parser + * to HandleParserContinueEvent when it is handled. + * @update kmcclusk6/1/2001 + */ + nsresult PostContinueEvent(); + + /** + * Fired when the continue parse event is triggered. + * @update kmcclusk 5/18/98 + */ + void HandleParserContinueEvent(class nsParserContinueEvent*); + + void Reset() { + Cleanup(); + mUnusedInput.Truncate(); + Initialize(); + } + + bool IsScriptExecuting() { return mSink && mSink->IsScriptExecuting(); } + + bool IsOkToProcessNetworkData() { + return !IsScriptExecuting() && !mProcessingNetworkData; + } + + // Returns Nothing() if we haven't determined yet what the parser is being + // used for. Else returns whether this parser is used for parsing XML. + mozilla::Maybe IsForParsingXML() { + if (!mParserContext || mParserContext->mDTDMode == eDTDMode_autodetect) { + return mozilla::Nothing(); + } + + return mozilla::Some(mParserContext->mDocType == eXML); + } + + protected: + void Initialize(); + void Cleanup(); + + /** + * + * @update gess5/18/98 + * @param + * @return + */ + nsresult WillBuildModel(); + + /** + * Called when parsing is done. + */ + void DidBuildModel(); + + private: + /** + * Pushes XML fragment parsing data to expat without an input stream. + */ + nsresult Parse(const nsAString& aSourceBuffer, bool aLastCall); + + protected: + //********************************************* + // And now, some data members... + //********************************************* + + mozilla::UniquePtr mParserContext; + nsCOMPtr mDTD; + nsCOMPtr mSink; + nsIRunnable* mContinueEvent; // weak ref + + eParserCommands mCommand; + nsresult mInternalState; + nsresult mStreamStatus; + int32_t mCharsetSource; + + uint16_t mFlags; + uint32_t mBlocked; + + nsString mUnusedInput; + NotNull mCharset; + nsCString mCommandStr; + + bool mProcessingNetworkData; + bool mIsAboutBlank; +}; + +#endif diff --git a/parser/htmlparser/nsParserBase.h b/parser/htmlparser/nsParserBase.h new file mode 100644 index 0000000000..7d82f6f7d8 --- /dev/null +++ b/parser/htmlparser/nsParserBase.h @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsParserBase_h_ +#define nsParserBase_h_ + +#include "nsIChannel.h" + +class nsParserBase : public nsISupports { + public: + NS_IMETHOD_(bool) IsParserEnabled() { return true; } + NS_IMETHOD_(bool) IsParserClosed() { return false; } +}; + +#endif // nsParserBase_h_ diff --git a/parser/htmlparser/nsParserConstants.h b/parser/htmlparser/nsParserConstants.h new file mode 100644 index 0000000000..bd6e4d477d --- /dev/null +++ b/parser/htmlparser/nsParserConstants.h @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsParserConstants_h_ +#define nsParserConstants_h_ + +const char16_t kSpace = ' '; +const char16_t kQuote = '"'; +const char16_t kApostrophe = '\''; +const char16_t kLessThan = '<'; +const char16_t kGreaterThan = '>'; +const char16_t kAmpersand = '&'; +const char16_t kBackSlash = '\\'; +const char16_t kEqual = '='; +const char16_t kSemicolon = ';'; +const char16_t kComma = ','; +const char16_t kNullCh = '\0'; + +#endif // nsParserConstants_h_ diff --git a/parser/htmlparser/nsParserMsgUtils.cpp b/parser/htmlparser/nsParserMsgUtils.cpp new file mode 100644 index 0000000000..a629bcc5e3 --- /dev/null +++ b/parser/htmlparser/nsParserMsgUtils.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIStringBundle.h" +#include "nsString.h" +#include "nsParserMsgUtils.h" +#include "nsNetCID.h" +#include "mozilla/Components.h" + +static nsresult GetBundle(const char* aPropFileName, + nsIStringBundle** aBundle) { + NS_ENSURE_ARG_POINTER(aPropFileName); + NS_ENSURE_ARG_POINTER(aBundle); + + // Create a bundle for the localization + + nsCOMPtr stringService = + mozilla::components::StringBundle::Service(); + if (!stringService) return NS_ERROR_FAILURE; + + return stringService->CreateBundle(aPropFileName, aBundle); +} + +nsresult nsParserMsgUtils::GetLocalizedStringByName(const char* aPropFileName, + const char* aKey, + nsString& oVal) { + oVal.Truncate(); + + NS_ENSURE_ARG_POINTER(aKey); + + nsCOMPtr bundle; + nsresult rv = GetBundle(aPropFileName, getter_AddRefs(bundle)); + if (NS_SUCCEEDED(rv) && bundle) { + nsAutoString valUni; + rv = bundle->GetStringFromName(aKey, valUni); + if (NS_SUCCEEDED(rv)) { + oVal.Assign(valUni); + } + } + + return rv; +} + +nsresult nsParserMsgUtils::GetLocalizedStringByID(const char* aPropFileName, + uint32_t aID, + nsString& oVal) { + oVal.Truncate(); + + nsCOMPtr bundle; + nsresult rv = GetBundle(aPropFileName, getter_AddRefs(bundle)); + if (NS_SUCCEEDED(rv) && bundle) { + nsAutoString valUni; + rv = bundle->GetStringFromID(aID, valUni); + if (NS_SUCCEEDED(rv)) { + oVal.Assign(valUni); + } + } + + return rv; +} diff --git a/parser/htmlparser/nsParserMsgUtils.h b/parser/htmlparser/nsParserMsgUtils.h new file mode 100644 index 0000000000..3645610385 --- /dev/null +++ b/parser/htmlparser/nsParserMsgUtils.h @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsParserMsgUtils_h +#define nsParserMsgUtils_h + +#include "nsString.h" + +#define XMLPARSER_PROPERTIES \ + "chrome://global/locale/layout/xmlparser.properties" + +#define XMLPARSER_PROPERTIES_en_US \ + "resource://gre/res/locale/layout/xmlparser.properties" + +class nsParserMsgUtils { + nsParserMsgUtils(); // Currently this is not meant to be created, use the + // static methods + ~nsParserMsgUtils(); // If perf required, change this to cache values etc. + public: + static nsresult GetLocalizedStringByName(const char* aPropFileName, + const char* aKey, nsString& aVal); + static nsresult GetLocalizedStringByID(const char* aPropFileName, + uint32_t aID, nsString& aVal); +}; + +#endif diff --git a/parser/htmlparser/nsRLBoxExpatDriver.h b/parser/htmlparser/nsRLBoxExpatDriver.h new file mode 100644 index 0000000000..84236f3365 --- /dev/null +++ b/parser/htmlparser/nsRLBoxExpatDriver.h @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef NS_RLBOX_EXPAT_DRIVER__ +#define NS_RLBOX_EXPAT_DRIVER__ + +#include "mozilla/RLBoxSandboxPool.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/UniquePtr.h" + +class RLBoxExpatSandboxPool : public mozilla::RLBoxSandboxPool { + public: + explicit RLBoxExpatSandboxPool(size_t aDelaySeconds) + : RLBoxSandboxPool(aDelaySeconds) {} + + static mozilla::StaticRefPtr sSingleton; + static void Initialize(size_t aDelaySeconds = 10); + + protected: + mozilla::UniquePtr CreateSandboxData( + uint64_t aSize) override; + ~RLBoxExpatSandboxPool() = default; +}; + +#endif diff --git a/parser/htmlparser/nsScanner.cpp b/parser/htmlparser/nsScanner.cpp new file mode 100644 index 0000000000..36a14e1083 --- /dev/null +++ b/parser/htmlparser/nsScanner.cpp @@ -0,0 +1,331 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// #define __INCREMENTAL 1 + +#include "nsScanner.h" + +#include "mozilla/Attributes.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Encoding.h" +#include "mozilla/UniquePtr.h" +#include "nsDebug.h" +#include "nsReadableUtils.h" +#include "nsUTF8Utils.h" // for LossyConvertEncoding +#include "nsCRT.h" +#include "nsParser.h" +#include "nsCharsetSource.h" + +nsReadEndCondition::nsReadEndCondition(const char16_t* aTerminateChars) + : mChars(aTerminateChars), + mFilter(char16_t(~0)) // All bits set +{ + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because terminal chars often have only the last 4-6 bits set and + // normal ascii letters have bit 7 set. Other letters have even higher + // bits set. + + // Calculate filter + const char16_t* current = aTerminateChars; + char16_t terminalChar = *current; + while (terminalChar) { + mFilter &= ~terminalChar; + ++current; + terminalChar = *current; + } +} + +/** + * Use this constructor if you want i/o to be based on + * a single string you hand in during construction. + * This short cut was added for Javascript. + * + * @update gess 5/12/98 + * @param aMode represents the parser mode (nav, other) + * @return + */ +nsScanner::nsScanner(const nsAString& anHTMLString, bool aIncremental) + : mIncremental(aIncremental) { + MOZ_COUNT_CTOR(nsScanner); + + AppendToBuffer(anHTMLString); + MOZ_ASSERT(mMarkPosition == mCurrentPosition); +} + +/** + * Use this constructor if you want i/o to be based on strings + * the scanner receives. If you pass a null filename, you + * can still provide data to the scanner via append. + */ +nsScanner::nsScanner(nsIURI* aURI) : mURI(aURI), mIncremental(true) { + MOZ_COUNT_CTOR(nsScanner); + + // XXX This is a big hack. We need to initialize the iterators to something. + // What matters is that mCurrentPosition == mEndPosition, so that our methods + // believe that we are at EOF (see bug 182067). We null out mCurrentPosition + // so that we have some hope of catching null pointer dereferences associated + // with this hack. --darin + memset(&mCurrentPosition, 0, sizeof(mCurrentPosition)); + mMarkPosition = mCurrentPosition; + mEndPosition = mCurrentPosition; + + // XML defaults to UTF-8 and about:blank is UTF-8, too. + SetDocumentCharset(UTF_8_ENCODING, kCharsetFromDocTypeDefault); +} + +nsresult nsScanner::SetDocumentCharset(NotNull aEncoding, + int32_t aSource) { + if (aSource < mCharsetSource) // priority is lower than the current one + return NS_OK; + + mCharsetSource = aSource; + nsCString charsetName; + aEncoding->Name(charsetName); + if (!mCharset.IsEmpty() && charsetName.Equals(mCharset)) { + return NS_OK; // no difference, don't change it + } + + // different, need to change it + + mCharset.Assign(charsetName); + + mUnicodeDecoder = aEncoding->NewDecoderWithBOMRemoval(); + + return NS_OK; +} + +/** + * default destructor + * + * @update gess 3/25/98 + * @param + * @return + */ +nsScanner::~nsScanner() { MOZ_COUNT_DTOR(nsScanner); } + +/** + * Resets current offset position of input stream to marked position. + * This allows us to back up to this point if the need should arise, + * such as when tokenization gets interrupted. + * NOTE: IT IS REALLY BAD FORM TO CALL RELEASE WITHOUT CALLING MARK FIRST! + * + * @update gess 5/12/98 + * @param + * @return + */ +void nsScanner::RewindToMark(void) { + if (mSlidingBuffer) { + mCurrentPosition = mMarkPosition; + } +} + +/** + * Records current offset position in input stream. This allows us + * to back up to this point if the need should arise, such as when + * tokenization gets interrupted. + * + * @update gess 7/29/98 + * @param + * @return + */ +int32_t nsScanner::Mark() { + int32_t distance = 0; + if (mSlidingBuffer) { + nsScannerIterator oldStart; + mSlidingBuffer->BeginReading(oldStart); + + distance = Distance(oldStart, mCurrentPosition); + + mSlidingBuffer->DiscardPrefix(mCurrentPosition); + mSlidingBuffer->BeginReading(mCurrentPosition); + mMarkPosition = mCurrentPosition; + } + + return distance; +} + +/** + * Insert data to our underlying input buffer as + * if it were read from an input stream. + * + * @update harishd 01/12/99 + * @return error code + */ +bool nsScanner::UngetReadable(const nsAString& aBuffer) { + if (!mSlidingBuffer) { + return false; + } + + mSlidingBuffer->UngetReadable(aBuffer, mCurrentPosition); + mSlidingBuffer->BeginReading( + mCurrentPosition); // Insertion invalidated our iterators + mSlidingBuffer->EndReading(mEndPosition); + + return true; +} + +/** + * Append data to our underlying input buffer as + * if it were read from an input stream. + * + * @update gess4/3/98 + * @return error code + */ +nsresult nsScanner::Append(const nsAString& aBuffer) { + if (!AppendToBuffer(aBuffer)) return NS_ERROR_OUT_OF_MEMORY; + return NS_OK; +} + +/** + * + * + * @update gess 5/21/98 + * @param + * @return + */ +nsresult nsScanner::Append(const char* aBuffer, uint32_t aLen) { + nsresult res = NS_OK; + if (mUnicodeDecoder) { + mozilla::CheckedInt needed = + mUnicodeDecoder->MaxUTF16BufferLength(aLen); + if (!needed.isValid()) { + return NS_ERROR_OUT_OF_MEMORY; + } + mozilla::CheckedInt allocLen( + 1); // null terminator due to legacy sadness + allocLen += needed.value(); + if (!allocLen.isValid()) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsScannerString::Buffer* buffer = + nsScannerString::AllocBuffer(allocLen.value()); + NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY); + char16_t* unichars = buffer->DataStart(); + + uint32_t result; + size_t read; + size_t written; + // Do not use structured binding lest deal with [-Werror=unused-variable] + std::tie(result, read, written) = + mUnicodeDecoder->DecodeToUTF16WithoutReplacement( + AsBytes(mozilla::Span(aBuffer, aLen)), + mozilla::Span(unichars, needed.value()), + false); // Retain bug about failure to handle EOF + MOZ_ASSERT(result != mozilla::kOutputFull); + MOZ_ASSERT(read <= aLen); + MOZ_ASSERT(written <= needed.value()); + if (result != mozilla::kInputEmpty) { + // Since about:blank is empty, this line runs only for XML. Use a + // character that's illegal in XML instead of U+FFFD in order to make + // expat flag the error. There is no need to loop and convert more, since + // expat will stop here anyway. + unichars[written++] = 0xFFFF; + } + buffer->SetDataLength(written); + // Don't propagate return code of unicode decoder + // since it doesn't reflect on our success or failure + // - Ref. bug 87110 + res = NS_OK; + AppendToBuffer(buffer); + } else { + NS_WARNING("No decoder found."); + res = NS_ERROR_FAILURE; + } + + return res; +} + +/** + * retrieve next char from scanners internal input stream + * + * @update gess 3/25/98 + * @param + * @return error code reflecting read status + */ +nsresult nsScanner::GetChar(char16_t& aChar) { + if (!mSlidingBuffer || mCurrentPosition == mEndPosition) { + aChar = 0; + return NS_ERROR_HTMLPARSER_EOF; + } + + aChar = *mCurrentPosition++; + + return NS_OK; +} + +void nsScanner::BindSubstring(nsScannerSubstring& aSubstring, + const nsScannerIterator& aStart, + const nsScannerIterator& aEnd) { + aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd); +} + +void nsScanner::CurrentPosition(nsScannerIterator& aPosition) { + aPosition = mCurrentPosition; +} + +void nsScanner::EndReading(nsScannerIterator& aPosition) { + aPosition = mEndPosition; +} + +void nsScanner::SetPosition(nsScannerIterator& aPosition, bool aTerminate) { + if (mSlidingBuffer) { + mCurrentPosition = aPosition; + if (aTerminate && (mCurrentPosition == mEndPosition)) { + mMarkPosition = mCurrentPosition; + mSlidingBuffer->DiscardPrefix(mCurrentPosition); + } + } +} + +void nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf) { + if (!mSlidingBuffer) { + mSlidingBuffer = mozilla::MakeUnique(aBuf); + mSlidingBuffer->BeginReading(mCurrentPosition); + mMarkPosition = mCurrentPosition; + } else { + mSlidingBuffer->AppendBuffer(aBuf); + if (mCurrentPosition == mEndPosition) { + mSlidingBuffer->BeginReading(mCurrentPosition); + } + } + mSlidingBuffer->EndReading(mEndPosition); +} + +/** + * call this to copy bytes out of the scanner that have not yet been consumed + * by the tokenization process. + * + * @update gess 5/12/98 + * @param aCopyBuffer is where the scanner buffer will be copied to + * @return true if OK or false on OOM + */ +bool nsScanner::CopyUnusedData(nsString& aCopyBuffer) { + if (!mSlidingBuffer) { + aCopyBuffer.Truncate(); + return true; + } + + nsScannerIterator start, end; + start = mCurrentPosition; + end = mEndPosition; + + return CopyUnicodeTo(start, end, aCopyBuffer); +} + +/** + * Conduct self test. Actually, selftesting for this class + * occurs in the parser selftest. + * + * @update gess 3/25/98 + * @param + * @return + */ + +void nsScanner::SelfTest(void) { +#ifdef _DEBUG +#endif +} diff --git a/parser/htmlparser/nsScanner.h b/parser/htmlparser/nsScanner.h new file mode 100644 index 0000000000..ca0e51bc5e --- /dev/null +++ b/parser/htmlparser/nsScanner.h @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * MODULE NOTES: + * @update gess 4/1/98 + * + * The scanner is a low-level service class that knows + * how to consume characters out of an (internal) stream. + * This class also offers a series of utility methods + * that most tokenizers want, such as readUntil() + * and SkipWhitespace(). + */ + +#ifndef SCANNER +#define SCANNER + +#include "nsCharsetSource.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsIParser.h" +#include "mozilla/Encoding.h" +#include "nsScannerString.h" +#include "mozilla/CheckedInt.h" + +class nsReadEndCondition { + public: + const char16_t* mChars; + char16_t mFilter; + explicit nsReadEndCondition(const char16_t* aTerminateChars); + + private: + nsReadEndCondition(const nsReadEndCondition& aOther); // No copying + void operator=(const nsReadEndCondition& aOther); // No assigning +}; + +class nsScanner final { + using Encoding = mozilla::Encoding; + template + using NotNull = mozilla::NotNull; + + public: + /** + * Use this constructor for the XML fragment parsing case + */ + nsScanner(const nsAString& anHTMLString, bool aIncremental); + + /** + * Use this constructor if you want i/o to be based on + * a file (therefore a stream) or just data you provide via Append(). + */ + explicit nsScanner(nsIURI* aURI); + + ~nsScanner(); + + /** + * retrieve next char from internal input stream + * + * @update gess 3/25/98 + * @param ch is the char to accept new value + * @return error code reflecting read status + */ + nsresult GetChar(char16_t& ch); + + /** + * Records current offset position in input stream. This allows us + * to back up to this point if the need should arise, such as when + * tokenization gets interrupted. + * + * @update gess 5/12/98 + * @param + * @return + */ + int32_t Mark(void); + + /** + * Resets current offset position of input stream to marked position. + * This allows us to back up to this point if the need should arise, + * such as when tokenization gets interrupted. + * NOTE: IT IS REALLY BAD FORM TO CALL RELEASE WITHOUT CALLING MARK FIRST! + * + * @update gess 5/12/98 + * @param + * @return + */ + void RewindToMark(void); + + /** + * + * + * @update harishd 01/12/99 + * @param + * @return + */ + bool UngetReadable(const nsAString& aBuffer); + + /** + * + * + * @update gess 5/13/98 + * @param + * @return + */ + nsresult Append(const nsAString& aBuffer); + + /** + * + * + * @update gess 5/21/98 + * @param + * @return + */ + nsresult Append(const char* aBuffer, uint32_t aLen); + + /** + * Call this to copy bytes out of the scanner that have not yet been consumed + * by the tokenization process. + * + * @update gess 5/12/98 + * @param aCopyBuffer is where the scanner buffer will be copied to + * @return true if OK or false on OOM + */ + bool CopyUnusedData(nsString& aCopyBuffer); + + /** + * Retrieve the URI of the file that the scanner is reading from. + * In some cases, it's just a given name, because the scanner isn't + * really reading from a file. + */ + nsIURI* GetURI(void) const { return mURI; } + + static void SelfTest(); + + /** + * Use this setter to change the scanner's unicode decoder + * + * @update ftang 3/02/99 + * @param aCharset a normalized (alias resolved) charset name + * @param aCharsetSource- where the charset info came from + * @return + */ + nsresult SetDocumentCharset(NotNull aEncoding, + int32_t aSource); + + void BindSubstring(nsScannerSubstring& aSubstring, + const nsScannerIterator& aStart, + const nsScannerIterator& aEnd); + void CurrentPosition(nsScannerIterator& aPosition); + void EndReading(nsScannerIterator& aPosition); + void SetPosition(nsScannerIterator& aPosition, bool aTruncate = false); + + /** + * Internal method used to cause the internal buffer to + * be filled with data. + * + * @update gess4/3/98 + */ + bool IsIncremental(void) { return mIncremental; } + void SetIncremental(bool anIncrValue) { mIncremental = anIncrValue; } + + protected: + void AppendToBuffer(nsScannerString::Buffer* aBuffer); + bool AppendToBuffer(const nsAString& aStr) { + nsScannerString::Buffer* buf = nsScannerString::AllocBufferFromString(aStr); + if (!buf) return false; + AppendToBuffer(buf); + return true; + } + + mozilla::UniquePtr mSlidingBuffer; + nsScannerIterator mCurrentPosition; // The position we will next read from in + // the scanner buffer + nsScannerIterator + mMarkPosition; // The position last marked (we may rewind to here) + nsScannerIterator mEndPosition; // The current end of the scanner buffer + nsCOMPtr mURI; + bool mIncremental; + int32_t mCharsetSource = kCharsetUninitialized; + nsCString mCharset; + mozilla::UniquePtr mUnicodeDecoder; + + private: + nsScanner& operator=(const nsScanner&); // Not implemented. +}; + +#endif diff --git a/parser/htmlparser/nsScannerString.cpp b/parser/htmlparser/nsScannerString.cpp new file mode 100644 index 0000000000..2c7f09cfdd --- /dev/null +++ b/parser/htmlparser/nsScannerString.cpp @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "nsScannerString.h" +#include "mozilla/CheckedInt.h" + +/** + * nsScannerBufferList + */ + +#define MAX_CAPACITY \ + ((UINT32_MAX / sizeof(char16_t)) - (sizeof(Buffer) + sizeof(char16_t))) + +nsScannerBufferList::Buffer* nsScannerBufferList::AllocBufferFromString( + const nsAString& aString) { + uint32_t len = aString.Length(); + Buffer* buf = AllocBuffer(len); + + if (buf) { + nsAString::const_iterator source; + aString.BeginReading(source); + nsCharTraits::copy(buf->DataStart(), source.get(), len); + } + return buf; +} + +nsScannerBufferList::Buffer* nsScannerBufferList::AllocBuffer( + uint32_t capacity) { + if (capacity > MAX_CAPACITY) return nullptr; + + void* ptr = malloc(sizeof(Buffer) + (capacity + 1) * sizeof(char16_t)); + if (!ptr) return nullptr; + + Buffer* buf = new (ptr) Buffer(); + + buf->mUsageCount = 0; + buf->mDataEnd = buf->DataStart() + capacity; + + // XXX null terminate. this shouldn't be required, but we do it because + // nsScanner erroneously thinks it can dereference DataEnd :-( + *buf->mDataEnd = char16_t(0); + return buf; +} + +void nsScannerBufferList::ReleaseAll() { + while (!mBuffers.isEmpty()) { + Buffer* node = mBuffers.popFirst(); + // printf(">>> freeing buffer @%p\n", node); + free(node); + } +} + +void nsScannerBufferList::SplitBuffer(const Position& pos) { + // splitting to the right keeps the work string and any extant token + // pointing to and holding a reference count on the same buffer. + + Buffer* bufferToSplit = pos.mBuffer; + NS_ASSERTION(bufferToSplit, "null pointer"); + + uint32_t splitOffset = pos.mPosition - bufferToSplit->DataStart(); + NS_ASSERTION(pos.mPosition >= bufferToSplit->DataStart() && + splitOffset <= bufferToSplit->DataLength(), + "split offset is outside buffer"); + + uint32_t len = bufferToSplit->DataLength() - splitOffset; + Buffer* new_buffer = AllocBuffer(len); + if (new_buffer) { + nsCharTraits::copy(new_buffer->DataStart(), + bufferToSplit->DataStart() + splitOffset, len); + InsertAfter(new_buffer, bufferToSplit); + bufferToSplit->SetDataLength(splitOffset); + } +} + +void nsScannerBufferList::DiscardUnreferencedPrefix(Buffer* aBuf) { + if (aBuf == Head()) { + while (!mBuffers.isEmpty() && !Head()->IsInUse()) { + Buffer* buffer = Head(); + buffer->remove(); + free(buffer); + } + } +} + +size_t nsScannerBufferList::Position::Distance(const Position& aStart, + const Position& aEnd) { + size_t result = 0; + if (aStart.mBuffer == aEnd.mBuffer) { + result = aEnd.mPosition - aStart.mPosition; + } else { + result = aStart.mBuffer->DataEnd() - aStart.mPosition; + for (Buffer* b = aStart.mBuffer->Next(); b != aEnd.mBuffer; b = b->Next()) + result += b->DataLength(); + result += aEnd.mPosition - aEnd.mBuffer->DataStart(); + } + return result; +} + +/** + * nsScannerSubstring + */ + +nsScannerSubstring::nsScannerSubstring() + : mStart(nullptr, nullptr), + mEnd(nullptr, nullptr), + mBufferList(nullptr), + mLength(0) {} + +nsScannerSubstring::nsScannerSubstring(const nsAString& s) + : mBufferList(nullptr) { + Rebind(s); +} + +nsScannerSubstring::~nsScannerSubstring() { + release_ownership_of_buffer_list(); +} + +void nsScannerSubstring::Rebind(const nsScannerSubstring& aString, + const nsScannerIterator& aStart, + const nsScannerIterator& aEnd) { + // allow for the case where &aString == this + + aString.acquire_ownership_of_buffer_list(); + release_ownership_of_buffer_list(); + + mStart = aStart; + mEnd = aEnd; + mBufferList = aString.mBufferList; + mLength = Distance(aStart, aEnd); +} + +void nsScannerSubstring::Rebind(const nsAString& aString) { + release_ownership_of_buffer_list(); + + mBufferList = new nsScannerBufferList(AllocBufferFromString(aString)); + + init_range_from_buffer_list(); + acquire_ownership_of_buffer_list(); +} + +nsScannerIterator& nsScannerSubstring::BeginReading( + nsScannerIterator& iter) const { + iter.mOwner = this; + + iter.mFragment.mBuffer = mStart.mBuffer; + iter.mFragment.mFragmentStart = mStart.mPosition; + if (mStart.mBuffer == mEnd.mBuffer) + iter.mFragment.mFragmentEnd = mEnd.mPosition; + else + iter.mFragment.mFragmentEnd = mStart.mBuffer->DataEnd(); + + iter.mPosition = mStart.mPosition; + iter.normalize_forward(); + return iter; +} + +nsScannerIterator& nsScannerSubstring::EndReading( + nsScannerIterator& iter) const { + iter.mOwner = this; + + iter.mFragment.mBuffer = mEnd.mBuffer; + iter.mFragment.mFragmentEnd = mEnd.mPosition; + if (mStart.mBuffer == mEnd.mBuffer) + iter.mFragment.mFragmentStart = mStart.mPosition; + else + iter.mFragment.mFragmentStart = mEnd.mBuffer->DataStart(); + + iter.mPosition = mEnd.mPosition; + // must not |normalize_backward| as that would likely invalidate tests like + // |while ( first != last )| + return iter; +} + +bool nsScannerSubstring::GetNextFragment(nsScannerFragment& frag) const { + // check to see if we are at the end of the buffer list + if (frag.mBuffer == mEnd.mBuffer) return false; + + frag.mBuffer = frag.mBuffer->getNext(); + + if (frag.mBuffer == mStart.mBuffer) + frag.mFragmentStart = mStart.mPosition; + else + frag.mFragmentStart = frag.mBuffer->DataStart(); + + if (frag.mBuffer == mEnd.mBuffer) + frag.mFragmentEnd = mEnd.mPosition; + else + frag.mFragmentEnd = frag.mBuffer->DataEnd(); + + return true; +} + +bool nsScannerSubstring::GetPrevFragment(nsScannerFragment& frag) const { + // check to see if we are at the beginning of the buffer list + if (frag.mBuffer == mStart.mBuffer) return false; + + frag.mBuffer = frag.mBuffer->getPrevious(); + + if (frag.mBuffer == mStart.mBuffer) + frag.mFragmentStart = mStart.mPosition; + else + frag.mFragmentStart = frag.mBuffer->DataStart(); + + if (frag.mBuffer == mEnd.mBuffer) + frag.mFragmentEnd = mEnd.mPosition; + else + frag.mFragmentEnd = frag.mBuffer->DataEnd(); + + return true; +} + +/** + * nsScannerString + */ + +nsScannerString::nsScannerString(Buffer* aBuf) { + mBufferList = new nsScannerBufferList(aBuf); + + init_range_from_buffer_list(); + acquire_ownership_of_buffer_list(); +} + +void nsScannerString::AppendBuffer(Buffer* aBuf) { + mBufferList->Append(aBuf); + mLength += aBuf->DataLength(); + + mEnd.mBuffer = aBuf; + mEnd.mPosition = aBuf->DataEnd(); +} + +void nsScannerString::DiscardPrefix(const nsScannerIterator& aIter) { + Position old_start(mStart); + mStart = aIter; + mLength -= Position::Distance(old_start, mStart); + + mStart.mBuffer->IncrementUsageCount(); + old_start.mBuffer->DecrementUsageCount(); + + mBufferList->DiscardUnreferencedPrefix(old_start.mBuffer); +} + +void nsScannerString::UngetReadable(const nsAString& aReadable, + const nsScannerIterator& aInsertPoint) +/* + * Warning: this routine manipulates the shared buffer list in an + * unexpected way. The original design did not really allow for + * insertions, but this call promises that if called for a point after the + * end of all extant token strings, that no token string or the work string + * will be invalidated. + * + * This routine is protected because it is the responsibility of the + * derived class to keep those promises. + */ +{ + Position insertPos(aInsertPoint); + + mBufferList->SplitBuffer(insertPos); + // splitting to the right keeps the work string and any extant token + // pointing to and holding a reference count on the same buffer + + Buffer* new_buffer = AllocBufferFromString(aReadable); + // make a new buffer with all the data to insert... + // ALERT: we may have empty space to re-use in the split buffer, + // measure the cost of this and decide if we should do the work to fill + // it + + Buffer* buffer_to_split = insertPos.mBuffer; + mBufferList->InsertAfter(new_buffer, buffer_to_split); + mLength += aReadable.Length(); + + mEnd.mBuffer = mBufferList->Tail(); + mEnd.mPosition = mEnd.mBuffer->DataEnd(); +} + +/** + * nsScannerSharedSubstring + */ + +void nsScannerSharedSubstring::Rebind(const nsScannerIterator& aStart, + const nsScannerIterator& aEnd) { + // If the start and end positions are inside the same buffer, we must + // acquire ownership of the buffer. If not, we can optimize by not holding + // onto it. + + Buffer* buffer = const_cast(aStart.buffer()); + bool sameBuffer = buffer == aEnd.buffer(); + + nsScannerBufferList* bufferList; + + if (sameBuffer) { + bufferList = aStart.mOwner->mBufferList; + bufferList->AddRef(); + buffer->IncrementUsageCount(); + } + + if (mBufferList) ReleaseBuffer(); + + if (sameBuffer) { + mBuffer = buffer; + mBufferList = bufferList; + mString.Rebind(aStart.mPosition, aEnd.mPosition); + } else { + mBuffer = nullptr; + mBufferList = nullptr; + CopyUnicodeTo(aStart, aEnd, mString); + } +} + +void nsScannerSharedSubstring::ReleaseBuffer() { + NS_ASSERTION(mBufferList, "Should only be called with non-null mBufferList"); + mBuffer->DecrementUsageCount(); + mBufferList->DiscardUnreferencedPrefix(mBuffer); + mBufferList->Release(); +} + +/** + * utils -- based on code from nsReadableUtils.cpp + */ + +// private helper function +static inline nsAString::iterator& copy_multifragment_string( + nsScannerIterator& first, const nsScannerIterator& last, + nsAString::iterator& result) { + typedef nsCharSourceTraits source_traits; + typedef nsCharSinkTraits sink_traits; + + while (first != last) { + uint32_t distance = source_traits::readable_distance(first, last); + sink_traits::write(result, source_traits::read(first), distance); + NS_ASSERTION(distance > 0, + "|copy_multifragment_string| will never terminate"); + source_traits::advance(first, distance); + } + + return result; +} + +bool CopyUnicodeTo(const nsScannerIterator& aSrcStart, + const nsScannerIterator& aSrcEnd, nsAString& aDest) { + mozilla::CheckedInt distance( + Distance(aSrcStart, aSrcEnd)); + if (!distance.isValid()) { + return false; // overflow detected + } + + if (!aDest.SetLength(distance.value(), mozilla::fallible)) { + aDest.Truncate(); + return false; // out of memory + } + auto writer = aDest.BeginWriting(); + nsScannerIterator fromBegin(aSrcStart); + + copy_multifragment_string(fromBegin, aSrcEnd, writer); + return true; +} + +bool AppendUnicodeTo(const nsScannerIterator& aSrcStart, + const nsScannerIterator& aSrcEnd, nsAString& aDest) { + const nsAString::size_type oldLength = aDest.Length(); + mozilla::CheckedInt newLen( + Distance(aSrcStart, aSrcEnd)); + newLen += oldLength; + if (!newLen.isValid()) { + return false; // overflow detected + } + + if (!aDest.SetLength(newLen.value(), mozilla::fallible)) + return false; // out of memory + auto writer = aDest.BeginWriting(); + std::advance(writer, oldLength); + nsScannerIterator fromBegin(aSrcStart); + + copy_multifragment_string(fromBegin, aSrcEnd, writer); + return true; +} diff --git a/parser/htmlparser/nsScannerString.h b/parser/htmlparser/nsScannerString.h new file mode 100644 index 0000000000..195e63e4bb --- /dev/null +++ b/parser/htmlparser/nsScannerString.h @@ -0,0 +1,459 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsScannerString_h___ +#define nsScannerString_h___ + +#include "nsString.h" +#include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator +#include "mozilla/LinkedList.h" +#include + +/** + * NOTE: nsScannerString (and the other classes defined in this file) are + * not related to nsAString or any of the other xpcom/string classes. + * + * nsScannerString is based on the nsSlidingString implementation that used + * to live in xpcom/string. Now that nsAString is limited to representing + * only single fragment strings, nsSlidingString can no longer be used. + * + * An advantage to this design is that it does not employ any virtual + * functions. + * + * This file uses SCC-style indenting in deference to the nsSlidingString + * code from which this code is derived ;-) + */ + +class nsScannerIterator; +class nsScannerSubstring; +class nsScannerString; + +/** + * nsScannerBufferList + * + * This class maintains a list of heap-allocated Buffer objects. The buffers + * are maintained in a circular linked list. Each buffer has a usage count + * that is decremented by the owning nsScannerSubstring. + * + * The buffer list itself is reference counted. This allows the buffer list + * to be shared by multiple nsScannerSubstring objects. The reference + * counting is not threadsafe, which is not at all a requirement. + * + * When a nsScannerSubstring releases its reference to a buffer list, it + * decrements the usage count of the first buffer in the buffer list that it + * was referencing. It informs the buffer list that it can discard buffers + * starting at that prefix. The buffer list will do so if the usage count of + * that buffer is 0 and if it is the first buffer in the list. It will + * continue to prune buffers starting from the front of the buffer list until + * it finds a buffer that has a usage count that is non-zero. + */ +class nsScannerBufferList { + public: + /** + * Buffer objects are directly followed by a data segment. The start + * of the data segment is determined by increment the |this| pointer + * by 1 unit. + */ + class Buffer : public mozilla::LinkedListElement { + public: + void IncrementUsageCount() { ++mUsageCount; } + void DecrementUsageCount() { --mUsageCount; } + + bool IsInUse() const { return mUsageCount != 0; } + + const char16_t* DataStart() const { return (const char16_t*)(this + 1); } + char16_t* DataStart() { return (char16_t*)(this + 1); } + + const char16_t* DataEnd() const { return mDataEnd; } + char16_t* DataEnd() { return mDataEnd; } + + const Buffer* Next() const { return getNext(); } + Buffer* Next() { return getNext(); } + + const Buffer* Prev() const { return getPrevious(); } + Buffer* Prev() { return getPrevious(); } + + uint32_t DataLength() const { return mDataEnd - DataStart(); } + void SetDataLength(uint32_t len) { mDataEnd = DataStart() + len; } + + private: + friend class nsScannerBufferList; + + int32_t mUsageCount; + char16_t* mDataEnd; + }; + + /** + * Position objects serve as lightweight pointers into a buffer list. + * The mPosition member must be contained with mBuffer->DataStart() + * and mBuffer->DataEnd(). + */ + class Position { + public: + Position() : mBuffer(nullptr), mPosition(nullptr) {} + + Position(Buffer* buffer, char16_t* position) + : mBuffer(buffer), mPosition(position) {} + + inline explicit Position(const nsScannerIterator& aIter); + + inline Position& operator=(const nsScannerIterator& aIter); + + static size_t Distance(const Position& p1, const Position& p2); + + Buffer* mBuffer; + char16_t* mPosition; + }; + + static Buffer* AllocBufferFromString(const nsAString&); + static Buffer* AllocBuffer(uint32_t capacity); // capacity = number of chars + + explicit nsScannerBufferList(Buffer* buf) : mRefCnt(0) { + mBuffers.insertBack(buf); + } + + void AddRef() { ++mRefCnt; } + void Release() { + if (--mRefCnt == 0) delete this; + } + + void Append(Buffer* buf) { mBuffers.insertBack(buf); } + void InsertAfter(Buffer* buf, Buffer* prev) { prev->setNext(buf); } + void SplitBuffer(const Position&); + void DiscardUnreferencedPrefix(Buffer*); + + Buffer* Head() { return mBuffers.getFirst(); } + const Buffer* Head() const { return mBuffers.getFirst(); } + + Buffer* Tail() { return mBuffers.getLast(); } + const Buffer* Tail() const { return mBuffers.getLast(); } + + private: + friend class nsScannerSubstring; + + ~nsScannerBufferList() { ReleaseAll(); } + void ReleaseAll(); + + int32_t mRefCnt; + mozilla::LinkedList mBuffers; +}; + +/** + * nsScannerFragment represents a "slice" of a Buffer object. + */ +struct nsScannerFragment { + typedef nsScannerBufferList::Buffer Buffer; + + const Buffer* mBuffer; + const char16_t* mFragmentStart; + const char16_t* mFragmentEnd; +}; + +/** + * nsScannerSubstring is the base class for nsScannerString. It provides + * access to iterators and methods to bind the substring to another + * substring or nsAString instance. + * + * This class owns the buffer list. + */ +class nsScannerSubstring { + public: + typedef nsScannerBufferList::Buffer Buffer; + typedef nsScannerBufferList::Position Position; + typedef uint32_t size_type; + + nsScannerSubstring(); + explicit nsScannerSubstring(const nsAString& s); + + ~nsScannerSubstring(); + + nsScannerIterator& BeginReading(nsScannerIterator& iter) const; + nsScannerIterator& EndReading(nsScannerIterator& iter) const; + + size_type Length() const { return mLength; } + + void Rebind(const nsScannerSubstring&, const nsScannerIterator&, + const nsScannerIterator&); + void Rebind(const nsAString&); + + bool GetNextFragment(nsScannerFragment&) const; + bool GetPrevFragment(nsScannerFragment&) const; + + static inline Buffer* AllocBufferFromString(const nsAString& aStr) { + return nsScannerBufferList::AllocBufferFromString(aStr); + } + static inline Buffer* AllocBuffer(size_type aCapacity) { + return nsScannerBufferList::AllocBuffer(aCapacity); + } + + protected: + void acquire_ownership_of_buffer_list() const { + mBufferList->AddRef(); + mStart.mBuffer->IncrementUsageCount(); + } + + void release_ownership_of_buffer_list() { + if (mBufferList) { + mStart.mBuffer->DecrementUsageCount(); + mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer); + mBufferList->Release(); + } + } + + void init_range_from_buffer_list() { + mStart.mBuffer = mBufferList->Head(); + mStart.mPosition = mStart.mBuffer->DataStart(); + + mEnd.mBuffer = mBufferList->Tail(); + mEnd.mPosition = mEnd.mBuffer->DataEnd(); + + mLength = Position::Distance(mStart, mEnd); + } + + Position mStart; + Position mEnd; + nsScannerBufferList* mBufferList; + size_type mLength; + + friend class nsScannerSharedSubstring; +}; + +/** + * nsScannerString provides methods to grow and modify a buffer list. + */ +class nsScannerString : public nsScannerSubstring { + public: + explicit nsScannerString(Buffer*); + + // you are giving ownership to the string, it takes and keeps your + // buffer, deleting it when done. + // Use AllocBuffer or AllocBufferFromString to create a Buffer object + // for use with this function. + void AppendBuffer(Buffer*); + + void DiscardPrefix(const nsScannerIterator&); + // any other way you want to do this? + + void UngetReadable(const nsAString& aReadable, + const nsScannerIterator& aCurrentPosition); +}; + +/** + * nsScannerSharedSubstring implements copy-on-write semantics for + * nsScannerSubstring. This class also manages releasing + * the reference to the scanner buffer when it is no longer needed. + */ + +class nsScannerSharedSubstring { + public: + nsScannerSharedSubstring() : mBuffer(nullptr), mBufferList(nullptr) {} + + ~nsScannerSharedSubstring() { + if (mBufferList) ReleaseBuffer(); + } + + // Acquire a copy-on-write reference to the given substring. + void Rebind(const nsScannerIterator& aStart, const nsScannerIterator& aEnd); + + // Get a const reference to this string + const nsAString& str() const { return mString; } + + private: + typedef nsScannerBufferList::Buffer Buffer; + + void ReleaseBuffer(); + + nsDependentSubstring mString; + Buffer* mBuffer; + nsScannerBufferList* mBufferList; +}; + +/** + * nsScannerIterator works just like nsReadingIterator except that + * it knows how to iterate over a list of scanner buffers. + */ +class nsScannerIterator { + public: + typedef nsScannerIterator self_type; + typedef ptrdiff_t difference_type; + typedef char16_t value_type; + typedef const char16_t* pointer; + typedef const char16_t& reference; + typedef nsScannerSubstring::Buffer Buffer; + + protected: + nsScannerFragment mFragment; + const char16_t* mPosition; + const nsScannerSubstring* mOwner; + + friend class nsScannerSubstring; + friend class nsScannerSharedSubstring; + + public: + // nsScannerIterator(); // auto-generate + // default constructor is OK nsScannerIterator( const nsScannerIterator& ); // + // auto-generated copy-constructor OK nsScannerIterator& operator=( const + // nsScannerIterator& ); // auto-generated copy-assignment operator OK + + inline void normalize_forward(); + inline void normalize_backward(); + + pointer get() const { return mPosition; } + + char16_t operator*() const { return *get(); } + + const nsScannerFragment& fragment() const { return mFragment; } + + const Buffer* buffer() const { return mFragment.mBuffer; } + + self_type& operator++() { + ++mPosition; + normalize_forward(); + return *this; + } + + self_type operator++(int) { + self_type result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + self_type& operator--() { + normalize_backward(); + --mPosition; + return *this; + } + + self_type operator--(int) { + self_type result(*this); + normalize_backward(); + --mPosition; + return result; + } + + difference_type size_forward() const { + return mFragment.mFragmentEnd - mPosition; + } + + difference_type size_backward() const { + return mPosition - mFragment.mFragmentStart; + } + + self_type& advance(difference_type n) { + while (n > 0) { + difference_type one_hop = std::min(n, size_forward()); + + NS_ASSERTION(one_hop > 0, + "Infinite loop: can't advance a reading iterator beyond the " + "end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while (n < 0) { + normalize_backward(); + difference_type one_hop = std::max(n, -size_backward()); + + NS_ASSERTION(one_hop < 0, + "Infinite loop: can't advance (backward) a reading iterator " + "beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } +}; + +inline bool SameFragment(const nsScannerIterator& a, + const nsScannerIterator& b) { + return a.fragment().mFragmentStart == b.fragment().mFragmentStart; +} + +/** + * this class is needed in order to make use of the methods in nsAlgorithm.h + */ +template <> +struct nsCharSourceTraits { + typedef nsScannerIterator::difference_type difference_type; + + static uint32_t readable_distance(const nsScannerIterator& first, + const nsScannerIterator& last) { + return uint32_t(SameFragment(first, last) ? last.get() - first.get() + : first.size_forward()); + } + + static const nsScannerIterator::value_type* read( + const nsScannerIterator& iter) { + return iter.get(); + } + + static void advance(nsScannerIterator& s, difference_type n) { s.advance(n); } +}; + +/** + * inline methods follow + */ + +inline void nsScannerIterator::normalize_forward() { + while (mPosition == mFragment.mFragmentEnd && + mOwner->GetNextFragment(mFragment)) + mPosition = mFragment.mFragmentStart; +} + +inline void nsScannerIterator::normalize_backward() { + while (mPosition == mFragment.mFragmentStart && + mOwner->GetPrevFragment(mFragment)) + mPosition = mFragment.mFragmentEnd; +} + +inline bool operator==(const nsScannerIterator& lhs, + const nsScannerIterator& rhs) { + return lhs.get() == rhs.get(); +} + +inline bool operator!=(const nsScannerIterator& lhs, + const nsScannerIterator& rhs) { + return lhs.get() != rhs.get(); +} + +inline nsScannerBufferList::Position::Position(const nsScannerIterator& aIter) + : mBuffer(const_cast(aIter.buffer())), + mPosition(const_cast(aIter.get())) {} + +inline nsScannerBufferList::Position& nsScannerBufferList::Position::operator=( + const nsScannerIterator& aIter) { + mBuffer = const_cast(aIter.buffer()); + mPosition = const_cast(aIter.get()); + return *this; +} + +/** + * scanner string utils + * + * These methods mimic the API provided by nsReadableUtils in xpcom/string. + * Here we provide only the methods that the htmlparser module needs. + */ + +inline size_t Distance(const nsScannerIterator& aStart, + const nsScannerIterator& aEnd) { + typedef nsScannerBufferList::Position Position; + return Position::Distance(Position(aStart), Position(aEnd)); +} + +bool CopyUnicodeTo(const nsScannerIterator& aSrcStart, + const nsScannerIterator& aSrcEnd, nsAString& aDest); + +bool AppendUnicodeTo(const nsScannerIterator& aSrcStart, + const nsScannerIterator& aSrcEnd, nsAString& aDest); + +#endif // !defined(nsScannerString_h___) diff --git a/parser/htmlparser/tests/crashtests/121591-1.html b/parser/htmlparser/tests/crashtests/121591-1.html new file mode 100644 index 0000000000..b411a18518 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/121591-1.html @@ -0,0 +1,22 @@ + + + + + + +
+ + + +
+
+ +
+
+
+
+ + + + + diff --git a/parser/htmlparser/tests/crashtests/1373045-1.html b/parser/htmlparser/tests/crashtests/1373045-1.html new file mode 100644 index 0000000000..d0bea2fa44 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1373045-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/147179-1.html b/parser/htmlparser/tests/crashtests/147179-1.html new file mode 100644 index 0000000000..2aaac19844 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/147179-1.html @@ -0,0 +1,7 @@ +Testcase for bug 141561 + + + + + + diff --git a/parser/htmlparser/tests/crashtests/151956-1.html b/parser/htmlparser/tests/crashtests/151956-1.html new file mode 100644 index 0000000000..0ae77f6a6c --- /dev/null +++ b/parser/htmlparser/tests/crashtests/151956-1.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + +
X
+ + + diff --git a/parser/htmlparser/tests/crashtests/152444-1.html b/parser/htmlparser/tests/crashtests/152444-1.html new file mode 100644 index 0000000000..6576444544 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/152444-1.html @@ -0,0 +1,15 @@ + + +Untitled + + + + + + + + + +
+ + diff --git a/parser/htmlparser/tests/crashtests/1534346-1.html b/parser/htmlparser/tests/crashtests/1534346-1.html new file mode 100644 index 0000000000..34ab7930db --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1534346-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/1547895-1.html b/parser/htmlparser/tests/crashtests/1547895-1.html new file mode 100644 index 0000000000..72d19c6caa --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1547895-1.html @@ -0,0 +1,10 @@ + diff --git a/parser/htmlparser/tests/crashtests/1604307-1.html b/parser/htmlparser/tests/crashtests/1604307-1.html new file mode 100644 index 0000000000..28a2e7caf0 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1604307-1.html @@ -0,0 +1,10 @@ + + + + diff --git a/parser/htmlparser/tests/crashtests/1606499-1.html b/parser/htmlparser/tests/crashtests/1606499-1.html new file mode 100644 index 0000000000..5771d73d8d --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1606499-1.html @@ -0,0 +1,15 @@ + + diff --git a/parser/htmlparser/tests/crashtests/1747514.html b/parser/htmlparser/tests/crashtests/1747514.html new file mode 100644 index 0000000000..9411f22a52 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1747514.html @@ -0,0 +1,13 @@ + + + + + diff --git a/parser/htmlparser/tests/crashtests/1810896-1.html b/parser/htmlparser/tests/crashtests/1810896-1.html new file mode 100644 index 0000000000..2c16456302 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1810896-1.html @@ -0,0 +1,1081 @@ + + +$B$"(B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + あ + + diff --git a/parser/htmlparser/tests/crashtests/185073-1.html b/parser/htmlparser/tests/crashtests/185073-1.html new file mode 100644 index 0000000000..39504ede22 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/185073-1.html @@ -0,0 +1,15 @@ + + + bug 185073 + + + +
+ +
+
+ + diff --git a/parser/htmlparser/tests/crashtests/1854907-1.html b/parser/htmlparser/tests/crashtests/1854907-1.html new file mode 100644 index 0000000000..f26f06e75f --- /dev/null +++ b/parser/htmlparser/tests/crashtests/1854907-1.html @@ -0,0 +1,225 @@ + + + + +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a diff --git a/parser/htmlparser/tests/crashtests/188474-1.html b/parser/htmlparser/tests/crashtests/188474-1.html new file mode 100644 index 0000000000..2e8b03d197 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/188474-1.html @@ -0,0 +1,13 @@ + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/194329-1.html b/parser/htmlparser/tests/crashtests/194329-1.html new file mode 100644 index 0000000000..c7ab69007e --- /dev/null +++ b/parser/htmlparser/tests/crashtests/194329-1.html @@ -0,0 +1,15 @@ + + + bug 188474 + + + +
+ +
+ + + diff --git a/parser/htmlparser/tests/crashtests/197052-1.html b/parser/htmlparser/tests/crashtests/197052-1.html new file mode 100644 index 0000000000..d0b30c761b --- /dev/null +++ b/parser/htmlparser/tests/crashtests/197052-1.html @@ -0,0 +1 @@ + testcase - crasher
\ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/220542-1.html b/parser/htmlparser/tests/crashtests/220542-1.html new file mode 100644 index 0000000000..f664734664 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/220542-1.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/crashtests/253979-1.html b/parser/htmlparser/tests/crashtests/253979-1.html new file mode 100644 index 0000000000..5e47ee84c9 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/253979-1.html @@ -0,0 +1,4 @@ + +

+ + diff --git a/parser/htmlparser/tests/crashtests/269095-1.html b/parser/htmlparser/tests/crashtests/269095-1.html new file mode 100644 index 0000000000..83cc52828e --- /dev/null +++ b/parser/htmlparser/tests/crashtests/269095-1.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/286733-1.html b/parser/htmlparser/tests/crashtests/286733-1.html new file mode 100644 index 0000000000..04be4f11d3 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/286733-1.html @@ -0,0 +1,4 @@ +
+ +
+

+#errors +(1,7): expected-doctype-but-got-start-tag +(1,20): unexpected-end-tag-implies-table-voodoo +(1,20): unexpected-end-tag +(1,24): unexpected-end-tag-implies-table-voodoo +(1,24): unexpected-end-tag +(1,29): unexpected-end-tag-implies-table-voodoo +(1,29): unexpected-end-tag +(1,33): unexpected-end-tag-implies-table-voodoo +(1,33): unexpected-end-tag +(1,37): unexpected-end-tag-implies-table-voodoo +(1,37): unexpected-end-tag +(1,46): unexpected-end-tag-implies-table-voodoo +(1,46): unexpected-end-tag +(1,50): unexpected-end-tag-implies-table-voodoo +(1,50): unexpected-end-tag +(1,58): unexpected-end-tag-implies-table-voodoo +(1,58): unexpected-end-tag +(1,63): unexpected-end-tag-implies-table-voodoo +(1,63): unexpected-end-tag +(1,69): unexpected-end-tag-implies-table-voodoo +(1,69): end-tag-too-early +(1,75): unexpected-end-tag-implies-table-voodoo +(1,75): unexpected-end-tag +(1,83): unexpected-end-tag-implies-table-voodoo +(1,83): unexpected-end-tag +(1,90): unexpected-end-tag-implies-table-voodoo +(1,90): unexpected-end-tag +(1,99): unexpected-end-tag-implies-table-voodoo +(1,99): unexpected-end-tag +(1,104): unexpected-end-tag-implies-table-voodoo +(1,104): end-tag-too-early +(1,109): unexpected-end-tag-implies-table-voodoo +(1,109): end-tag-too-early +(1,114): unexpected-end-tag-implies-table-voodoo +(1,114): end-tag-too-early +(1,119): unexpected-end-tag-implies-table-voodoo +(1,119): end-tag-too-early +(1,124): unexpected-end-tag-implies-table-voodoo +(1,124): end-tag-too-early +(1,129): unexpected-end-tag-implies-table-voodoo +(1,129): end-tag-too-early +(1,136): unexpected-end-tag-in-table-row +(1,141): unexpected-end-tag-implies-table-voodoo +(1,141): unexpected-end-tag-treated-as +(1,145): unexpected-end-tag-implies-table-voodoo +(1,145): unexpected-end-tag +(1,151): unexpected-end-tag-implies-table-voodoo +(1,151): unexpected-end-tag +(1,159): unexpected-end-tag-implies-table-voodoo +(1,159): unexpected-end-tag +(1,166): unexpected-end-tag-implies-table-voodoo +(1,166): unexpected-end-tag +(1,174): unexpected-end-tag-implies-table-voodoo +(1,174): unexpected-end-tag +(1,183): unexpected-end-tag-implies-table-voodoo +(1,183): unexpected-end-tag +(1,196): unexpected-end-tag +(1,201): unexpected-end-tag +(1,206): unexpected-end-tag +(1,214): unexpected-end-tag +(1,221): unexpected-end-tag +(1,228): unexpected-end-tag +(1,236): unexpected-end-tag +(1,241): unexpected-end-tag +(1,249): unexpected-end-tag +(1,255): unexpected-end-tag +(1,262): unexpected-end-tag +(1,269): unexpected-end-tag +(1,280): unexpected-end-tag +(1,290): unexpected-end-tag +(1,298): unexpected-end-tag +(1,307): unexpected-end-tag +(1,311): unexpected-end-tag +(1,316): unexpected-end-tag +(1,321): unexpected-end-tag +(1,331): unexpected-end-tag +(1,342): unexpected-end-tag +(1,350): unexpected-end-tag +(1,358): unexpected-end-tag +(1,366): unexpected-end-tag +(1,376): end-tag-too-early +(1,389): end-tag-too-early +(1,398): end-tag-too-early +(1,404): end-tag-too-early +(1,410): end-tag-too-early +(1,415): end-tag-too-early +(1,426): end-tag-too-early +(1,436): end-tag-too-early +(1,443): end-tag-too-early +(1,448): end-tag-too-early +(1,453): end-tag-too-early +(1,458): unexpected-end-tag +(1,465): unexpected-end-tag +(1,471): unexpected-end-tag +(1,478): unexpected-end-tag +(1,487): end-tag-too-early +(1,497): end-tag-too-early +(1,506): end-tag-too-early +(1,524): expected-eof-but-got-end-tag +(1,524): unexpected-end-tag +(1,531): unexpected-end-tag +(1,540): unexpected-end-tag +(1,548): unexpected-end-tag +(1,558): unexpected-end-tag +(1,568): unexpected-end-tag +(1,579): unexpected-end-tag +(1,590): unexpected-end-tag +(1,601): unexpected-end-tag +(1,610): unexpected-end-tag +(1,622): unexpected-end-tag +(1,633): unexpected-end-tag +#document +| +| +| +|
+|

diff --git a/parser/htmlparser/tests/crashtests/286733-2.html b/parser/htmlparser/tests/crashtests/286733-2.html new file mode 100644 index 0000000000..5fcf7a7ff9 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/286733-2.html @@ -0,0 +1,4 @@ +
+ +

+#errors +(1,9): expected-doctype-but-got-end-tag +(1,9): unexpected-end-tag-before-html +(1,13): unexpected-end-tag-before-html +(1,18): unexpected-end-tag-before-html +(1,22): unexpected-end-tag-before-html +(1,26): unexpected-end-tag-before-html +(1,35): unexpected-end-tag-before-html +(1,39): unexpected-end-tag-before-html +(1,47): unexpected-end-tag-before-html +(1,52): unexpected-end-tag-before-html +(1,58): unexpected-end-tag-before-html +(1,64): unexpected-end-tag-before-html +(1,72): unexpected-end-tag-before-html +(1,79): unexpected-end-tag-before-html +(1,88): unexpected-end-tag-before-html +(1,93): unexpected-end-tag-before-html +(1,98): unexpected-end-tag-before-html +(1,103): unexpected-end-tag-before-html +(1,108): unexpected-end-tag-before-html +(1,113): unexpected-end-tag-before-html +(1,118): unexpected-end-tag-before-html +(1,130): unexpected-end-tag-after-body +(1,130): unexpected-end-tag-treated-as +(1,134): unexpected-end-tag +(1,140): unexpected-end-tag +(1,148): unexpected-end-tag +(1,155): unexpected-end-tag +(1,163): unexpected-end-tag +(1,172): unexpected-end-tag +(1,180): unexpected-end-tag +(1,185): unexpected-end-tag +(1,190): unexpected-end-tag +(1,195): unexpected-end-tag +(1,203): unexpected-end-tag +(1,210): unexpected-end-tag +(1,217): unexpected-end-tag +(1,225): unexpected-end-tag +(1,230): unexpected-end-tag +(1,238): unexpected-end-tag +(1,244): unexpected-end-tag +(1,251): unexpected-end-tag +(1,258): unexpected-end-tag +(1,269): unexpected-end-tag +(1,279): unexpected-end-tag +(1,287): unexpected-end-tag +(1,296): unexpected-end-tag +(1,300): unexpected-end-tag +(1,305): unexpected-end-tag +(1,310): unexpected-end-tag +(1,320): unexpected-end-tag +(1,331): unexpected-end-tag +(1,339): unexpected-end-tag +(1,347): unexpected-end-tag +(1,355): unexpected-end-tag +(1,365): end-tag-too-early +(1,378): end-tag-too-early +(1,387): end-tag-too-early +(1,393): end-tag-too-early +(1,399): end-tag-too-early +(1,404): end-tag-too-early +(1,415): end-tag-too-early +(1,425): end-tag-too-early +(1,432): end-tag-too-early +(1,437): end-tag-too-early +(1,442): end-tag-too-early +(1,447): unexpected-end-tag +(1,454): unexpected-end-tag +(1,460): unexpected-end-tag +(1,467): unexpected-end-tag +(1,476): end-tag-too-early +(1,486): end-tag-too-early +(1,495): end-tag-too-early +(1,513): expected-eof-but-got-end-tag +(1,513): unexpected-end-tag +(1,520): unexpected-end-tag +(1,529): unexpected-end-tag +(1,537): unexpected-end-tag +(1,547): unexpected-end-tag +(1,557): unexpected-end-tag +(1,568): unexpected-end-tag +(1,579): unexpected-end-tag +(1,590): unexpected-end-tag +(1,599): unexpected-end-tag +(1,611): unexpected-end-tag +(1,622): unexpected-end-tag +#document +| +| +| +|
+|

+ +#data +

+

diff --git a/parser/htmlparser/tests/crashtests/299036-1.html b/parser/htmlparser/tests/crashtests/299036-1.html new file mode 100644 index 0000000000..e21ce2b9b7 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/299036-1.html @@ -0,0 +1,2 @@ +
+ diff --git a/parser/htmlparser/tests/crashtests/30885-1.html b/parser/htmlparser/tests/crashtests/30885-1.html new file mode 100644 index 0000000000..2dc0fe035d --- /dev/null +++ b/parser/htmlparser/tests/crashtests/30885-1.html @@ -0,0 +1,17 @@ + + + + + + + +
+ + + + + MacDesktops + +
+ + diff --git a/parser/htmlparser/tests/crashtests/30956-1.html b/parser/htmlparser/tests/crashtests/30956-1.html new file mode 100644 index 0000000000..508149a97d --- /dev/null +++ b/parser/htmlparser/tests/crashtests/30956-1.html @@ -0,0 +1,10 @@ + + + + +
+
  • +
  • +
  • + + \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/31392-1.html b/parser/htmlparser/tests/crashtests/31392-1.html new file mode 100644 index 0000000000..0a4a138b34 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/31392-1.html @@ -0,0 +1,15 @@ + + +Crash Test page + + + + + + + +
    + +
    + + \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/31694-1.html b/parser/htmlparser/tests/crashtests/31694-1.html new file mode 100644 index 0000000000..8be2d47f02 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/31694-1.html @@ -0,0 +1,8 @@ + + + + + + + +
    diff --git a/parser/htmlparser/tests/crashtests/31940-1.html b/parser/htmlparser/tests/crashtests/31940-1.html new file mode 100644 index 0000000000..ec2f370e83 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/31940-1.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/32613-1.html b/parser/htmlparser/tests/crashtests/32613-1.html new file mode 100644 index 0000000000..f50c342e9f --- /dev/null +++ b/parser/htmlparser/tests/crashtests/32613-1.html @@ -0,0 +1,18 @@ +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +
    diff --git a/parser/htmlparser/tests/crashtests/328751-1.html b/parser/htmlparser/tests/crashtests/328751-1.html new file mode 100644 index 0000000000..37b46af345 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/328751-1.html @@ -0,0 +1,9 @@ + + + + + +<TBODY > +</HEAD > \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/34168-1.html b/parser/htmlparser/tests/crashtests/34168-1.html new file mode 100644 index 0000000000..a191a03681 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/34168-1.html @@ -0,0 +1 @@ +<!ENTITY editAwayMessageSpecial3.label " %d = Current date"> \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/34168-1.xml b/parser/htmlparser/tests/crashtests/34168-1.xml new file mode 100644 index 0000000000..71a058c316 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/34168-1.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<!DOCTYPE foo [ +<!ENTITY editAwayMessageSpecial3.label " %%d = Current date"> +<!ELEMENT foo EMPTY> +]> +<foo/> diff --git a/parser/htmlparser/tests/crashtests/408939-1.html b/parser/htmlparser/tests/crashtests/408939-1.html new file mode 100644 index 0000000000..844c70e72e --- /dev/null +++ b/parser/htmlparser/tests/crashtests/408939-1.html @@ -0,0 +1,139 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> + +<div> +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +</div> + +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> + +</body> +</html> diff --git a/parser/htmlparser/tests/crashtests/41427-1.html b/parser/htmlparser/tests/crashtests/41427-1.html new file mode 100644 index 0000000000..5612153da5 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/41427-1.html @@ -0,0 +1 @@ +<A HREF=""><font><B>t</A><head><script> diff --git a/parser/htmlparser/tests/crashtests/423373-1.html b/parser/htmlparser/tests/crashtests/423373-1.html new file mode 100644 index 0000000000..4876095480 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/423373-1.html @@ -0,0 +1 @@ +<body><asdf><legend> diff --git a/parser/htmlparser/tests/crashtests/44178-1.html b/parser/htmlparser/tests/crashtests/44178-1.html new file mode 100644 index 0000000000..0ecb40ef77 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/44178-1.html @@ -0,0 +1,8 @@ +<html> +<body> +<div> +<server> +</server> +</div> +</body> +</html> diff --git a/parser/htmlparser/tests/crashtests/445171-1-inner.svg b/parser/htmlparser/tests/crashtests/445171-1-inner.svg new file mode 100644 index 0000000000..24ed6f8a70 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/445171-1-inner.svg @@ -0,0 +1,5 @@ +<svg xmlns="http://www.w3.org/2000/svg" onload="location = 'file_445171-1.html'"> + +<rect x="5" y="5" width="50" height="50" /> + +</svg> diff --git a/parser/htmlparser/tests/crashtests/445171-1.html b/parser/htmlparser/tests/crashtests/445171-1.html new file mode 100644 index 0000000000..0abaacdfba --- /dev/null +++ b/parser/htmlparser/tests/crashtests/445171-1.html @@ -0,0 +1,9 @@ +<html class="reftest-wait"> +<head> +<script> +function done() { document.documentElement.removeAttribute("class"); } +</script> +<body> +<iframe src="445171-1-inner.svg"></iframe> +</body> +</html> diff --git a/parser/htmlparser/tests/crashtests/46495-1.html b/parser/htmlparser/tests/crashtests/46495-1.html new file mode 100644 index 0000000000..a0947ff2ca --- /dev/null +++ b/parser/htmlparser/tests/crashtests/46495-1.html @@ -0,0 +1,5 @@ +<html> + <body> + <p "> + </body> +</html> diff --git a/parser/htmlparser/tests/crashtests/468538-1.xhtml b/parser/htmlparser/tests/crashtests/468538-1.xhtml new file mode 100644 index 0000000000..576b333c19 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/468538-1.xhtml @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<head> +<script type="text/javascript"> + +function boom() +{ + var v = document.getElementById("v"); + document.body.removeChild(document.body.firstChild); + v.innerHTML = "f"; +} + +</script> +</head> +<body onload="boom();"><xul:box><div id="v"/></xul:box></body> +</html> diff --git a/parser/htmlparser/tests/crashtests/50134-1.html b/parser/htmlparser/tests/crashtests/50134-1.html new file mode 100644 index 0000000000..efe680a1f4 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/50134-1.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>Mozilla Bug 50134 + + + + + diff --git a/parser/htmlparser/tests/crashtests/502103.html b/parser/htmlparser/tests/crashtests/502103.html new file mode 100644 index 0000000000..171a2890e5 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/502103.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/502869-iframe.html b/parser/htmlparser/tests/crashtests/502869-iframe.html new file mode 100644 index 0000000000..ff76e020bf --- /dev/null +++ b/parser/htmlparser/tests/crashtests/502869-iframe.html @@ -0,0 +1,9 @@ +[HTML5] Crash [@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster] with document.write and removing stuff + +
    + + diff --git a/parser/htmlparser/tests/crashtests/502869.html b/parser/htmlparser/tests/crashtests/502869.html new file mode 100644 index 0000000000..5da23b5076 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/502869.html @@ -0,0 +1,18 @@ + + + + Testcase for bug 502869 + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/50994-1.html b/parser/htmlparser/tests/crashtests/50994-1.html new file mode 100644 index 0000000000..11bd9aaf07 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/50994-1.html @@ -0,0 +1,12 @@ + + + + Mozilla Bug 50994 + + +

    + +

    + + + diff --git a/parser/htmlparser/tests/crashtests/515278-1.html b/parser/htmlparser/tests/crashtests/515278-1.html new file mode 100644 index 0000000000..33e01f2224 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515278-1.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/crashtests/515533-1-inner.html b/parser/htmlparser/tests/crashtests/515533-1-inner.html new file mode 100644 index 0000000000..6bd0684e21 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515533-1-inner.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/515533-1.html b/parser/htmlparser/tests/crashtests/515533-1.html new file mode 100644 index 0000000000..b0d5b570b8 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515533-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/515816-1.html b/parser/htmlparser/tests/crashtests/515816-1.html new file mode 100644 index 0000000000..c518d2a3cf --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515816-1.html @@ -0,0 +1,11 @@ + + + + + + + + +

    + + diff --git a/parser/htmlparser/tests/crashtests/522326-1.html b/parser/htmlparser/tests/crashtests/522326-1.html new file mode 100644 index 0000000000..d06ab6cf7d --- /dev/null +++ b/parser/htmlparser/tests/crashtests/522326-1.html @@ -0,0 +1 @@ +abcd diff --git a/parser/htmlparser/tests/crashtests/525229-1.html b/parser/htmlparser/tests/crashtests/525229-1.html new file mode 100644 index 0000000000..8bffa7d601 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/525229-1.html @@ -0,0 +1,7 @@ + +Test for bug 525229 + + +text diff --git a/parser/htmlparser/tests/crashtests/536097-1.html b/parser/htmlparser/tests/crashtests/536097-1.html new file mode 100644 index 0000000000..76befb3cc8 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/536097-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/555462-iframe.html b/parser/htmlparser/tests/crashtests/555462-iframe.html new file mode 100644 index 0000000000..3ddd6282db --- /dev/null +++ b/parser/htmlparser/tests/crashtests/555462-iframe.html @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/555462.html b/parser/htmlparser/tests/crashtests/555462.html new file mode 100644 index 0000000000..f8d4afad71 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/555462.html @@ -0,0 +1,21 @@ + + + + Testcase for bug 555462 + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/563514-1.html b/parser/htmlparser/tests/crashtests/563514-1.html new file mode 100644 index 0000000000..b96ce14661 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/563514-1.html @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/574884-1.html b/parser/htmlparser/tests/crashtests/574884-1.html new file mode 100644 index 0000000000..19de3c74a4 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/574884-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/574884-2.html b/parser/htmlparser/tests/crashtests/574884-2.html new file mode 100644 index 0000000000..09bec52e6d --- /dev/null +++ b/parser/htmlparser/tests/crashtests/574884-2.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/58455-1.html b/parser/htmlparser/tests/crashtests/58455-1.html new file mode 100644 index 0000000000..7c235f9806 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/58455-1.html @@ -0,0 +1,15 @@ + + + Computer Market Online + + + + + + + + +
    This shows
    This does not show
    + + + diff --git a/parser/htmlparser/tests/crashtests/591330-1.html b/parser/htmlparser/tests/crashtests/591330-1.html new file mode 100644 index 0000000000..31719fac6a --- /dev/null +++ b/parser/htmlparser/tests/crashtests/591330-1.html @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/60110-1.html b/parser/htmlparser/tests/crashtests/60110-1.html new file mode 100644 index 0000000000..34f8c406b8 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/60110-1.html @@ -0,0 +1,22 @@ + +Edit parameters + + + + + +

    +Any item you check Reset on will get reset to its default value. + + + + +
    Reset + +
    Reset + +
    2.11
    +
    + +

    \ No newline at end of file diff --git a/parser/htmlparser/tests/crashtests/616027-1.html b/parser/htmlparser/tests/crashtests/616027-1.html new file mode 100644 index 0000000000..d4707c9359 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/616027-1.html @@ -0,0 +1,15 @@ + + + + + + diff --git a/parser/htmlparser/tests/crashtests/650501-1.xhtml b/parser/htmlparser/tests/crashtests/650501-1.xhtml new file mode 100644 index 0000000000..c701a0c76c --- /dev/null +++ b/parser/htmlparser/tests/crashtests/650501-1.xhtml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/662185-1.html b/parser/htmlparser/tests/crashtests/662185-1.html new file mode 100644 index 0000000000..41d67e5355 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/662185-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/696651-1.html b/parser/htmlparser/tests/crashtests/696651-1.html new file mode 100644 index 0000000000..8c5ee9ed3a --- /dev/null +++ b/parser/htmlparser/tests/crashtests/696651-1.html @@ -0,0 +1,11 @@ + + + + + diff --git a/parser/htmlparser/tests/crashtests/699347-1.xml b/parser/htmlparser/tests/crashtests/699347-1.xml new file mode 100644 index 0000000000..c6dd4bfa1b --- /dev/null +++ b/parser/htmlparser/tests/crashtests/699347-1.xml @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/721313-1.html b/parser/htmlparser/tests/crashtests/721313-1.html new file mode 100644 index 0000000000..06497cd65b --- /dev/null +++ b/parser/htmlparser/tests/crashtests/721313-1.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/crashtests/73331-1.html b/parser/htmlparser/tests/crashtests/73331-1.html new file mode 100644 index 0000000000..6761a6686a --- /dev/null +++ b/parser/htmlparser/tests/crashtests/73331-1.html @@ -0,0 +1,27 @@ + + + + + +http://www.mozilla.org/ + +
    + + + +
    + + + diff --git a/parser/htmlparser/tests/crashtests/742414-1.html b/parser/htmlparser/tests/crashtests/742414-1.html new file mode 100644 index 0000000000..e35b125603 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/742414-1.html @@ -0,0 +1,4 @@ + diff --git a/parser/htmlparser/tests/crashtests/762726-1.html b/parser/htmlparser/tests/crashtests/762726-1.html new file mode 100644 index 0000000000..4692b73e1e --- /dev/null +++ b/parser/htmlparser/tests/crashtests/762726-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/92647-1.html b/parser/htmlparser/tests/crashtests/92647-1.html new file mode 100644 index 0000000000..16be8d98e1 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/92647-1.html @@ -0,0 +1,33 @@ + + +
    + + + + +
    + + + + + + + + + + +
    + Member Number: + + +
    + PIN: + + + +
    +
    +
    + + + diff --git a/parser/htmlparser/tests/crashtests/92788-1.html b/parser/htmlparser/tests/crashtests/92788-1.html new file mode 100644 index 0000000000..955301e3f2 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/92788-1.html @@ -0,0 +1,20 @@ +Bug #92788 + + + + + +
    +
    + diff --git a/parser/htmlparser/tests/crashtests/981279-1.html b/parser/htmlparser/tests/crashtests/981279-1.html new file mode 100644 index 0000000000..5f14c8af37 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/981279-1.html @@ -0,0 +1,15 @@ + + + + + + +
    + + + + diff --git a/parser/htmlparser/tests/crashtests/982285-1.html b/parser/htmlparser/tests/crashtests/982285-1.html new file mode 100644 index 0000000000..d3e124d957 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/982285-1.html @@ -0,0 +1,19 @@ + + +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + +
    +
    diff --git a/parser/htmlparser/tests/crashtests/crashtests.list b/parser/htmlparser/tests/crashtests/crashtests.list
    new file mode 100644
    index 0000000000..1c786b7acc
    --- /dev/null
    +++ b/parser/htmlparser/tests/crashtests/crashtests.list
    @@ -0,0 +1,68 @@
    +load 30885-1.html
    +load 30956-1.html
    +load 31392-1.html
    +load 31694-1.html
    +load 31940-1.html
    +load 32613-1.html
    +load 34168-1.html
    +load 34168-1.xml
    +load 41427-1.html
    +load 44178-1.html
    +load 46495-1.html
    +load 50134-1.html
    +load 50994-1.html
    +load 58455-1.html
    +load 60110-1.html
    +load 73331-1.html
    +load 92647-1.html
    +load 92788-1.html
    +load 121591-1.html
    +load 147179-1.html
    +load 151956-1.html
    +load 152444-1.html
    +load 185073-1.html
    +load 188474-1.html
    +load 194329-1.html
    +load 197052-1.html
    +load 220542-1.html
    +load 253979-1.html
    +load 269095-1.html
    +load 286733-1.html
    +load 286733-2.html
    +load 299036-1.html
    +skip-if(cocoaWidget&&browserIsRemote) load 328751-1.html # Bug 849747
    +load 408939-1.html
    +load 423373-1.html
    +load 445171-1.html
    +load 468538-1.xhtml
    +load 502103.html
    +load 502869.html
    +load 515278-1.html
    +load 515533-1.html
    +load 515816-1.html
    +load 522326-1.html
    +load 525229-1.html
    +load 536097-1.html
    +load 555462.html
    +load 563514-1.html
    +load 574884-1.html
    +load 574884-2.html
    +load 591330-1.html
    +load 616027-1.html
    +load 650501-1.xhtml
    +load 662185-1.html
    +load 696651-1.html
    +load view-source:699347-1.xml
    +load 721313-1.html
    +load view-source:742414-1.html
    +load 762726-1.html
    +load 981279-1.html
    +load 982285-1.html
    +load 1373045-1.html
    +load 1534346-1.html
    +load 1604307-1.html
    +load 1606499-1.html
    +load 1547895-1.html
    +skip-if(Android) skip-if(isDebugBuild) load 1747514.html # Bug 1780219
    +HTTP load 1810896-1.html
    +load 1854907-1.html
    diff --git a/parser/htmlparser/tests/crashtests/file_445171-1.html b/parser/htmlparser/tests/crashtests/file_445171-1.html
    new file mode 100644
    index 0000000000..de8a5eb065
    --- /dev/null
    +++ b/parser/htmlparser/tests/crashtests/file_445171-1.html
    @@ -0,0 +1 @@
    +
    diff --git a/parser/htmlparser/tests/mochitest/blue.png b/parser/htmlparser/tests/mochitest/blue.png
    new file mode 100644
    index 0000000000..8df58f3a5f
    Binary files /dev/null and b/parser/htmlparser/tests/mochitest/blue.png differ
    diff --git a/parser/htmlparser/tests/mochitest/broken_xml.xhtml b/parser/htmlparser/tests/mochitest/broken_xml.xhtml
    new file mode 100644
    index 0000000000..f81bf3998b
    --- /dev/null
    +++ b/parser/htmlparser/tests/mochitest/broken_xml.xhtml
    @@ -0,0 +1,7 @@
    +
    +  
    +    &nonExistingEntity;
    +  
    +  
    +  
    +
    diff --git a/parser/htmlparser/tests/mochitest/browser.toml b/parser/htmlparser/tests/mochitest/browser.toml
    new file mode 100644
    index 0000000000..3ece65c115
    --- /dev/null
    +++ b/parser/htmlparser/tests/mochitest/browser.toml
    @@ -0,0 +1,15 @@
    +[DEFAULT]
    +prefs = ["nglayout.debug.disable_xul_cache=true"] # we need to reload the XML file to make the test pass
    +
    +["browser_elementindtd.js"]
    +support-files = [
    +  "browser_elementindtd.xml",
    +  "browser_elementindtd.dtd"
    +]
    +
    +["browser_viewsource.js"]
    +support-files = ["file_viewsource.html"]
    +
    +["browser_ysod_telemetry.js"]
    +support-files = ["broken_xml.xhtml"]
    +
    diff --git a/parser/htmlparser/tests/mochitest/browser_elementindtd.dtd b/parser/htmlparser/tests/mochitest/browser_elementindtd.dtd
    new file mode 100644
    index 0000000000..1c2acdcda8
    --- /dev/null
    +++ b/parser/htmlparser/tests/mochitest/browser_elementindtd.dtd
    @@ -0,0 +1,2 @@
    +From dtd

    '> diff --git a/parser/htmlparser/tests/mochitest/browser_elementindtd.js b/parser/htmlparser/tests/mochitest/browser_elementindtd.js new file mode 100644 index 0000000000..bc146ba73e --- /dev/null +++ b/parser/htmlparser/tests/mochitest/browser_elementindtd.js @@ -0,0 +1,31 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * Test for bug 1539759 + * Loads a chrome XML document that has an exteernal DTD file with an entity + * that contains an element, and verifies that that element was not inserted + * into the document (but its content was). + */ + +add_task(async function test() { + await BrowserTestUtils.withNewTab( + getRootDirectory(gTestPath) + "browser_elementindtd.xml", + async function (newBrowser) { + // NB: We load the chrome:// page in the parent process. + testNoElementFromEntity(newBrowser); + } + ); +}); + +function testNoElementFromEntity(newBrowser) { + let doc = newBrowser.contentDocument; + is(doc.body.textContent, "From dtd", "Should load DTD."); + is( + doc.body.firstElementChild, + null, + "Shouldn't have an element inserted from the DTD" + ); +} diff --git a/parser/htmlparser/tests/mochitest/browser_elementindtd.xml b/parser/htmlparser/tests/mochitest/browser_elementindtd.xml new file mode 100644 index 0000000000..937c896f43 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/browser_elementindtd.xml @@ -0,0 +1,8 @@ + + %externaldtd; +]> + +&entitywithelement; + diff --git a/parser/htmlparser/tests/mochitest/browser_viewsource.js b/parser/htmlparser/tests/mochitest/browser_viewsource.js new file mode 100644 index 0000000000..e4d44e05be --- /dev/null +++ b/parser/htmlparser/tests/mochitest/browser_viewsource.js @@ -0,0 +1,28 @@ +"use strict"; + +add_task(async function () { + const PAGE_URL = getRootDirectory(gTestPath) + "file_viewsource.html"; + let viewSourceTab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "view-source:" + PAGE_URL + ); + + let xhrPromise = new Promise(resolve => { + let xhr = new XMLHttpRequest(); + xhr.open("GET", PAGE_URL, true); + xhr.onload = event => resolve(event.target.responseText); + xhr.send(); + }); + + let viewSourceContentPromise = SpecialPowers.spawn( + viewSourceTab.linkedBrowser, + [], + async function () { + return content.document.body.textContent; + } + ); + + let results = await Promise.all([viewSourceContentPromise, xhrPromise]); + is(results[0], results[1], "Sources should match"); + BrowserTestUtils.removeTab(viewSourceTab); +}); diff --git a/parser/htmlparser/tests/mochitest/browser_ysod_telemetry.js b/parser/htmlparser/tests/mochitest/browser_ysod_telemetry.js new file mode 100644 index 0000000000..d7a654cad0 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/browser_ysod_telemetry.js @@ -0,0 +1,49 @@ +"use strict"; + +const { TelemetryTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TelemetryTestUtils.sys.mjs" +); + +add_task(async function test_popup_opened() { + Services.telemetry.clearEvents(); + Services.telemetry.setEventRecordingEnabled("ysod", true); + + const PAGE_URL = getRootDirectory(gTestPath) + "broken_xml.xhtml"; + let viewSourceTab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + PAGE_URL + ); + + let content = await SpecialPowers.spawn( + viewSourceTab.linkedBrowser, + [], + async function () { + return content.document.documentElement.innerHTML; + } + ); + + ok(content.includes("XML"), "Document shows XML error"); + + TelemetryTestUtils.assertEvents( + [ + { + method: "shown", + object: "ysod", + value: PAGE_URL.substr(0, 80), + extra: { + error_code: "11", + location: "3:12", + last_line: " &nonExistingEntity;", + last_line_len: "38", + hidden: "false", + destroyed: "false", + }, + }, + ], + { + category: "ysod", + }, + { process: "parent" } + ); + BrowserTestUtils.removeTab(viewSourceTab); +}); diff --git a/parser/htmlparser/tests/mochitest/bug_502091_iframe.html b/parser/htmlparser/tests/mochitest/bug_502091_iframe.html new file mode 100644 index 0000000000..076d3ed662 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/bug_502091_iframe.html @@ -0,0 +1,17 @@ + + +Crash [@ nsContentSink::ProcessHeaderData] with meta in innerHTML + + +
    + testdiv +
    + +some text here + + + diff --git a/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs b/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs new file mode 100644 index 0000000000..faf44df66c --- /dev/null +++ b/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/javascript", false); + if (request.queryString.includes("report")) { + if (getState("loaded") == "loaded") { + response.write("ok(true, 'This script was supposed to get fetched.');"); + } else { + response.write("ok(false, 'This script was supposed to get fetched.');"); + } + } else { + setState("loaded", "loaded"); + response.write("ok(true, 'This script is supposed to run.');"); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs b/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs new file mode 100644 index 0000000000..5e83e50510 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs @@ -0,0 +1,17 @@ +var timer = null; + +function handleRequest(request, response) { + response.processAsync(); + response.setHeader("Content-Type", "application/javascript", false); + response.write("asyncState = 'mid-async';\n"); + + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + function () { + response.write("asyncState = 'loaded';\n"); + response.finish(); + }, + 5 * 1000 /* milliseconds */, + timer.TYPE_ONE_SHOT + ); +} diff --git a/parser/htmlparser/tests/mochitest/file_base_csp_img.sjs b/parser/htmlparser/tests/mochitest/file_base_csp_img.sjs new file mode 100644 index 0000000000..aae7bde6a1 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_base_csp_img.sjs @@ -0,0 +1,18 @@ +function handleRequest(request, response) { + var hosts = getState("hosts"); + hosts = hosts ? JSON.parse(hosts) : []; + + if (request.queryString == "result") { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/json", false); + response.write(JSON.stringify(hosts)); + + setState("hosts", "[]"); + } else { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "blue.png", false); + + hosts.push(request.host); + setState("hosts", JSON.stringify(hosts)); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug102699.sjs b/parser/htmlparser/tests/mochitest/file_bug102699.sjs new file mode 100644 index 0000000000..6e7c57cae4 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug102699.sjs @@ -0,0 +1,19 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/javascript", false); + if (request.queryString.includes("report")) { + if (getState("loaded") == "loaded") { + response.write( + "ok(false, 'This script was not supposed to get fetched.'); continueAfterReport();" + ); + } else { + response.write( + "ok(true, 'This script was not supposed to get fetched.'); continueAfterReport();" + ); + } + } else { + setState("loaded", "loaded"); + response.write( + 'document.documentElement.setAttribute("data-fail", "FAIL");' + ); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs b/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs new file mode 100644 index 0000000000..d2236de612 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs @@ -0,0 +1,16 @@ +var timer; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript", false); + response.write("ok(true, 'Slow script ran.');"); + response.processAsync(); + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + function () { + response.finish(); + }, + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} diff --git a/parser/htmlparser/tests/mochitest/file_bug534293.sjs b/parser/htmlparser/tests/mochitest/file_bug534293.sjs new file mode 100644 index 0000000000..279897c567 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug534293.sjs @@ -0,0 +1,17 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/javascript", false); + if (request.queryString.includes("report")) { + if (getState("loaded") == "loaded") { + response.write( + "ok(false, 'This script was not supposed to get fetched.');" + ); + } else { + response.write( + "ok(true, 'This script was not supposed to get fetched.');" + ); + } + } else { + setState("loaded", "loaded"); + response.write("ok(false, 'This script is not supposed to run.');"); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug543062.sjs b/parser/htmlparser/tests/mochitest/file_bug543062.sjs new file mode 100644 index 0000000000..508cde5644 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug543062.sjs @@ -0,0 +1,38 @@ +var timer; + +function armTimer(response) { + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + function () { + if ( + getState("docwritepreloadssecond") == "second" && + getState("docwritepreloadsthird") == "third" + ) { + response.write( + "ok(true, 'Second and third scripts should have started loading while the first one is loading');" + ); + response.finish(); + } else { + armTimer(response); + } + }, + 20, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript", false); + if (request.queryString.includes("first")) { + response.write("// first\n"); + response.processAsync(); + armTimer(response); + } else if (request.queryString.includes("second")) { + response.write("// second\n"); + setState("docwritepreloadssecond", "second"); + } else { + response.write("// third\n"); + setState("docwritepreloadsthird", "third"); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs b/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs new file mode 100644 index 0000000000..7cd25ddc08 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs @@ -0,0 +1,17 @@ +var timer = null; // Declare outside to prevent premature GC + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript", false); + response.write("var i = 0;"); + response.bodyOutputStream.flush(); + response.processAsync(); + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + function () { + response.finish(); + }, + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} diff --git a/parser/htmlparser/tests/mochitest/file_bug568470.sjs b/parser/htmlparser/tests/mochitest/file_bug568470.sjs new file mode 100644 index 0000000000..57559e2f6e --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug568470.sjs @@ -0,0 +1,22 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.write(""); + response.write("
    "); + for (var i = 0; i < 2000; i++) { + response.write("Lorem ipsum dolor sit amet. "); + } + response.write("
    "); + response.bodyOutputStream.flush(); + response.processAsync(); + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + function () { + response.finish(); + }, + 1200, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-1.html b/parser/htmlparser/tests/mochitest/file_bug594730-1.html new file mode 100644 index 0000000000..8877311e21 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-1.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-2.html b/parser/htmlparser/tests/mochitest/file_bug594730-2.html new file mode 100644 index 0000000000..f609df3976 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-2.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-3.html b/parser/htmlparser/tests/mochitest/file_bug594730-3.html new file mode 100644 index 0000000000..d6470d80fc --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-3.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-4.html b/parser/htmlparser/tests/mochitest/file_bug594730-4.html new file mode 100644 index 0000000000..bdce353a59 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-4.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-5.html b/parser/htmlparser/tests/mochitest/file_bug594730-5.html new file mode 100644 index 0000000000..9fdbdded5c --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-5.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-6.html b/parser/htmlparser/tests/mochitest/file_bug594730-6.html new file mode 100644 index 0000000000..570fa460bc --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-6.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-7.html b/parser/htmlparser/tests/mochitest/file_bug594730-7.html new file mode 100644 index 0000000000..92c19c8ffa --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-7.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-8.html b/parser/htmlparser/tests/mochitest/file_bug594730-8.html new file mode 100644 index 0000000000..a9e7525c2c --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-8.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-9.html b/parser/htmlparser/tests/mochitest/file_bug594730-9.html new file mode 100644 index 0000000000..60fab3a399 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug594730-9.html @@ -0,0 +1,5 @@ + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug642908.sjs b/parser/htmlparser/tests/mochitest/file_bug642908.sjs new file mode 100644 index 0000000000..6d83609216 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug642908.sjs @@ -0,0 +1,19 @@ +function handleRequest(request, response) { + if (request.queryString.includes("report")) { + response.setHeader("Content-Type", "text/javascript", false); + if (getState("loaded") == "loaded") { + response.write( + "ok(false, 'There was an attempt to preload the image.');" + ); + } else { + response.write("ok(true, 'There was no attempt to preload the image.');"); + } + response.write("SimpleTest.finish();"); + } else { + setState("loaded", "loaded"); + response.setHeader("Content-Type", "image/svg", false); + response.write( + "Not supposed to load this" + ); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug655682.sjs b/parser/htmlparser/tests/mochitest/file_bug655682.sjs new file mode 100644 index 0000000000..2f1e0211c3 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug655682.sjs @@ -0,0 +1,31 @@ +var timer; +var callback; + +function handleRequest(request, response) { + if (request.queryString.includes("trigger")) { + setState("triggered", "triggered"); + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript; charset=utf-8", false); + response.write(";"); + } else { + // Reset the state when running more than once in same browser session. + setState("triggered", ""); + + response.processAsync(); + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + response.write("
    +
    +
    + --> +
    + + + +
    "); + response.bodyOutputStream.flush(); + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + + callback = function () { + if (getState("triggered") == "triggered") { + response.write("
    AB
    "); + response.finish(); + } else { + timer.initWithCallback(callback, 10, Ci.nsITimer.TYPE_ONE_SHOT); + } + }; + timer.initWithCallback(callback, 10, Ci.nsITimer.TYPE_ONE_SHOT); + } +} diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_enc_error.html b/parser/htmlparser/tests/mochitest/file_bug672453_enc_error.html new file mode 100644 index 0000000000..07d037497d --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_enc_error.html @@ -0,0 +1,10 @@ + + + + + Encoding error + + +

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_enc_error_inherited.html b/parser/htmlparser/tests/mochitest/file_bug672453_enc_error_inherited.html new file mode 100644 index 0000000000..06d44ba9b1 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_enc_error_inherited.html @@ -0,0 +1,9 @@ + + + + Encoding error + + +

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html b/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html new file mode 100644 index 0000000000..0e76edd65b --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html^headers^ new file mode 100644 index 0000000000..0cb0a6b1bf --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_replacement.html^headers^ @@ -0,0 +1,2 @@ +HTTP 200 OK +Content-Type: text/html; charset=iso-2022-kr diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html new file mode 100644 index 0000000000..0e76edd65b --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^ new file mode 100644 index 0000000000..35885d0cc1 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^ @@ -0,0 +1,2 @@ +HTTP 200 OK +Content-Type: text/html; charset=bogus diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html b/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html new file mode 100644 index 0000000000..1e0b5870f7 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html @@ -0,0 +1,1028 @@ + +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_after_head.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_after_head.html new file mode 100644 index 0000000000..3def05a535 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_after_head.html @@ -0,0 +1,10 @@ + + + + Meta after head + + + +

    Meta after head

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html new file mode 100644 index 0000000000..dab8635286 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_replacement.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_replacement.html new file mode 100644 index 0000000000..9bbbe52313 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_replacement.html @@ -0,0 +1,10 @@ + + + + + Replacement encoding + + +

    Replacement encoding

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html new file mode 100644 index 0000000000..84bd1d3641 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html @@ -0,0 +1,1028 @@ + +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_speculation_fail.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_speculation_fail.html new file mode 100644 index 0000000000..b63255e981 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_speculation_fail.html @@ -0,0 +1,10 @@ + + + + Speculation filure + + + +

    Speculation fails

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html new file mode 100644 index 0000000000..91111d7e74 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html new file mode 100644 index 0000000000..250f6fa67c --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html new file mode 100644 index 0000000000..2e6fb9c8b7 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html b/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html new file mode 100644 index 0000000000..0e76edd65b --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_xml_decl.html b/parser/htmlparser/tests/mochitest/file_bug672453_xml_decl.html new file mode 100644 index 0000000000..ed350a1157 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_xml_decl.html @@ -0,0 +1,10 @@ + + + + + Has only XML decl + + +

    Only XML decl

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_xml_speculation_fail.html b/parser/htmlparser/tests/mochitest/file_bug672453_xml_speculation_fail.html new file mode 100644 index 0000000000..08ba678590 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug672453_xml_speculation_fail.html @@ -0,0 +1,10 @@ + + + + + Speculation filure + + +

    Speculation fails

    + + diff --git a/parser/htmlparser/tests/mochitest/file_bug688580.js b/parser/htmlparser/tests/mochitest/file_bug688580.js new file mode 100644 index 0000000000..bee04dde23 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug688580.js @@ -0,0 +1,8 @@ +/* globals state:true */ +is( + document.readyState, + "interactive", + "readyState should be interactive during defer." +); +is(state, "readyState interactive", "Bad state upon defer"); +state = "defer"; diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.html b/parser/htmlparser/tests/mochitest/file_bug716579-16.html new file mode 100644 index 0000000000..1cd07ca9a5 Binary files /dev/null and b/parser/htmlparser/tests/mochitest/file_bug716579-16.html differ diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^ new file mode 100644 index 0000000000..3fadd3bad3 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=windows-874 diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml new file mode 100644 index 0000000000..cc828a7ce7 Binary files /dev/null and b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml differ diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^ new file mode 100644 index 0000000000..208b923e8f --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^ @@ -0,0 +1 @@ +Content-Type: application/xhtml+xml; charset=windows-874 diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.html b/parser/htmlparser/tests/mochitest/file_bug716579-8.html new file mode 100644 index 0000000000..bbeb036db1 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html @@ -0,0 +1,3 @@ + diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^ new file mode 100644 index 0000000000..3fadd3bad3 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^ @@ -0,0 +1 @@ +Content-Type: text/html; charset=windows-874 diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml new file mode 100644 index 0000000000..a1221cafc7 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml @@ -0,0 +1,7 @@ + + + + + diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^ new file mode 100644 index 0000000000..208b923e8f --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^ @@ -0,0 +1 @@ +Content-Type: application/xhtml+xml; charset=windows-874 diff --git a/parser/htmlparser/tests/mochitest/file_bug717180.html b/parser/htmlparser/tests/mochitest/file_bug717180.html new file mode 100644 index 0000000000..ff43ca4091 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_bug717180.html @@ -0,0 +1 @@ +SUCCESS diff --git a/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js b/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js new file mode 100644 index 0000000000..5ba15f287b --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js @@ -0,0 +1,7 @@ +/* globals state:true */ +is( + document.readyState, + "interactive", + "readyState should be interactive during defer." +); +state = "defer"; diff --git a/parser/htmlparser/tests/mochitest/file_img_picture_preload.html b/parser/htmlparser/tests/mochitest/file_img_picture_preload.html new file mode 100644 index 0000000000..a5a55a56a3 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_img_picture_preload.html @@ -0,0 +1,167 @@ + + + + + Test for Bug 1067345 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs b/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs new file mode 100644 index 0000000000..e91da04352 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs @@ -0,0 +1,27 @@ +// Return a PNG, saving an array of query strings we see as state. When query +// string is 'status', return array as JSON + +function handleRequest(request, response) { + var seenImages = getState("seenImages"); + seenImages = seenImages ? JSON.parse(seenImages) : []; + + response.setHeader("Cache-Control", "must-revalidate", false); + + if (request.queryString == "status") { + response.setHeader("Content-Type", "text/javascript", false); + response.write(JSON.stringify(seenImages)); + } else if (request.queryString == "reset") { + // Respond with how many requests we had seen, drop them + response.setHeader("Content-Type", "text/plain", false); + response.write(String(seenImages.length)); + seenImages = []; + } else { + // Return an image + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "blue.png", false); + dump(request.queryString + "\n"); + seenImages.push(request.queryString); + } + + setState("seenImages", JSON.stringify(seenImages)); +} diff --git a/parser/htmlparser/tests/mochitest/file_viewsource.html b/parser/htmlparser/tests/mochitest/file_viewsource.html new file mode 100644 index 0000000000..3ed00150a7 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_viewsource.html @@ -0,0 +1,18 @@ + + + + Test for view source + + + + + + + + + + diff --git a/parser/htmlparser/tests/mochitest/file_xml_parse_error.js b/parser/htmlparser/tests/mochitest/file_xml_parse_error.js new file mode 100644 index 0000000000..8ab5425bce --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_xml_parse_error.js @@ -0,0 +1 @@ +parent.ok(true, "Loaded script."); diff --git a/parser/htmlparser/tests/mochitest/file_xml_parse_error.xml b/parser/htmlparser/tests/mochitest/file_xml_parse_error.xml new file mode 100644 index 0000000000..d75a4525e4 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/file_xml_parse_error.xml @@ -0,0 +1,3 @@ + + +

    BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +(1,21): self-closing-flag-on-end-tag +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +(1,20): unexpected-character-after-solidus-in-tag +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +(1,31): attributes-in-end-tag +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| BAR +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +| QUX +#errors +(1,3): expected-doctype-but-got-chars +#document +| +| +| +| "FOO" +|

    <p>

    +#errors +(1,8): expected-doctype-but-got-start-tag +(1,28): unexpected-end-tag +#document +| +| +| --> EOF +#errors +(1,52): unexpected-end-tag +#document +| +| +| +| +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +|


    +| +| +|

    + +#data + +#errors +(1,10): expected-doctype-but-got-start-tag +(1,10): eof-in-frameset +#document +| +| +| diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat new file mode 100644 index 0000000000..87d94786b1 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat @@ -0,0 +1,847 @@ +#data + +#errors +#document +| +| +| +| +| + +#data +a +#errors +(1,28) expected-dashes-or-doctype +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +(1,34) unexpected-start-tag-in-select +(1,40) unexpected-end-tag-in-select +#document +| +| +| +| +| +#errors +(1,42) unexpected-start-tag-in-select +(1,48) unexpected-end-tag-in-select +#document +| +| +| +| +|

    +#errors +(1,33) foster-parenting-start-tag +#document +| +| +| +| +| +| + +#data +
    foo
    +#errors +(1,33) foster-parenting-start-tag +#document +| +| +| +| +| +| +| "foo" +| + +#data +
    foobar
    +#errors +(1,33) foster-parenting-start-tag +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| + +#data +
    foobar
    +#errors +(1,40) foster-parenting-start-tag +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| + +#data +
    foobar
    +#errors +(1,44) foster-parenting-start-tag +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| +| + +#data +
    foobar
    +#errors +#document +| +| +| +| +| +| +| +|
    +| +| +| "foo" +| +| "bar" + +#data +
    foobar

    baz

    +#errors +#document +| +| +| +| +| +| +| +|
    +| +| +| "foo" +| +| "bar" +|

    +| "baz" + +#data +
    foobar

    baz

    +#errors +#document +| +| +| +| +| +|
    +| +| +| "foo" +| +| "bar" +|

    +| "baz" + +#data +
    foobar

    baz

    quux +#errors +(1,65) unexpected-html-element-in-foreign-content +(1,76) XXX-undefined-error +#document +| +| +| +| +| +|
    +| +| +| "foo" +| +| "bar" +|

    +| "baz" +|

    +| "quux" + +#data +
    foobarbaz

    quux +#errors +(1,73) unexpected-end-tag +(1,73) expected-one-end-tag-but-got-another +#document +| +| +| +| +| +|
    +| +| +| "foo" +| +| "bar" +| "baz" +|

    +| "quux" + +#data +foobar

    baz

    quux +#errors +(1,43) foster-parenting-start-tag +(1,66) foster-parenting-start-tag +(1,67) foster-parenting-character +(1,68) foster-parenting-character +(1,69) foster-parenting-character +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

    +| "baz" +| +| +|

    +| "quux" + +#data +

    quux +#errors +(1,49) unexpected-start-tag-in-select +(1,52) unexpected-start-tag-in-select +(1,59) unexpected-end-tag-in-select +(1,62) unexpected-start-tag-in-select +(1,69) unexpected-end-tag-in-select +(1,72) unexpected-start-tag-in-select +(1,83) unexpected-table-element-end-tag-in-select-in-table +#document +| +| +| +| +| +| +| +|
    +|

    quux +#errors +(1,36) unexpected-start-tag-implies-table-voodoo +(1,41) unexpected-start-tag-in-select +(1,44) unexpected-start-tag-in-select +(1,51) unexpected-end-tag-in-select +(1,54) unexpected-start-tag-in-select +(1,61) unexpected-end-tag-in-select +(1,64) unexpected-start-tag-in-select +(1,75) unexpected-table-element-end-tag-in-select-in-table +#document +| +| +| +| +| +|

    +| "quux" + +#data +foobar

    baz +#errors +(1,40) expected-eof-but-got-start-tag +(1,63) unexpected-html-element-in-foreign-content +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

    +| "baz" + +#data +foobar

    baz +#errors +(1,33) unexpected-start-tag-after-body +(1,56) unexpected-html-element-in-foreign-content +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

    +| "baz" + +#data +

    +#errors +(1,30) unexpected-start-tag-in-frameset +(1,33) unexpected-start-tag-in-frameset +(1,37) unexpected-end-tag-in-frameset +(1,40) unexpected-start-tag-in-frameset +(1,44) unexpected-end-tag-in-frameset +(1,47) unexpected-start-tag-in-frameset +(1,53) unexpected-start-tag-in-frameset +(1,53) eof-in-frameset +#document +| +| +| +| + +#data +

    +#errors +(1,41) unexpected-start-tag-after-frameset +(1,44) unexpected-start-tag-after-frameset +(1,48) unexpected-end-tag-after-frameset +(1,51) unexpected-start-tag-after-frameset +(1,55) unexpected-end-tag-after-frameset +(1,58) unexpected-start-tag-after-frameset +(1,64) unexpected-start-tag-after-frameset +#document +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| +| xlink href="foo" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data +bar +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" +| "bar" + +#data + +#errors +(1,5) expected-doctype-but-got-start-tag +(1,12) unexpected-end-tag +(1,12) unexpected-end-tag +(1,12) expected-closing-tag-but-got-eof +#document +| +| +| +| + +#data +

    a +#errors +(1,5) expected-doctype-but-got-start-tag +(1,16) unexpected-end-tag +(1,16) end-tag-too-early +#document +| +| +| +|
    +| +| "a" + +#data +
    a +#errors +(1,5) expected-doctype-but-got-start-tag +(1,22) unexpected-end-tag +(1,22) end-tag-too-early +#document +| +| +| +|
    +| +| +| "a" + +#data +
    +#errors +(1,5) expected-doctype-but-got-start-tag +(1,22) unexpected-end-tag +(1,28) expected-closing-tag-but-got-eof +#document +| +| +| +|
    +| +| +| + +#data +
    a +#errors +(1,5) expected-doctype-but-got-start-tag +(1,43) unexpected-end-tag +(1,43) end-tag-too-early +(1,44) expected-closing-tag-but-got-eof +#document +| +| +| +|
    +| +| +| +| +| "a" + +#data +

    a +#errors +(1,5) expected-doctype-but-got-start-tag +(1,40) end-tag-too-early +(1,41) expected-closing-tag-but-got-eof +#document +| +| +| +|

    +| +| +| +|

    +| "a" + +#data +
      a +#errors +(1,40) unexpected-html-element-in-foreign-content +(1,41) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +|
      +| +|
        +| "a" + +#data +
          a +#errors +(1,35) unexpected-html-element-in-foreign-content +(1,36) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +| +|
            +| "a" + +#data +

            +#errors +(1,32) expected-closing-tag-but-got-eof +#document +| +| +| +| +|

            +| +| +|

            + +#data +

            +#errors +(1,33) expected-closing-tag-but-got-eof +#document +| +| +| +| +|

            +| +| +|

            + +#data +

            +#errors +(1,5) expected-doctype-but-got-start-tag +(1,50) unexpected-end-tag +(1,53) expected-closing-tag-but-got-eof +#document +| +| +| +|

            +| +| +| +|

            +|

            + +#data +
            +#errors +(1,6) expected-doctype-but-got-start-tag +(1,71) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +|
            +| +|
            +| +| + +#data +
            +#errors +(1,6) expected-doctype-but-got-start-tag +(1,83) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +| +|
            +|
            +| + +#data + +#errors +(1,5) expected-doctype-but-got-start-tag +(1,28) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data +

    +#errors +(1,7) expected-doctype-but-got-start-tag +(1,12) unexpected-start-tag-implies-table-voodoo +(1,22) eof-in-table +#document +| +| +| +| +|
    +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,18) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,22) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,18) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,22) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,18) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,22) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,18) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,22) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,21) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,25) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,54) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +| + +#data +
    +#errors +(1,6) expected-doctype-but-got-start-tag +(1,144) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +| +|
    +| +| +| +| +| + +#data + +#errors +(1,6) expected-doctype-but-got-start-tag +(1,153) expected-closing-tag-but-got-eof +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat new file mode 100644 index 0000000000..ad62cdf659 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat @@ -0,0 +1,482 @@ +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentscripttype="" +| contentstyletype="" +| diffuseConstant="" +| edgeMode="" +| externalresourcesrequired="" +| filterUnits="" +| filterres="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentscripttype="" +| contentstyletype="" +| diffuseConstant="" +| edgeMode="" +| externalresourcesrequired="" +| filterUnits="" +| filterres="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentscripttype="" +| contentstyletype="" +| diffuseConstant="" +| edgeMode="" +| externalresourcesrequired="" +| filterUnits="" +| filterres="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributename="" +| attributetype="" +| basefrequency="" +| baseprofile="" +| calcmode="" +| clippathunits="" +| contentscripttype="" +| contentstyletype="" +| diffuseconstant="" +| edgemode="" +| externalresourcesrequired="" +| filterres="" +| filterunits="" +| glyphref="" +| gradienttransform="" +| gradientunits="" +| kernelmatrix="" +| kernelunitlength="" +| keypoints="" +| keysplines="" +| keytimes="" +| lengthadjust="" +| limitingconeangle="" +| markerheight="" +| markerunits="" +| markerwidth="" +| maskcontentunits="" +| maskunits="" +| numoctaves="" +| pathlength="" +| patterncontentunits="" +| patterntransform="" +| patternunits="" +| pointsatx="" +| pointsaty="" +| pointsatz="" +| preservealpha="" +| preserveaspectratio="" +| primitiveunits="" +| refx="" +| refy="" +| repeatcount="" +| repeatdur="" +| requiredextensions="" +| requiredfeatures="" +| specularconstant="" +| specularexponent="" +| spreadmethod="" +| startoffset="" +| stddeviation="" +| stitchtiles="" +| surfacescale="" +| systemlanguage="" +| tablevalues="" +| targetx="" +| targety="" +| textlength="" +| viewbox="" +| viewtarget="" +| xchannelselector="" +| ychannelselector="" +| zoomandpan="" + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat new file mode 100644 index 0000000000..63107d277b --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat @@ -0,0 +1,62 @@ +#data +

    foobazeggs

    spam

    quuxbar +#errors +#document +| +| +| +| +|

    +| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

    +| "spam" +| +| +| +|
    +| +| +| "quux" +| "bar" + +#data +foobazeggs

    spam
    quuxbar +#errors +#document +| +| +| +| +| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

    +| "spam" +| +| +| +|
    +| +| +| "quux" +| "bar" diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat new file mode 100644 index 0000000000..a08b7649eb --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat @@ -0,0 +1,75 @@ +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +(1,38): non-html-root +#document +| +| +| abc:def="gh" +| +| +| + +#data + +#errors +(1,53): non-html-root +#document +| +| +| xml:lang="bar" +| +| + +#data + +#errors +#document +| +| +| 123="456" +| +| + +#data + +#errors +(1,43): non-html-root +#document +| +| +| 123="456" +| 789="012" +| +| + +#data + +#errors +#document +| +| +| +| +| 789="012" diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat new file mode 100644 index 0000000000..93d06a8717 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat @@ -0,0 +1,216 @@ +#data +

    X +#errors +(1,31): unexpected-end-tag +(1,36): expected-closing-tag-but-got-eof +#document +| +| +| +| +|

    +| +| +| +| +| +| +| " " +|

    +| "X" + +#data +

    +

    X +#errors +(1,3): expected-doctype-but-got-start-tag +(1,16): unexpected-end-tag +(2,4): expected-closing-tag-but-got-eof +#document +| +| +| +|

    +| +| +| +| +| +| +| " +" +|

    +| "X" + +#data + +#errors +(1,29): expected-eof-but-got-start-tag +(1,29): unexpected-start-tag-ignored +#document +| +| +| +| +| " " + +#data + +#errors +(1,28): unexpected-start-tag-after-body +#document +| +| +| +| +| + +#data + +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| +| +| +| + +#data +X +#errors +(1,29): unexpected-start-tag-after-body +#document +| +| +| +| +| +| "X" + +#data +<!doctype html><table> X<meta></table> +#errors +(1,23): foster-parenting-character +(1,24): foster-parenting-character +(1,30): foster-parenting-start-character +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " X" +| <meta> +| <table> + +#data +<!doctype html><table> x</table> +#errors +(1,23): foster-parenting-character +(1,24): foster-parenting-character +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> + +#data +<!doctype html><table> x </table> +#errors +(1,23): foster-parenting-character +(1,24): foster-parenting-character +(1,25): foster-parenting-character +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x " +| <table> + +#data +<!doctype html><table><tr> x</table> +#errors +(1,27): foster-parenting-character +(1,28): foster-parenting-character +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table>X<style> <tr>x </style> </table> +#errors +(1,23): foster-parenting-character +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" +| <table> +| <style> +| " <tr>x " +| " " + +#data +<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div> +#errors +(1,30): foster-parenting-start-tag +(1,31): foster-parenting-character +(1,32): foster-parenting-character +(1,33): foster-parenting-character +(1,37): foster-parenting-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <a> +| "foo" +| <table> +| " " +| <tbody> +| <tr> +| <td> +| "bar" +| " " + +#data +<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,7): unexpected-start-tag-ignored +(1,15): unexpected-end-tag +(1,23): unexpected-end-tag +(1,33): unexpected-start-tag +(1,99): expected-named-closing-tag-but-got-eof +(1,99): eof-in-frameset +#document +| <html> +| <head> +| <frameset> +| <frame> +| <frameset> +| <frame> +| <noframes> +| "</frameset><noframes>" + +#data +<!DOCTYPE html><object></html> +#errors +(1,30): expected-body-in-scope +(1,30): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat new file mode 100644 index 0000000000..1c57f14a32 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat @@ -0,0 +1,2396 @@ +#data +<!doctype html><script> +#errors +(1,23): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script>a +#errors +(1,24): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<!doctype html><script>< +#errors +(1,24): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<!doctype html><script></ +#errors +(1,25): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<!doctype html><script></S +#errors +(1,26): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<!doctype html><script></SC +#errors +(1,27): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<!doctype html><script></SCR +#errors +(1,28): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<!doctype html><script></SCRI +#errors +(1,29): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<!doctype html><script></SCRIP +#errors +(1,30): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +(1,31): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +(1,32): expected-attribute-name-but-got-eof +(1,32): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script></s +#errors +(1,26): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<!doctype html><script></sc +#errors +(1,27): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<!doctype html><script></scr +#errors +(1,28): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<!doctype html><script></scri +#errors +(1,29): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<!doctype html><script></scrip +#errors +(1,30): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<!doctype html><script></script +#errors +(1,31): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<!doctype html><script></script +#errors +(1,32): expected-attribute-name-but-got-eof +(1,32): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script><! +#errors +(1,25): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<!doctype html><script><!a +#errors +(1,26): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<!doctype html><script><!- +#errors +(1,26): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<!doctype html><script><!-a +#errors +(1,27): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<!doctype html><script><!-- +#errors +(1,27): expected-named-closing-tag-but-got-eof +(1,27): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--a +#errors +(1,28): expected-named-closing-tag-but-got-eof +(1,28): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<!doctype html><script><!--< +#errors +(1,28): expected-named-closing-tag-but-got-eof +(1,28): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<!doctype html><script><!--<a +#errors +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<!doctype html><script><!--</ +#errors +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<!doctype html><script><!--</script +#errors +(1,35): expected-named-closing-tag-but-got-eof +(1,35): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<!doctype html><script><!--</script +#errors +(1,36): expected-attribute-name-but-got-eof +(1,36): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--<s +#errors +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<!doctype html><script><!--<script +#errors +(1,34): expected-named-closing-tag-but-got-eof +(1,34): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<!doctype html><script><!--<script +#errors +(1,35): eof-in-script-in-script +(1,35): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<!doctype html><script><!--<script < +#errors +(1,36): eof-in-script-in-script +(1,36): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<!doctype html><script><!--<script <a +#errors +(1,37): eof-in-script-in-script +(1,37): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<!doctype html><script><!--<script </ +#errors +(1,37): eof-in-script-in-script +(1,37): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<!doctype html><script><!--<script </s +#errors +(1,38): eof-in-script-in-script +(1,38): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +(1,43): eof-in-script-in-script +(1,43): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<!doctype html><script><!--<script </scripta +#errors +(1,44): eof-in-script-in-script +(1,44): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +(1,44): expected-named-closing-tag-but-got-eof +(1,44): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script> +#errors +(1,44): expected-named-closing-tag-but-got-eof +(1,44): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<!doctype html><script><!--<script </script/ +#errors +(1,44): expected-named-closing-tag-but-got-eof +(1,44): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<!doctype html><script><!--<script </script < +#errors +(1,45): expected-named-closing-tag-but-got-eof +(1,45): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<!doctype html><script><!--<script </script <a +#errors +(1,46): expected-named-closing-tag-but-got-eof +(1,46): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<!doctype html><script><!--<script </script </ +#errors +(1,46): expected-named-closing-tag-but-got-eof +(1,46): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +(1,52): expected-named-closing-tag-but-got-eof +(1,52): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +(1,53): expected-attribute-name-but-got-eof +(1,53): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script/ +#errors +(1,53): unexpected-EOF-after-solidus-in-tag +(1,53): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script - +#errors +(1,36): eof-in-script-in-script +(1,36): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<!doctype html><script><!--<script -a +#errors +(1,37): eof-in-script-in-script +(1,37): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<!doctype html><script><!--<script -< +#errors +(1,37): eof-in-script-in-script +(1,37): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -<" +| <body> + +#data +<!doctype html><script><!--<script -- +#errors +(1,37): eof-in-script-in-script +(1,37): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<!doctype html><script><!--<script --a +#errors +(1,38): eof-in-script-in-script +(1,38): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<!doctype html><script><!--<script --< +#errors +(1,38): eof-in-script-in-script +(1,38): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --<" +| <body> + +#data +<!doctype html><script><!--<script --> +#errors +(1,38): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script -->< +#errors +(1,39): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<!doctype html><script><!--<script --></ +#errors +(1,40): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +(1,46): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +(1,47): expected-attribute-name-but-got-eof +(1,47): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script/ +#errors +(1,47): unexpected-EOF-after-solidus-in-tag +(1,47): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script><\/script>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<!doctype html><script><!--<script></scr'+'ipt>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>--><!--</script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-- ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- -></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- - ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<!doctype html><script><!--<script>--!></script>X +#errors +(1,49): expected-named-closing-tag-but-got-eof +(1,49): unexpected-EOF-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<!doctype html><script><!--<scr'+'ipt></script>--></script> +#errors +(1,59): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<!doctype html><script><!--<script></scr'+'ipt></script>X +#errors +(1,57): expected-named-closing-tag-but-got-eof +(1,57): unexpected-eof-in-text-mode +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<!doctype html><style><!--<style></style>--></style> +#errors +(1,52): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<!doctype html><style><!--</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<!doctype html><style><!--...</style>...--></style> +#errors +(1,51): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<!doctype html><style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<!doctype html><style><!--...<style><!--...--!></style>--></style> +#errors +(1,66): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<!doctype html><style><!--...</style><!-- --><style>@import ...</style> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<!doctype html><style>...<style><!--...</style><!-- --></style> +#errors +(1,63): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<!doctype html><style>...<!--[if IE]><style>...</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<!doctype html><title><!--<title>--> +#errors +(1,52): unexpected-end-tag +#document +| +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<!doctype html><title></title> +#errors +#document +| +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +(1,52): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<!doctype html><noscript><!--<noscript></noscript>--></noscript> +#errors +(1,64): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<!doctype html><noscript><!--</noscript>X<noscript>--></noscript> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<!doctype html><noscript><iframe></noscript>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<!doctype html><noframes><!--<noframes></noframes>--></noframes> +#errors +(1,64): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<!doctype html><noframes><body><script><!--...</script></body></noframes></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<!doctype html><textarea><!--<textarea></textarea>--></textarea> +#errors +(1,64): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<!doctype html><textarea></textarea></textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<!doctype html><textarea><</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<" + +#data +<!doctype html><textarea>a<b</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "a<b" + +#data +<!doctype html><iframe><!--<iframe></iframe>--></iframe> +#errors +(1,56): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<!doctype html><iframe>...<!--X->...<!--/X->...</iframe> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<!doctype html><xmp><!--<xmp></xmp>--></xmp> +#errors +(1,44): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<!doctype html><style></style</style> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "</style" +| <body> + +#data +<!doctype html><style></stylee</style> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "</stylee" +| <body> + +#data +<!doctype html><noembed><!--<noembed></noembed>--></noembed> +#errors +(1,60): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<script> +#errors +(1,8): expected-doctype-but-got-start-tag +(1,8): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script>a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,9): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<script>< +#errors +(1,8): expected-doctype-but-got-start-tag +(1,9): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<script></ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,10): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<script></S +#errors +(1,8): expected-doctype-but-got-start-tag +(1,11): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<script></SC +#errors +(1,8): expected-doctype-but-got-start-tag +(1,12): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<script></SCR +#errors +(1,8): expected-doctype-but-got-start-tag +(1,13): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<script></SCRI +#errors +(1,8): expected-doctype-but-got-start-tag +(1,14): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<script></SCRIP +#errors +(1,8): expected-doctype-but-got-start-tag +(1,15): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<script></SCRIPT +#errors +(1,8): expected-doctype-but-got-start-tag +(1,16): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<script></SCRIPT +#errors +(1,8): expected-doctype-but-got-start-tag +(1,17): expected-attribute-name-but-got-eof +(1,17): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script></s +#errors +(1,8): expected-doctype-but-got-start-tag +(1,11): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<script></sc +#errors +(1,8): expected-doctype-but-got-start-tag +(1,12): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<script></scr +#errors +(1,8): expected-doctype-but-got-start-tag +(1,13): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<script></scri +#errors +(1,8): expected-doctype-but-got-start-tag +(1,14): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<script></scrip +#errors +(1,8): expected-doctype-but-got-start-tag +(1,15): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<script></script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,16): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<script></script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,17): expected-attribute-name-but-got-eof +(1,17): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script><! +#errors +(1,8): expected-doctype-but-got-start-tag +(1,10): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<script><!a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,11): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<script><!- +#errors +(1,8): expected-doctype-but-got-start-tag +(1,11): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<script><!-a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,12): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<script><!-- +#errors +(1,8): expected-doctype-but-got-start-tag +(1,12): expected-named-closing-tag-but-got-eof +(1,12): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,13): expected-named-closing-tag-but-got-eof +(1,13): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<script><!--< +#errors +(1,8): expected-doctype-but-got-start-tag +(1,13): expected-named-closing-tag-but-got-eof +(1,13): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<script><!--<a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,14): expected-named-closing-tag-but-got-eof +(1,14): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<script><!--</ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,14): expected-named-closing-tag-but-got-eof +(1,14): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<script><!--</script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,20): expected-named-closing-tag-but-got-eof +(1,20): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<script><!--</script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,21): expected-attribute-name-but-got-eof +(1,21): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--<s +#errors +(1,8): expected-doctype-but-got-start-tag +(1,14): expected-named-closing-tag-but-got-eof +(1,14): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<script><!--<script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,19): expected-named-closing-tag-but-got-eof +(1,19): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<script><!--<script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,20): eof-in-script-in-script +(1,20): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<script><!--<script < +#errors +(1,8): expected-doctype-but-got-start-tag +(1,21): eof-in-script-in-script +(1,21): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<script><!--<script <a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,22): eof-in-script-in-script +(1,22): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<script><!--<script </ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,22): eof-in-script-in-script +(1,22): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<script><!--<script </s +#errors +(1,8): expected-doctype-but-got-start-tag +(1,23): eof-in-script-in-script +(1,23): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<script><!--<script </script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,28): eof-in-script-in-script +(1,28): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<script><!--<script </scripta +#errors +(1,8): expected-doctype-but-got-start-tag +(1,29): eof-in-script-in-script +(1,29): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<script><!--<script </script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script> +#errors +(1,8): expected-doctype-but-got-start-tag +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<script><!--<script </script/ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,29): expected-named-closing-tag-but-got-eof +(1,29): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<script><!--<script </script < +#errors +(1,8): expected-doctype-but-got-start-tag +(1,30): expected-named-closing-tag-but-got-eof +(1,30): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<script><!--<script </script <a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,31): expected-named-closing-tag-but-got-eof +(1,31): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<script><!--<script </script </ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,31): expected-named-closing-tag-but-got-eof +(1,31): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<script><!--<script </script </script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,37): expected-named-closing-tag-but-got-eof +(1,37): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<script><!--<script </script </script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,38): expected-attribute-name-but-got-eof +(1,38): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script/ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,38): unexpected-EOF-after-solidus-in-tag +(1,38): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script - +#errors +(1,8): expected-doctype-but-got-start-tag +(1,21): eof-in-script-in-script +(1,21): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<script><!--<script -a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,22): eof-in-script-in-script +(1,22): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<script><!--<script -- +#errors +(1,8): expected-doctype-but-got-start-tag +(1,22): eof-in-script-in-script +(1,22): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<script><!--<script --a +#errors +(1,8): expected-doctype-but-got-start-tag +(1,23): eof-in-script-in-script +(1,23): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<script><!--<script --> +#errors +(1,8): expected-doctype-but-got-start-tag +(1,23): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script -->< +#errors +(1,8): expected-doctype-but-got-start-tag +(1,24): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<script><!--<script --></ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,25): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<script><!--<script --></script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,31): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<script><!--<script --></script +#errors +(1,8): expected-doctype-but-got-start-tag +(1,32): expected-attribute-name-but-got-eof +(1,32): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script/ +#errors +(1,8): expected-doctype-but-got-start-tag +(1,32): unexpected-EOF-after-solidus-in-tag +(1,32): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script><\/script>--></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<script><!--<script></scr'+'ipt>--></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<script><!--<script></script><script></script></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<script><!--<script></script><script></script>--><!--</script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<script><!--<script></script><script></script>-- ></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<script><!--<script></script><script></script>- -></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<script><!--<script></script><script></script>- - ></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<script><!--<script></script><script></script>-></script> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<script><!--<script>--!></script>X +#errors +(1,8): expected-doctype-but-got-start-tag +(1,34): expected-named-closing-tag-but-got-eof +(1,34): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<script><!--<scr'+'ipt></script>--></script> +#errors +(1,8): expected-doctype-but-got-start-tag +(1,44): unexpected-end-tag +#document +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<script><!--<script></scr'+'ipt></script>X +#errors +(1,8): expected-doctype-but-got-start-tag +(1,42): expected-named-closing-tag-but-got-eof +(1,42): unexpected-eof-in-text-mode +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<style><!--<style></style>--></style> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,37): unexpected-end-tag +#document +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<style><!--</style>X +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<style><!--...</style>...--></style> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,36): unexpected-end-tag +#document +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<style><!--...<style><!--...--!></style>--></style> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,51): unexpected-end-tag +#document +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<style><!--...</style><!-- --><style>@import ...</style> +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<style>...<style><!--...</style><!-- --></style> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,48): unexpected-end-tag +#document +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<style>...<!--[if IE]><style>...</style>X +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<title><!--<title>--> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,37): unexpected-end-tag +#document +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<title></title> +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +(1,7): expected-doctype-but-got-start-tag +(1,37): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<noscript><!--<noscript></noscript>--></noscript> +#errors +(1,10): expected-doctype-but-got-start-tag +(1,49): unexpected-end-tag +#document +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<noscript><!--</noscript>X<noscript>--></noscript> +#errors +(1,10): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<noscript><iframe></noscript>X +#errors +(1,10): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<noframes><!--<noframes></noframes>--></noframes> +#errors +(1,10): expected-doctype-but-got-start-tag +(1,49): unexpected-end-tag +#document +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<noframes><body><script><!--...</script></body></noframes></html> +#errors +(1,10): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<textarea><!--<textarea></textarea>--></textarea> +#errors +(1,10): expected-doctype-but-got-start-tag +(1,49): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<textarea></textarea></textarea> +#errors +(1,10): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<iframe><!--<iframe></iframe>--></iframe> +#errors +(1,8): expected-doctype-but-got-start-tag +(1,41): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<iframe>...<!--X->...<!--/X->...</iframe> +#errors +(1,8): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<xmp><!--<xmp></xmp>--></xmp> +#errors +(1,5): expected-doctype-but-got-start-tag +(1,29): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<noembed><!--<noembed></noembed>--></noembed> +#errors +(1,9): expected-doctype-but-got-start-tag +(1,45): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<!doctype html><table> + +#errors +(2,0): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " +" + +#data +<!doctype html><table><td><span><font></span><span> +#errors +(1,26): unexpected-cell-in-table-body +(1,45): unexpected-end-tag +(1,51): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <span> +| <font> +| <font> +| <span> + +#data +<!doctype html><form><table></form><form></table></form> +#errors +(1,35): unexpected-end-tag-implies-table-voodoo +(1,35): unexpected-end-tag +(1,41): unexpected-form-in-table +(1,56): unexpected-end-tag +(1,56): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <table> +| <form> diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat new file mode 100644 index 0000000000..37a7be4187 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat @@ -0,0 +1,180 @@ +#data +<!doctype html><table><tbody><select><tr> +#errors +(1,37): unexpected-start-tag-implies-table-voodoo +(1,41): unexpected-table-element-start-tag-in-select-in-table +(1,41): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><tr><select><td> +#errors +(1,34): unexpected-start-tag-implies-table-voodoo +(1,38): unexpected-table-element-start-tag-in-select-in-table +(1,38): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<!doctype html><table><tr><td><select><td> +#errors +(1,42): unexpected-table-element-start-tag-in-select-in-table +(1,42): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <select> +| <td> + +#data +<!doctype html><table><tr><th><select><td> +#errors +(1,42): unexpected-table-element-start-tag-in-select-in-table +(1,42): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <th> +| <select> +| <td> + +#data +<!doctype html><table><caption><select><tr> +#errors +(1,43): unexpected-table-element-start-tag-in-select-in-table +(1,43): XXX-undefined-error +(1,43): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <select> +| <tbody> +| <tr> + +#data +<!doctype html><select><tr> +#errors +(1,27): unexpected-start-tag-in-select +(1,27): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><td> +#errors +(1,27): unexpected-start-tag-in-select +(1,27): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><th> +#errors +(1,27): unexpected-start-tag-in-select +(1,27): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tbody> +#errors +(1,30): unexpected-start-tag-in-select +(1,30): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><thead> +#errors +(1,30): unexpected-start-tag-in-select +(1,30): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tfoot> +#errors +(1,30): unexpected-start-tag-in-select +(1,30): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><caption> +#errors +(1,32): unexpected-start-tag-in-select +(1,32): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><table><tr></table>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| "a" diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat new file mode 100644 index 0000000000..926bccb387 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat @@ -0,0 +1,322 @@ +#data +<!doctype html><plaintext></plaintext> +#errors +(1,38): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><plaintext></plaintext> +#errors +(1,33): foster-parenting-start-tag +(1,34): foster-parenting-character +(1,35): foster-parenting-character +(1,36): foster-parenting-character +(1,37): foster-parenting-character +(1,38): foster-parenting-character +(1,39): foster-parenting-character +(1,40): foster-parenting-character +(1,41): foster-parenting-character +(1,42): foster-parenting-character +(1,43): foster-parenting-character +(1,44): foster-parenting-character +(1,45): foster-parenting-character +(1,45): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> + +#data +<!doctype html><table><tbody><plaintext></plaintext> +#errors +(1,40): foster-parenting-start-tag +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,41): foster-parenting-character +(1,52): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> + +#data +<!doctype html><table><tbody><tr><plaintext></plaintext> +#errors +(1,44): foster-parenting-start-tag +(1,45): foster-parenting-character +(1,46): foster-parenting-character +(1,47): foster-parenting-character +(1,48): foster-parenting-character +(1,49): foster-parenting-character +(1,50): foster-parenting-character +(1,51): foster-parenting-character +(1,52): foster-parenting-character +(1,53): foster-parenting-character +(1,54): foster-parenting-character +(1,55): foster-parenting-character +(1,56): foster-parenting-character +(1,56): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><plaintext></plaintext> +#errors +(1,26): unexpected-cell-in-table-body +(1,49): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><caption><plaintext></plaintext> +#errors +(1,54): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><tr><style></script></style>abc +#errors +(1,51): foster-parenting-character +(1,52): foster-parenting-character +(1,53): foster-parenting-character +(1,53): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <style> +| "</script>" + +#data +<!doctype html><table><tr><script></style></script>abc +#errors +(1,52): foster-parenting-character +(1,53): foster-parenting-character +(1,54): foster-parenting-character +(1,54): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <script> +| "</style>" + +#data +<!doctype html><table><caption><style></script></style>abc +#errors +(1,58): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><table><td><style></script></style>abc +#errors +(1,26): unexpected-cell-in-table-body +(1,53): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><select><script></style></script>abc +#errors +(1,51): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" + +#data +<!doctype html><table><select><script></style></script>abc +#errors +(1,30): unexpected-start-tag-implies-table-voodoo +(1,58): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> + +#data +<!doctype html><table><tr><select><script></style></script>abc +#errors +(1,34): unexpected-start-tag-implies-table-voodoo +(1,62): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><frameset></frameset><noframes>abc +#errors +(1,49): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><frameset></frameset></html><noframes>abc +#errors +(1,56): expected-named-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><table><tr></tbody><tfoot> +#errors +(1,41): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <tfoot> + +#data +<!doctype html><table><td><svg></svg>abc<td> +#errors +(1,26): unexpected-cell-in-table-body +(1,44): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| "abc" +| <td> diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat new file mode 100644 index 0000000000..a1897774df --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat @@ -0,0 +1,1454 @@ +#data +<!doctype html><math><mn DefinitionUrl="foo"> +#errors +(1,45): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <math mn> +| definitionURL="foo" + +#data +<!doctype html><html></p><!--foo--> +#errors +(1,25): end-tag-after-implied-root +#document +| <!DOCTYPE html> +| <html> +| <!-- foo --> +| <head> +| <body> + +#data +<!doctype html><head></head></p><!--foo--> +#errors +(1,32): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- foo --> +| <body> + +#data +<!doctype html><body><p><pre> +#errors +(1,29): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <pre> + +#data +<!doctype html><body><p><listing> +#errors +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <listing> + +#data +<!doctype html><p><plaintext> +#errors +(1,29): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <plaintext> + +#data +<!doctype html><p><h1> +#errors +(1,22): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <h1> + +#data +<!doctype html><isindex type="hidden"> +#errors +(1,38): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <isindex> +| type="hidden" + +#data +<!doctype html><ruby><p><rp> +#errors +(1,28): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rp> + +#data +<!doctype html><ruby><div><span><rp> +#errors +(1,36): XXX-undefined-error +(1,36): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rp> + +#data +<!doctype html><ruby><div><p><rp> +#errors +(1,33): XXX-undefined-error +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rp> + +#data +<!doctype html><ruby><p><rt> +#errors +(1,28): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rt> + +#data +<!doctype html><ruby><div><span><rt> +#errors +(1,36): XXX-undefined-error +(1,36): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rt> + +#data +<!doctype html><ruby><div><p><rt> +#errors +(1,33): XXX-undefined-error +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rt> + +#data +<html><ruby>a<rb>b<rt></ruby></html> +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <ruby> +| "a" +| <rb> +| "b" +| <rt> + +#data +<html><ruby>a<rp>b<rt></ruby></html> +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <ruby> +| "a" +| <rp> +| "b" +| <rt> + +#data +<html><ruby>a<rt>b<rt></ruby></html> +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <ruby> +| "a" +| <rt> +| "b" +| <rt> + +#data +<html><ruby>a<rtc>b<rt>c<rb>d</ruby></html> +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| <html> +| <head> +| <body> +| <ruby> +| "a" +| <rtc> +| "b" +| <rt> +| "c" +| <rb> +| "d" + +#data +<!doctype html><math/><foo> +#errors +(1,27): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <foo> + +#data +<!doctype html><svg/><foo> +#errors +(1,26): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| <foo> + +#data +<!doctype html><div></body><!--foo--> +#errors +(1,27): expected-one-end-tag-but-got-another +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <!-- foo --> + +#data +<!doctype html><h1><div><h3><span></h1>foo +#errors +(1,39): end-tag-too-early +(1,42): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h1> +| <div> +| <h3> +| <span> +| "foo" + +#data +<!doctype html><p></h3>foo +#errors +(1,23): end-tag-too-early +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "foo" + +#data +<!doctype html><h3><li>abc</h2>foo +#errors +(1,31): end-tag-too-early +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h3> +| <li> +| "abc" +| "foo" + +#data +<!doctype html><table>abc<!--foo--> +#errors +(1,23): foster-parenting-character +(1,24): foster-parenting-character +(1,25): foster-parenting-character +(1,35): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <!-- foo --> + +#data +<!doctype html><table> <!--foo--> +#errors +(1,34): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " " +| <!-- foo --> + +#data +<!doctype html><table> b <!--foo--> +#errors +(1,23): foster-parenting-character +(1,24): foster-parenting-character +(1,25): foster-parenting-character +(1,35): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " b " +| <table> +| <!-- foo --> + +#data +<!doctype html><select><option><option> +#errors +(1,39): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +(1,42): unexpected-end-tag-in-select +(1,42): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +(1,42): unexpected-end-tag-in-select +(1,42): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><dd><optgroup><dd> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dd> +| <optgroup> +| <dd> + +#data +<!doctype html><p><math><mi><p><h1> +#errors +(1,35): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mi> +| <p> +| <h1> + +#data +<!doctype html><p><math><mo><p><h1> +#errors +(1,35): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mo> +| <p> +| <h1> + +#data +<!doctype html><p><math><mn><p><h1> +#errors +(1,35): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <p> +| <h1> + +#data +<!doctype html><p><math><ms><p><h1> +#errors +(1,35): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math ms> +| <p> +| <h1> + +#data +<!doctype html><p><math><mtext><p><h1> +#errors +(1,38): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mtext> +| <p> +| <h1> + +#data +<!doctype html><frameset></noframes> +#errors +(1,36): unexpected-end-tag-in-frameset +(1,36): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html c=d><body></html><html a=b> +#errors +(1,48): non-html-root +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><html c=d><frameset></frameset></html><html a=b> +#errors +(1,63): non-html-root +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <!-- foo --> + +#data +<!doctype html><html><frameset></frameset></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| " " + +#data +<!doctype html><html><frameset></frameset></html>abc +#errors +(1,50): expected-eof-but-got-char +(1,51): expected-eof-but-got-char +(1,52): expected-eof-but-got-char +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><p> +#errors +(1,52): expected-eof-but-got-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html></p> +#errors +(1,53): expected-eof-but-got-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<html><frameset></frameset></html><!doctype html> +#errors +(1,6): expected-doctype-but-got-start-tag +(1,49): unexpected-doctype +#document +| <html> +| <head> +| <frameset> + +#data +<!doctype html><body><frameset> +#errors +(1,31): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!doctype html><p><frameset><frame> +#errors +(1,28): unexpected-start-tag +(1,35): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><p>a<frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "a" + +#data +<!doctype html><p> <frameset><frame> +#errors +(1,29): unexpected-start-tag +(1,36): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><pre><frameset> +#errors +(1,30): unexpected-start-tag +(1,30): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <pre> + +#data +<!doctype html><listing><frameset> +#errors +(1,34): unexpected-start-tag +(1,34): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <listing> + +#data +<!doctype html><li><frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <li> + +#data +<!doctype html><dd><frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dd> + +#data +<!doctype html><dt><frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> + +#data +<!doctype html><button><frameset> +#errors +(1,33): unexpected-start-tag +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <button> + +#data +<!doctype html><applet><frameset> +#errors +(1,33): unexpected-start-tag +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <applet> + +#data +<!doctype html><marquee><frameset> +#errors +(1,34): unexpected-start-tag +(1,34): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <marquee> + +#data +<!doctype html><object><frameset> +#errors +(1,33): unexpected-start-tag +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> + +#data +<!doctype html><table><frameset> +#errors +(1,32): unexpected-start-tag-implies-table-voodoo +(1,32): unexpected-start-tag +(1,32): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> + +#data +<!doctype html><area><frameset> +#errors +(1,31): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <area> + +#data +<!doctype html><basefont><frameset> +#errors +(1,35): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <basefont> +| <frameset> + +#data +<!doctype html><bgsound><frameset> +#errors +(1,34): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <bgsound> +| <frameset> + +#data +<!doctype html><br><frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <br> + +#data +<!doctype html><embed><frameset> +#errors +(1,32): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <embed> + +#data +<!doctype html><img><frameset> +#errors +(1,30): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html><input><frameset> +#errors +(1,32): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <input> + +#data +<!doctype html><keygen><frameset> +#errors +(1,33): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <keygen> + +#data +<!doctype html><wbr><frameset> +#errors +(1,30): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <wbr> + +#data +<!doctype html><hr><frameset> +#errors +(1,29): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <hr> + +#data +<!doctype html><textarea></textarea><frameset> +#errors +(1,46): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> + +#data +<!doctype html><xmp></xmp><frameset> +#errors +(1,36): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> + +#data +<!doctype html><iframe></iframe><frameset> +#errors +(1,42): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> + +#data +<!doctype html><select></select><frameset> +#errors +(1,42): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><svg></svg><frameset><frame> +#errors +(1,36): unexpected-start-tag +(1,43): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><math></math><frameset><frame> +#errors +(1,38): unexpected-start-tag +(1,45): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg><foreignObject><div> <frameset><frame> +#errors +(1,51): unexpected-start-tag +(1,58): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg>a</svg><frameset><frame> +#errors +(1,37): unexpected-start-tag +(1,44): unexpected-start-tag-ignored +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| "a" + +#data +<!doctype html><svg> </svg><frameset><frame> +#errors +(1,37): unexpected-start-tag +(1,44): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<html>aaa<frameset></frameset> +#errors +(1,6): expected-doctype-but-got-start-tag +(1,19): unexpected-start-tag +(1,30): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| "aaa" + +#data +<html> a <frameset></frameset> +#errors +(1,6): expected-doctype-but-got-start-tag +(1,19): unexpected-start-tag +(1,30): unexpected-end-tag +#document +| <html> +| <head> +| <body> +| "a " + +#data +<!doctype html><div><frameset> +#errors +(1,30): unexpected-start-tag +(1,30): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><div><body><frameset> +#errors +(1,26): unexpected-start-tag +(1,36): unexpected-start-tag +(1,36): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> + +#data +<!doctype html><p><math></p>a +#errors +(1,28): unexpected-end-tag +(1,28): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| "a" + +#data +<!doctype html><p><math><mn><span></p>a +#errors +(1,38): unexpected-end-tag +(1,39): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <span> +| <p> +| "a" + +#data +<!doctype html><math></html> +#errors +(1,28): unexpected-end-tag +(1,28): expected-one-end-tag-but-got-another +(1,28): unexpected-end-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> + +#data +<!doctype html><meta charset="ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| charset="ascii" +| <body> + +#data +<!doctype html><meta http-equiv="content-type" content="text/html;charset=ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| content="text/html;charset=ascii" +| http-equiv="content-type" +| <body> + +#data +<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset="utf8"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --> +| <meta> +| charset="utf8" +| <body> + +#data +<!doctype html><html a=b><head></head><html c=d> +#errors +(1,48): non-html-root +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><image/> +#errors +(1,23): image-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html>a<i>b<table>c<b>d</i>e</b>f +#errors +(1,28): foster-parenting-character +(1,31): foster-parenting-start-tag +(1,32): foster-parenting-character +(1,36): foster-parenting-end-tag +(1,36): adoption-agency-1.3 +(1,37): foster-parenting-character +(1,41): foster-parenting-end-tag +(1,42): foster-parenting-character +(1,42): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "a" +| <i> +| "bc" +| <b> +| "de" +| "f" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +(1,25): foster-parenting-start-tag +(1,26): foster-parenting-character +(1,29): foster-parenting-start-tag +(1,30): foster-parenting-character +(1,35): foster-parenting-start-tag +(1,36): foster-parenting-character +(1,39): foster-parenting-start-tag +(1,40): foster-parenting-character +(1,44): foster-parenting-end-tag +(1,44): adoption-agency-1.3 +(1,44): adoption-agency-1.3 +(1,45): foster-parenting-character +(1,49): foster-parenting-end-tag +(1,49): adoption-agency-1.3 +(1,49): adoption-agency-1.3 +(1,50): foster-parenting-character +(1,50): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f +#errors +(1,37): adoption-agency-1.3 +(1,37): adoption-agency-1.3 +(1,42): adoption-agency-1.3 +(1,42): adoption-agency-1.3 +(1,43): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" + +#data +<!doctype html><table><i>a<b>b<div>c</i> +#errors +(1,25): foster-parenting-start-tag +(1,26): foster-parenting-character +(1,29): foster-parenting-start-tag +(1,30): foster-parenting-character +(1,35): foster-parenting-start-tag +(1,36): foster-parenting-character +(1,40): foster-parenting-end-tag +(1,40): adoption-agency-1.3 +(1,40): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <i> +| "c" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +(1,25): foster-parenting-start-tag +(1,26): foster-parenting-character +(1,29): foster-parenting-start-tag +(1,30): foster-parenting-character +(1,35): foster-parenting-start-tag +(1,36): foster-parenting-character +(1,39): foster-parenting-start-tag +(1,40): foster-parenting-character +(1,44): foster-parenting-end-tag +(1,44): adoption-agency-1.3 +(1,44): adoption-agency-1.3 +(1,45): foster-parenting-character +(1,49): foster-parenting-end-tag +(1,44): adoption-agency-1.3 +(1,44): adoption-agency-1.3 +(1,50): foster-parenting-character +(1,50): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><table><i>a<div>b<tr>c<b>d</i>e +#errors +(1,25): foster-parenting-start-tag +(1,26): foster-parenting-character +(1,31): foster-parenting-start-tag +(1,32): foster-parenting-character +(1,37): foster-parenting-character +(1,40): foster-parenting-start-tag +(1,41): foster-parenting-character +(1,45): foster-parenting-end-tag +(1,45): adoption-agency-1.3 +(1,46): foster-parenting-character +(1,46): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <div> +| "b" +| <i> +| "c" +| <b> +| "d" +| <b> +| "e" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><table><i>a<div>b<b>c</i>d +#errors +(1,26): unexpected-cell-in-table-body +(1,36): foster-parenting-start-tag +(1,37): foster-parenting-character +(1,42): foster-parenting-start-tag +(1,43): foster-parenting-character +(1,46): foster-parenting-start-tag +(1,47): foster-parenting-character +(1,51): foster-parenting-end-tag +(1,51): adoption-agency-1.3 +(1,51): adoption-agency-1.3 +(1,52): foster-parenting-character +(1,52): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <i> +| "a" +| <div> +| <i> +| "b" +| <b> +| "c" +| <b> +| "d" +| <table> + +#data +<!doctype html><body><bgsound> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <bgsound> + +#data +<!doctype html><body><basefont> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <basefont> + +#data +<!doctype html><a><b></a><basefont> +#errors +(1,25): adoption-agency-1.3 +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <basefont> + +#data +<!doctype html><a><b></a><bgsound> +#errors +(1,25): adoption-agency-1.3 +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <bgsound> + +#data +<!doctype html><figcaption><article></figcaption>a +#errors +(1,49): end-tag-too-early +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <figcaption> +| <article> +| "a" + +#data +<!doctype html><summary><article></summary>a +#errors +(1,43): end-tag-too-early +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <summary> +| <article> +| "a" + +#data +<!doctype html><p><a><plaintext>b +#errors +(1,32): unexpected-end-tag +(1,33): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <a> +| <plaintext> +| <a> +| "b" + +#data +<!DOCTYPE html><div>a<a></div>b<p>c</p>d +#errors +(1,30): end-tag-too-early +(1,40): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| "a" +| <a> +| <a> +| "b" +| <p> +| "c" +| "d" diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat new file mode 100644 index 0000000000..b44fec4d76 --- /dev/null +++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat @@ -0,0 +1,821 @@ +#data +<!DOCTYPE html>Test +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "Test" + +#data +<textarea>test</div>test +#errors +(1,10): expected-doctype-but-got-start-tag +(1,24): expected-closing-tag-but-got-eof +#document +| <html> +| <head> +| <body> +| <textarea> +| "test</div>test" + +#data +<table><td> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,11): unexpected-cell-in-table-body +(1,11): expected-closing-tag-but-got-eof +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<table><td>test</tbody></table> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,11): unexpected-cell-in-table-body +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| "test" + +#data +<frame>test +#errors +(1,7): expected-doctype-but-got-start-tag +(1,7): unexpected-start-tag-ignored +#document +| <html> +| <head> +| <body> +| "test" + +#data +<!DOCTYPE html><frameset>test +#errors +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><frameset> te st +#errors +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): unexpected-char-in-frameset +(1,29): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| " " + +#data +<!DOCTYPE html><frameset></frameset> te st +#errors +(1,29): unexpected-char-after-frameset +(1,29): unexpected-char-after-frameset +(1,29): unexpected-char-after-frameset +(1,29): unexpected-char-after-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| " " + +#data +<!DOCTYPE html><frameset><!DOCTYPE html> +#errors +(1,40): unexpected-doctype +(1,40): eof-in-frameset +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><font><p><b>test</font> +#errors +(1,38): adoption-agency-1.3 +(1,38): adoption-agency-1.3 +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <p> +| <font> +| <b> +| "test" + +#data +<!DOCTYPE html><dt><div><dd> +#errors +(1,28): end-tag-too-early +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> +| <div> +| <dd> + +#data +<script></x +#errors +(1,8): expected-doctype-but-got-start-tag +(1,11): expected-named-closing-tag-but-got-eof +#document +| <html> +| <head> +| <script> +| "</x" +| <body> + +#data +<table><plaintext><td> +#errors +(1,7): expected-doctype-but-got-start-tag +(1,18): unexpected-start-tag-implies-table-voodoo +(1,22): foster-parenting-character-in-table +(1,22): foster-parenting-character-in-table +(1,22): foster-parenting-character-in-table +(1,22): foster-parenting-character-in-table +(1,22): eof-in-table +#document +| <html> +| <head> +| <body> +| <plaintext> +| "<td>" +| <table> + +#data +<plaintext></plaintext> +#errors +(1,11): expected-doctype-but-got-start-tag +(1,23): expected-closing-tag-but-got-eof +#document +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!DOCTYPE html><table><tr>TEST +#errors +(1,30): foster-parenting-character-in-table +(1,30): foster-parenting-character-in-table +(1,30): foster-parenting-character-in-table +(1,30): foster-parenting-character-in-table +(1,30): eof-in-table +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "TEST" +| <table> +| <tbody> +| <tr> + +#data +<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4> +#errors +(1,37): unexpected-start-tag +(1,53): unexpected-start-tag +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| t1="1" +| t2="2" +| t3="3" +| t4="4" + +#data +</b test +#errors +(1,8): eof-in-attribute-name +(1,8): expected-doctype-but-got-eof +#new-errors +(1:9) eof-in-tag +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html></b test<b &=&>X +#errors +(1,24): invalid-character-in-attribute-name +(1,32): named-entity-without-semicolon +(1,33): attributes-in-end-tag +(1,33): unexpected-end-tag-before-html +#new-errors +(1:24) unexpected-character-in-attribute-name +(1:33) missing-semicolon-after-character-reference +(1:33) end-tag-with-attributes +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" + +#data +<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt +#errors +(1,9): need-space-after-doctype +(1,54): expected-named-closing-tag-but-got-eof +#new-errors +(1:10) missing-whitespace-before-doctype-name +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| type="text/x-foobar;baz" +| "X</SCRipt" +| <body> + +#data +& +#errors +(1,1): expected-doctype-but-got-chars +#document +| <html> +| <head> +| <body> +| "&" + +#data +&# +#errors +(1,2): expected-numeric-entity +(1,2): expected-doctype-but-got-chars +#new-errors +(1:3) absence-of-digits-in-numeric-character-reference +#document +| <html> +| <head> +| <body> +| "&#" + +#data +&#X +#errors +(1,3): expected-numeric-entity +(1,3): expected-doctype-but-got-chars +#new-errors +(1:4) absence-of-digits-in-numeric-character-reference +#document +| <html> +| <head> +| <body> +| "&#X" + +#data +&#x +#errors +(1,3): expected-numeric-entity +(1,3): expected-doctype-but-got-chars +#new-errors +(1:4) absence-of-digits-in-numeric-character-reference +#document +| <html> +| <head> +| <body> +| "&#x" + +#data +- +#errors +(1,4): numeric-entity-without-semicolon +(1,4): expected-doctype-but-got-chars +#new-errors +(1:5) missing-semicolon-after-character-reference +#document +| <html> +| <head> +| <body> +| "-" + +#data +&x-test +#errors +(1,2): expected-doctype-but-got-chars +#document +| <html> +| <head> +| <body> +| "&x-test" + +#data +<!doctypehtml><p><li> +#errors +(1,9): need-space-after-doctype +#new-errors +(1:10) missing-whitespace-before-doctype-name +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <li> + +#data +<!doctypehtml><p><dt> +#errors +(1,9): need-space-after-doctype +#new-errors +(1:10) missing-whitespace-before-doctype-name +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dt> + +#data +<!doctypehtml><p><dd> +#errors +(1,9): need-space-after-doctype +#new-errors +(1:10) missing-whitespace-before-doctype-name +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dd> + +#data +<!doctypehtml><p><form> +#errors +(1,9): need-space-after-doctype +(1,23): expected-closing-tag-but-got-eof +#new-errors +(1:10) missing-whitespace-before-doctype-name +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <form> + +#data +<!DOCTYPE html><p></P>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "X" + +#data +& +#errors +(1,4): named-entity-without-semicolon +(1,4): expected-doctype-but-got-chars +#new-errors +(1:5) missing-semicolon-after-character-reference +#document +| <html> +| <head> +| <body> +| "&" + +#data +&AMp; +#errors +(1,3): expected-named-entity +(1,3): expected-doctype-but-got-chars +#new-errors +(1:5) unknown-named-character-reference +#document +| <html> +| <head> +| <body> +| "&AMp;" + +#data +<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY> +#errors +(1,110): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly> + +#data +<!DOCTYPE html>X</body>X +#errors +(1,24): unexpected-char-after-body +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "XX" + +#data +<!DOCTYPE html><!-- X +#errors +(1,21): eof-in-comment +#new-errors +(1:22) eof-in-comment +#document +| <!DOCTYPE html> +| <!-- X --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><table><caption>test TEST</caption><td>test +#errors +(1,54): unexpected-cell-in-table-body +(1,58): expected-closing-tag-but-got-eof +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| "test TEST" +| <tbody> +| <tr> +| <td> +| "test" + +#data +<!DOCTYPE html><select><option><optgroup> +#errors +(1,41): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option> +#errors +(1,68): unexpected-select-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <option> +| <option> + +#data +<!DOCTYPE html><select><optgroup><option><optgroup> +#errors +(1,51): eof-in-select +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><datalist><option>foo</datalist>bar +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <datalist> +| <option> +| "foo" +| "bar" + +#data +<!DOCTYPE html><font><input><input></font> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <input> +| <input> + +#data +<!DOCTYPE html><!-- XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX +#errors +(1,29): eof-in-comment +#new-errors +(1:30) eof-in-comment +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX - XXX --> +| <html> +| <head> +| <body> + +#data +test +test +#errors +(2,4): expected-doctype-but-got-chars +#document +| <html> +| <head> +| <body> +| "test +test" + +#data +<!DOCTYPE html><body><title>test</body> +#errors +#document +| +| +| +| +| +| "test</body>" + +#data +<!DOCTYPE html><body><title>X +#errors +#document +| +| +| +| +| +| "X" +| <meta> +| name="z" +| <link> +| rel="foo" +| <style> +| " +x { content:"</style" } " + +#data +<!DOCTYPE html><select><optgroup></optgroup></select> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> + +#data + + +#errors +(2,1): expected-doctype-but-got-eof +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html> <html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><script> +</script> <title>x +#errors +#document +| +| +| +| +#errors +(1,6): expected-doctype-but-got-start-tag +(1,21): unexpected-start-tag-out-of-my-head +#document +| +| +| +#errors +(1,6): expected-doctype-but-got-start-tag +(1,28): unexpected-start-tag-out-of-my-head +(1,52): unexpected-start-tag-out-of-my-head +#document +| +| +| +#errors +(1,6): expected-doctype-but-got-start-tag +#document +| +| +| +| +| "x" +| x +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +| --> x +#errors +(1,7): expected-doctype-but-got-start-tag +(1,34): unexpected-end-tag +#document +| +| +| x +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +| x +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +| x +#errors +(1,7): expected-doctype-but-got-start-tag +#document +| +| +|

    +#errors +#document +| +| +| +| +| +| ddd +#errors +(1,6): expected-doctype-but-got-start-tag +(1,21): unexpected-start-tag-out-of-my-head +#document +| +| +| +#errors +(1,3): expected-doctype-but-got-start-tag +(1,41): adoption-agency-1.3 +#document +| +| +| +| +|
  • +| +| +

    This document is in mode.

    +

    This is a test for the line height quirk which is present in limited-quirks mode and quirks mode:

    +
    hello
    hello
    +

    This is a test for the hashless hex color quirk which is present in quirks mode only:

    +
    test
    + + diff --git a/parser/htmlparser/tests/reftest/bug1636607-1.html b/parser/htmlparser/tests/reftest/bug1636607-1.html new file mode 100644 index 0000000000..af2c2cb3e8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1636607-1.html @@ -0,0 +1,18 @@ + + +

    This document is in mode.

    +

    This is a test for the line height quirk which is present in limited-quirks mode and quirks mode:

    +
    hello
    hello
    +

    This is a test for the hashless hex color quirk which is present in quirks mode only:

    +
    test
    + + diff --git a/parser/htmlparser/tests/reftest/bug1636607-2-ref.html b/parser/htmlparser/tests/reftest/bug1636607-2-ref.html new file mode 100644 index 0000000000..e82fd73824 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1636607-2-ref.html @@ -0,0 +1,17 @@ + +

    This document is in mode.

    +

    This is a test for the line height quirk which is present in limited-quirks mode and quirks mode:

    +
    hello
    hello
    +

    This is a test for the hashless hex color quirk which is present in quirks mode only:

    +
    test
    + + diff --git a/parser/htmlparser/tests/reftest/bug1636607-2.html b/parser/htmlparser/tests/reftest/bug1636607-2.html new file mode 100644 index 0000000000..f551df5ac1 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1636607-2.html @@ -0,0 +1,18 @@ + + +

    This document is in mode.

    +

    This is a test for the line height quirk which is present in limited-quirks mode and quirks mode:

    +
    hello
    hello
    +

    This is a test for the hashless hex color quirk which is present in quirks mode only:

    +
    test
    + + diff --git a/parser/htmlparser/tests/reftest/bug1650087-1-ref.html b/parser/htmlparser/tests/reftest/bug1650087-1-ref.html new file mode 100644 index 0000000000..284f097100 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1650087-1-ref.html @@ -0,0 +1,8 @@ +
    <!DOCTYPE html>
    +<template><td></template>
    +<template><tr></template>
    +<template><thead></template>
    +<template><tbody></template>
    +<template><tfoot></template>
    +<template><colgroup></template>
    +
    diff --git a/parser/htmlparser/tests/reftest/bug1650087-1.html b/parser/htmlparser/tests/reftest/bug1650087-1.html new file mode 100644 index 0000000000..c5b92f1615 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1650087-1.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug1726374-1-ref.html b/parser/htmlparser/tests/reftest/bug1726374-1-ref.html new file mode 100644 index 0000000000..1bd351963d --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1726374-1-ref.html @@ -0,0 +1,2 @@ +
    <!DOCTYPE html><!-- a <!-->b
    +
    diff --git a/parser/htmlparser/tests/reftest/bug1726374-1.html b/parser/htmlparser/tests/reftest/bug1726374-1.html new file mode 100644 index 0000000000..edcb3952c5 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1726374-1.html @@ -0,0 +1 @@ +b diff --git a/parser/htmlparser/tests/reftest/bug1749522-1-ref.txt b/parser/htmlparser/tests/reftest/bug1749522-1-ref.txt new file mode 100644 index 0000000000..c95d7230fd --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1749522-1-ref.txt @@ -0,0 +1,3 @@ + diff --git a/parser/htmlparser/tests/reftest/bug1749522-1.txt b/parser/htmlparser/tests/reftest/bug1749522-1.txt new file mode 100644 index 0000000000..3520d89838 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug1749522-1.txt @@ -0,0 +1,3 @@ + diff --git a/parser/htmlparser/tests/reftest/bug482921-1-ref.html b/parser/htmlparser/tests/reftest/bug482921-1-ref.html new file mode 100644 index 0000000000..71c0f91c08 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug482921-1-ref.html @@ -0,0 +1,27 @@ +
    <!DOCTYPE html>
    +<html>
    +<head>
    +<title>Title</title>
    +<script>
    +var lt = "<";
    +<!--
    +var s = "<script>foo</script>";
    +-->
    +</script><!-- Comment. -->
    +<style>
    +/* </foo> */
    +</style>
    +</head>
    +<body>
    +<p>Entity: &amp; </p>
    +<iframe><img></iframe>
    +<noscript><p>Not para</p></noscript>
    +<svg>
    +<title><![CDATA[bar]]></title>
    +<script><!-- this is a comment --></script>
    +</svg>
    +</body>
    +</html>
    +
    +
    + diff --git a/parser/htmlparser/tests/reftest/bug482921-1.html b/parser/htmlparser/tests/reftest/bug482921-1.html new file mode 100644 index 0000000000..ca603844f2 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug482921-1.html @@ -0,0 +1,24 @@ + + + +Title + + + + +

    Entity: &

    + + + +bar + + + + diff --git a/parser/htmlparser/tests/reftest/bug482921-2-ref.html b/parser/htmlparser/tests/reftest/bug482921-2-ref.html new file mode 100644 index 0000000000..d764c70bca --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug482921-2-ref.html @@ -0,0 +1,28 @@ +
    <?xml version="1.0" encoding="utf-8"?>
    +<?foo bar?>
    +<html>
    +<head>
    +<title>Title</title>
    +<script>
    +var s = "<script>foo</script>";
    +<!--
    +var s = "<script>foo</script>";
    +-->
    +</script>
    +<style>
    +/* <foo/> */
    +</style>
    +</head>
    +<body>
    +<p>Entity: &amp; </p>
    +<iframe><img></iframe>
    +<noscript><p>Not para</p></noscript>
    +<svg>
    +<title><![CDATA[bar]]></title>
    +<script><!-- this is a comment --></script>
    +</svg>
    +</body>
    +</html>
    +
    +
    + diff --git a/parser/htmlparser/tests/reftest/bug482921-2.xhtml b/parser/htmlparser/tests/reftest/bug482921-2.xhtml new file mode 100644 index 0000000000..4d3f0b6a73 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug482921-2.xhtml @@ -0,0 +1,25 @@ + + + + +Title +"; + + + + + +

    Entity: &

    + + + +bar + + + + diff --git a/parser/htmlparser/tests/reftest/bug535530-1-ref.html b/parser/htmlparser/tests/reftest/bug535530-1-ref.html new file mode 100644 index 0000000000..22d0dc0b0b --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug535530-1-ref.html @@ -0,0 +1,2 @@ + +XX&XX XX&nXX XX&noXX XX¬XX XX¬iXX XX¬inXX XX&;XX XX&n;XX XX&no;XX XX¬XX XX¬i;XX XX∉XX diff --git a/parser/htmlparser/tests/reftest/bug535530-1.html b/parser/htmlparser/tests/reftest/bug535530-1.html new file mode 100644 index 0000000000..63f2d8782e --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug535530-1.html @@ -0,0 +1,14 @@ + +XX&XX +XX&nXX +XX&noXX +XX¬XX +XX¬iXX +XX¬inXX +XX&;XX +XX&n;XX +XX&no;XX +XX¬XX +XX¬i;XX +XX∉XX + diff --git a/parser/htmlparser/tests/reftest/bug535530-2-ref.html b/parser/htmlparser/tests/reftest/bug535530-2-ref.html new file mode 100644 index 0000000000..174e94dc8b --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug535530-2-ref.html @@ -0,0 +1,17 @@ +
    <!DOCTYPE html>
    +XX&XX
    +XX&nXX
    +XX&noXX
    +XX&notXX
    +XX&notiXX
    +XX&notinXX
    +XX&;XX
    +XX&n;XX
    +XX&no;XX
    +XX&not;XX
    +XX&noti;XX
    +XX&notin;XX
    +
    +
    +
    + diff --git a/parser/htmlparser/tests/reftest/bug535530-2.html b/parser/htmlparser/tests/reftest/bug535530-2.html new file mode 100644 index 0000000000..63f2d8782e --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug535530-2.html @@ -0,0 +1,14 @@ + +XX&XX +XX&nXX +XX&noXX +XX¬XX +XX¬iXX +XX¬inXX +XX&;XX +XX&n;XX +XX&no;XX +XX¬XX +XX¬i;XX +XX∉XX + diff --git a/parser/htmlparser/tests/reftest/bug566280-1-ref.html b/parser/htmlparser/tests/reftest/bug566280-1-ref.html new file mode 100644 index 0000000000..6585cac38f --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug566280-1-ref.html @@ -0,0 +1,2 @@ +hello world + diff --git a/parser/htmlparser/tests/reftest/bug566280-1.html b/parser/htmlparser/tests/reftest/bug566280-1.html new file mode 100644 index 0000000000..3aa60caf34 Binary files /dev/null and b/parser/htmlparser/tests/reftest/bug566280-1.html differ diff --git a/parser/htmlparser/tests/reftest/bug569229-1-ref.xml b/parser/htmlparser/tests/reftest/bug569229-1-ref.xml new file mode 100644 index 0000000000..652f1d7da8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug569229-1-ref.xml @@ -0,0 +1,2 @@ + +

    abcd

    diff --git a/parser/htmlparser/tests/reftest/bug569229-1.xml b/parser/htmlparser/tests/reftest/bug569229-1.xml new file mode 100644 index 0000000000..2e1ff75603 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug569229-1.xml @@ -0,0 +1,6 @@ + +

    abcd

    "> + +]> +&outer; diff --git a/parser/htmlparser/tests/reftest/bug577418-1-ref.html b/parser/htmlparser/tests/reftest/bug577418-1-ref.html new file mode 100644 index 0000000000..ff773d5364 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug577418-1-ref.html @@ -0,0 +1,6 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug577418-1.html b/parser/htmlparser/tests/reftest/bug577418-1.html new file mode 100644 index 0000000000..cfd53be0a8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug577418-1.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug582788-1-ref.html b/parser/htmlparser/tests/reftest/bug582788-1-ref.html new file mode 100644 index 0000000000..c1f684807a --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug582788-1-ref.html @@ -0,0 +1,11 @@ + + + + +Not ISO-10646 + + +

    Not ISO-10646

    + + + diff --git a/parser/htmlparser/tests/reftest/bug582788-1.html b/parser/htmlparser/tests/reftest/bug582788-1.html new file mode 100644 index 0000000000..ee31b3de9d --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug582788-1.html @@ -0,0 +1,11 @@ + + + + +Not ISO-10646 + + +

    Not ISO-10646

    + + + diff --git a/parser/htmlparser/tests/reftest/bug582940-1-ref.html b/parser/htmlparser/tests/reftest/bug582940-1-ref.html new file mode 100644 index 0000000000..7209c8e69e --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug582940-1-ref.html @@ -0,0 +1,16 @@ + + + + +Fragment nav + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug582940-1.html b/parser/htmlparser/tests/reftest/bug582940-1.html new file mode 100644 index 0000000000..fd721a8bc3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug582940-1.html @@ -0,0 +1,16 @@ + + + + +Fragment nav + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug592656-1-ref.html b/parser/htmlparser/tests/reftest/bug592656-1-ref.html new file mode 100644 index 0000000000..824d815633 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug592656-1-ref.html @@ -0,0 +1,9 @@ + + + +document.write() from script-inserted inline scripts and script@onload + + +1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + + diff --git a/parser/htmlparser/tests/reftest/bug592656-1.html b/parser/htmlparser/tests/reftest/bug592656-1.html new file mode 100644 index 0000000000..769f62f648 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug592656-1.html @@ -0,0 +1,32 @@ + + + +document.write() from script-inserted inline scripts and script@onload + + +1 + + + diff --git a/parser/htmlparser/tests/reftest/bug599320-1-ref.html b/parser/htmlparser/tests/reftest/bug599320-1-ref.html new file mode 100644 index 0000000000..bb48fe5d25 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug599320-1-ref.html @@ -0,0 +1,17 @@ + + + + + +UTF-16 doc + + +

    UTF-16 doc

    + +

    Euro sign: €

    +

    iframe:

    + + + + + diff --git a/parser/htmlparser/tests/reftest/bug599320-1.html b/parser/htmlparser/tests/reftest/bug599320-1.html new file mode 100644 index 0000000000..590e9126c3 Binary files /dev/null and b/parser/htmlparser/tests/reftest/bug599320-1.html differ diff --git a/parser/htmlparser/tests/reftest/bug608373-1-ref.html b/parser/htmlparser/tests/reftest/bug608373-1-ref.html new file mode 100644 index 0000000000..69fec47d0f --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug608373-1-ref.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug608373-1.html b/parser/htmlparser/tests/reftest/bug608373-1.html new file mode 100644 index 0000000000..7bc47552f7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug608373-1.html @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-1-ref.html b/parser/htmlparser/tests/reftest/bug659763-1-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-1-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-1.html b/parser/htmlparser/tests/reftest/bug659763-1.html new file mode 100644 index 0000000000..46dbde092e --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-1.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-2-ref.html b/parser/htmlparser/tests/reftest/bug659763-2-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-2-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-2.html b/parser/htmlparser/tests/reftest/bug659763-2.html new file mode 100644 index 0000000000..c6152193aa --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-2.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-3-ref.html b/parser/htmlparser/tests/reftest/bug659763-3-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-3-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-3.html b/parser/htmlparser/tests/reftest/bug659763-3.html new file mode 100644 index 0000000000..bd2ed094bc --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-3.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-4-ref.html b/parser/htmlparser/tests/reftest/bug659763-4-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-4-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-4.html b/parser/htmlparser/tests/reftest/bug659763-4.html new file mode 100644 index 0000000000..5317186351 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-4.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-5-ref.html b/parser/htmlparser/tests/reftest/bug659763-5-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-5-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-5.html b/parser/htmlparser/tests/reftest/bug659763-5.html new file mode 100644 index 0000000000..23e9fd8e6f --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-5.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug659763-6-ref.html b/parser/htmlparser/tests/reftest/bug659763-6-ref.html new file mode 100644 index 0000000000..99429bf4e7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-6-ref.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug659763-6.html b/parser/htmlparser/tests/reftest/bug659763-6.html new file mode 100644 index 0000000000..f0a5ea8d3f --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug659763-6.html @@ -0,0 +1,9 @@ + + + diff --git a/parser/htmlparser/tests/reftest/bug673094-1-ref.html b/parser/htmlparser/tests/reftest/bug673094-1-ref.html new file mode 100644 index 0000000000..f8f8ce5939 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug673094-1-ref.html @@ -0,0 +1,9 @@ + + + +bidi in attribute + + +

    Persian فارسی

    +

    + diff --git a/parser/htmlparser/tests/reftest/bug673094-1.html b/parser/htmlparser/tests/reftest/bug673094-1.html new file mode 100644 index 0000000000..2fbdbfb10d --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug673094-1.html @@ -0,0 +1,9 @@ + + + +bidi in attribute + + +

    Persian فارسی

    +

    + diff --git a/parser/htmlparser/tests/reftest/bug696651-1-ref.html b/parser/htmlparser/tests/reftest/bug696651-1-ref.html new file mode 100644 index 0000000000..02f59b7ae6 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug696651-1-ref.html @@ -0,0 +1 @@ +CcBbAa diff --git a/parser/htmlparser/tests/reftest/bug696651-1.html b/parser/htmlparser/tests/reftest/bug696651-1.html new file mode 100644 index 0000000000..50a9135aa3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug696651-1.html @@ -0,0 +1,2 @@ + + diff --git a/parser/htmlparser/tests/reftest/bug696651-2-ref.html b/parser/htmlparser/tests/reftest/bug696651-2-ref.html new file mode 100644 index 0000000000..7999785c09 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug696651-2-ref.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/reftest/bug696651-2.html b/parser/htmlparser/tests/reftest/bug696651-2.html new file mode 100644 index 0000000000..2d3515b6af --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug696651-2.html @@ -0,0 +1,6 @@ + + + + diff --git a/parser/htmlparser/tests/reftest/bug696651-external.js b/parser/htmlparser/tests/reftest/bug696651-external.js new file mode 100644 index 0000000000..c1c2a8f788 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug696651-external.js @@ -0,0 +1 @@ +document.write("C"); document.write("c"); diff --git a/parser/htmlparser/tests/reftest/bug700260-1-ref.html b/parser/htmlparser/tests/reftest/bug700260-1-ref.html new file mode 100644 index 0000000000..0ba4495a09 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug700260-1-ref.html @@ -0,0 +1,3 @@ + 1 + 2 + 3 diff --git a/parser/htmlparser/tests/reftest/bug700260-1.html b/parser/htmlparser/tests/reftest/bug700260-1.html new file mode 100644 index 0000000000..37d3008347 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug700260-1.html @@ -0,0 +1,3 @@ + 1 + 2 + 3 diff --git a/parser/htmlparser/tests/reftest/bug704667-1-ref.html b/parser/htmlparser/tests/reftest/bug704667-1-ref.html new file mode 100644 index 0000000000..a7a939f3a4 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug704667-1-ref.html @@ -0,0 +1,4 @@ +
    <!--> <!X>
    +
    +
    + diff --git a/parser/htmlparser/tests/reftest/bug704667-1.html b/parser/htmlparser/tests/reftest/bug704667-1.html new file mode 100644 index 0000000000..553c62b309 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug704667-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/reftest/bug731234-1-ref.html b/parser/htmlparser/tests/reftest/bug731234-1-ref.html new file mode 100644 index 0000000000..897b73ea1b --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug731234-1-ref.html @@ -0,0 +1,30 @@ +
    <!DOCTYPE html>
    +<body>
    +<script></script>X
    +<script></script >X
    +<script></script
    +>X
    +<script></script foo>X
    +<script></script foo=bar>X
    +<script></script foo="bar">X
    +<script><!--</script>X
    +<script><!-- </script>X
    +<script><!-- </script >X
    +<script><!-- </script
    +>X
    +<script><!-- </script foo>X
    +<script><!-- </script foo=bar>X
    +<script><!-- </script foo="bar">X
    +<script><!-- -</script>X
    +<script><!-- --</script>X
    +<script><!-- --></script>X
    +<script><!--<script> </script> </script>X
    +<script><!--<script> </script> --></script>X
    +<script><!--<script </script> --></script>X
    +<script><!--<script> </script  > --></script>X
    +<script><!--<script> </script  foo> --></script>X
    +<script><!--<script> </script  foo=bar> --></script>X
    +<script><!--<script> </script  foo="bar"> --></script>X
    +
    +
    + diff --git a/parser/htmlparser/tests/reftest/bug731234-1.html b/parser/htmlparser/tests/reftest/bug731234-1.html new file mode 100644 index 0000000000..313e44cca7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug731234-1.html @@ -0,0 +1,27 @@ + + +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X +X diff --git a/parser/htmlparser/tests/reftest/bug820508-1-ref.html b/parser/htmlparser/tests/reftest/bug820508-1-ref.html new file mode 100644 index 0000000000..e624b16885 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug820508-1-ref.html @@ -0,0 +1,6 @@ + +main { display: block; } + +
    foo
    bar
    diff --git a/parser/htmlparser/tests/reftest/bug820508-1.html b/parser/htmlparser/tests/reftest/bug820508-1.html new file mode 100644 index 0000000000..60eabee67d --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug820508-1.html @@ -0,0 +1,6 @@ + +main { display: block; } + +
    foo
    bar
    diff --git a/parser/htmlparser/tests/reftest/bug910588-1-ref.html b/parser/htmlparser/tests/reftest/bug910588-1-ref.html new file mode 100644 index 0000000000..46133dd2c4 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug910588-1-ref.html @@ -0,0 +1,2 @@ +
    <!DOCTYPE html><table><input type=hidden></table>
    +
    diff --git a/parser/htmlparser/tests/reftest/bug910588-1.html b/parser/htmlparser/tests/reftest/bug910588-1.html new file mode 100644 index 0000000000..d0f5958582 --- /dev/null +++ b/parser/htmlparser/tests/reftest/bug910588-1.html @@ -0,0 +1 @@ +
  • diff --git a/parser/htmlparser/tests/reftest/document-write-ref.html b/parser/htmlparser/tests/reftest/document-write-ref.html new file mode 100644 index 0000000000..9902cf77d1 --- /dev/null +++ b/parser/htmlparser/tests/reftest/document-write-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta from document.write (with concatenation in the middle of charset to require execution for effect).

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/document-write.html b/parser/htmlparser/tests/reftest/document-write.html new file mode 100644 index 0000000000..b70a15c567 --- /dev/null +++ b/parser/htmlparser/tests/reftest/document-write.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta from document.write (with concatenation in the middle of charset to require execution for effect).

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/frame582940-ref.html b/parser/htmlparser/tests/reftest/frame582940-ref.html new file mode 100644 index 0000000000..ac665679b5 --- /dev/null +++ b/parser/htmlparser/tests/reftest/frame582940-ref.html @@ -0,0 +1,51 @@ + + + + +Fragment nav + + +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Ref!

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    + + + diff --git a/parser/htmlparser/tests/reftest/frame582940.html b/parser/htmlparser/tests/reftest/frame582940.html new file mode 100644 index 0000000000..646b7d5a71 --- /dev/null +++ b/parser/htmlparser/tests/reftest/frame582940.html @@ -0,0 +1,51 @@ + + + + +Fragment nav + + +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Ref!

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    +

    Filler

    + + + diff --git a/parser/htmlparser/tests/reftest/frame599320-1-ref.html b/parser/htmlparser/tests/reftest/frame599320-1-ref.html new file mode 100644 index 0000000000..735c368f8b --- /dev/null +++ b/parser/htmlparser/tests/reftest/frame599320-1-ref.html @@ -0,0 +1,15 @@ + + + + + +Non-UTF-16 doc + + +

    Non-UTF-16 doc

    + +

    Euro sign: €

    + + + + diff --git a/parser/htmlparser/tests/reftest/frame599320-1.html b/parser/htmlparser/tests/reftest/frame599320-1.html new file mode 100644 index 0000000000..145ee94ba8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/frame599320-1.html @@ -0,0 +1,1092 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Non-UTF-16 doc + + +

    Non-UTF-16 doc

    + +

    Euro sign: €

    + + + + diff --git a/parser/htmlparser/tests/reftest/in-comment-ref.html b/parser/htmlparser/tests/reftest/in-comment-ref.html new file mode 100644 index 0000000000..94b2016e0d --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-comment-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta inside comment.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-comment.html b/parser/htmlparser/tests/reftest/in-comment.html new file mode 100644 index 0000000000..65828a1872 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-comment.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta inside comment.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb-ref.html b/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb-ref.html new file mode 100644 index 0000000000..12e9b93626 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in noscript after template (which is also inside the noscript) after 1kb of padding following the template.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb.html b/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb.html new file mode 100644 index 0000000000..d22e83aaa7 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-after-template-after-1kb.html @@ -0,0 +1,894 @@ + + + + + + +

    Meta in noscript after template (which is also inside the noscript) after 1kb of padding following the template.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-after-template-ref.html b/parser/htmlparser/tests/reftest/in-noscript-after-template-ref.html new file mode 100644 index 0000000000..27defe54c0 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-after-template-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in noscript after template (which is also inside the noscript).

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-after-template.html b/parser/htmlparser/tests/reftest/in-noscript-after-template.html new file mode 100644 index 0000000000..71ef9144e0 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-after-template.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in noscript after template (which is also inside the noscript).

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-ncr-ref.html b/parser/htmlparser/tests/reftest/in-noscript-ncr-ref.html new file mode 100644 index 0000000000..3581ab68db --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-ncr-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta with NCR in the encoding label in noscript.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-ncr.html b/parser/htmlparser/tests/reftest/in-noscript-ncr.html new file mode 100644 index 0000000000..645f151b26 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-ncr.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta with NCR in the encoding label in noscript.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript-ref.html b/parser/htmlparser/tests/reftest/in-noscript-ref.html new file mode 100644 index 0000000000..9bb9f24b88 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in noscript.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-noscript.html b/parser/htmlparser/tests/reftest/in-noscript.html new file mode 100644 index 0000000000..e76054d618 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-noscript.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in noscript.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-object-ref.html b/parser/htmlparser/tests/reftest/in-object-ref.html new file mode 100644 index 0000000000..3f52d0efe9 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-object-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in object.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-object.html b/parser/htmlparser/tests/reftest/in-object.html new file mode 100644 index 0000000000..32535b8eba --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-object.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in object.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-script-ref.html b/parser/htmlparser/tests/reftest/in-script-ref.html new file mode 100644 index 0000000000..bbb63fd931 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-script-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in script.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-script.html b/parser/htmlparser/tests/reftest/in-script.html new file mode 100644 index 0000000000..0c18a4435e --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-script.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in script.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-style-ref.html b/parser/htmlparser/tests/reftest/in-style-ref.html new file mode 100644 index 0000000000..9669146eb5 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-style-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in style.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-style.html b/parser/htmlparser/tests/reftest/in-style.html new file mode 100644 index 0000000000..69d8fa429c --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-style.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in style.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt-ref.html b/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt-ref.html new file mode 100644 index 0000000000..2868f47fc2 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt-ref.html @@ -0,0 +1,10 @@ + + + + + + +

    In SVG in CDATA after greater-than sign in the CDATA (after head).

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt.html b/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt.html new file mode 100644 index 0000000000..56783b7afc --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg-in-cdata-after-gt.html @@ -0,0 +1,10 @@ + + + + + +><meta charset="windows-1251"> +

    In SVG in CDATA after greater-than sign in the CDATA (after head).

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg-in-cdata-ref.html b/parser/htmlparser/tests/reftest/in-svg-in-cdata-ref.html new file mode 100644 index 0000000000..1d17d2720b --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg-in-cdata-ref.html @@ -0,0 +1,10 @@ + + + + + + +

    In SVG in CDATA (after head).

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg-in-cdata.html b/parser/htmlparser/tests/reftest/in-svg-in-cdata.html new file mode 100644 index 0000000000..d1c4ca12b3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg-in-cdata.html @@ -0,0 +1,10 @@ + + + + + +<meta charset="windows-1251"> +

    In SVG in CDATA (after head).

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg-ref.html b/parser/htmlparser/tests/reftest/in-svg-ref.html new file mode 100644 index 0000000000..c9e41aa177 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg-ref.html @@ -0,0 +1,10 @@ + + + + + + +

    In SVG (after head).

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-svg.html b/parser/htmlparser/tests/reftest/in-svg.html new file mode 100644 index 0000000000..cb29164289 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-svg.html @@ -0,0 +1,10 @@ + + + + + +
    +

    In SVG (after head).

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-template-after-1kb-ref.html b/parser/htmlparser/tests/reftest/in-template-after-1kb-ref.html new file mode 100644 index 0000000000..df20eba39b --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-template-after-1kb-ref.html @@ -0,0 +1,8 @@ + + + + +

    In template, before head end tag, after first kilobyte.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-template-after-1kb.html b/parser/htmlparser/tests/reftest/in-template-after-1kb.html new file mode 100644 index 0000000000..ae77decea2 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-template-after-1kb.html @@ -0,0 +1,1046 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    In template, before head end tag, after first kilobyte.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-template-ref.html b/parser/htmlparser/tests/reftest/in-template-ref.html new file mode 100644 index 0000000000..83c0e93072 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-template-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Meta in template.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-template.html b/parser/htmlparser/tests/reftest/in-template.html new file mode 100644 index 0000000000..264affc269 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-template.html @@ -0,0 +1,10 @@ + + + + + + +

    Meta in template.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-title-ref.html b/parser/htmlparser/tests/reftest/in-title-ref.html new file mode 100644 index 0000000000..5fb8a05f2d --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-title-ref.html @@ -0,0 +1,10 @@ + + + +<meta charset="windows-1251"> + + +

    Meta in title.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/in-title.html b/parser/htmlparser/tests/reftest/in-title.html new file mode 100644 index 0000000000..7b72c48dd8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/in-title.html @@ -0,0 +1,10 @@ + + + +<meta charset="windows-1251"> + + +

    Meta in title.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/incomplete-xml-decl-ref.html b/parser/htmlparser/tests/reftest/incomplete-xml-decl-ref.html new file mode 100644 index 0000000000..201fe664d5 --- /dev/null +++ b/parser/htmlparser/tests/reftest/incomplete-xml-decl-ref.html @@ -0,0 +1,2 @@ +incomplete-xml-decl.xml
    <?xml 
    +
    diff --git a/parser/htmlparser/tests/reftest/incomplete-xml-decl.xml b/parser/htmlparser/tests/reftest/incomplete-xml-decl.xml new file mode 100644 index 0000000000..1b345b6c84 --- /dev/null +++ b/parser/htmlparser/tests/reftest/incomplete-xml-decl.xml @@ -0,0 +1 @@ + + + + + +

    NCR in encoding label.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/ncr.html b/parser/htmlparser/tests/reftest/ncr.html new file mode 100644 index 0000000000..9f8b7308ad --- /dev/null +++ b/parser/htmlparser/tests/reftest/ncr.html @@ -0,0 +1,10 @@ + + + + + + +

    NCR in encoding label.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/non-ascii-in-comment-before-ref.html b/parser/htmlparser/tests/reftest/non-ascii-in-comment-before-ref.html new file mode 100644 index 0000000000..bd2acd274c --- /dev/null +++ b/parser/htmlparser/tests/reftest/non-ascii-in-comment-before-ref.html @@ -0,0 +1,9 @@ + + + + + +

    Normal meta. Non-ASCII in comment before.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/non-ascii-in-comment-before.html b/parser/htmlparser/tests/reftest/non-ascii-in-comment-before.html new file mode 100644 index 0000000000..148c6544a3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/non-ascii-in-comment-before.html @@ -0,0 +1,11 @@ + + + + + + + +

    Normal meta. Non-ASCII in comment before.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/non-ascii-in-title-before-ref.html b/parser/htmlparser/tests/reftest/non-ascii-in-title-before-ref.html new file mode 100644 index 0000000000..4f54732432 --- /dev/null +++ b/parser/htmlparser/tests/reftest/non-ascii-in-title-before-ref.html @@ -0,0 +1,10 @@ + + + +ж + + +

    Normal meta. Non-ASCII in title before.

    +

    Test: ж

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/non-ascii-in-title-before.html b/parser/htmlparser/tests/reftest/non-ascii-in-title-before.html new file mode 100644 index 0000000000..aac0ca94c1 --- /dev/null +++ b/parser/htmlparser/tests/reftest/non-ascii-in-title-before.html @@ -0,0 +1,11 @@ + + + + + + + +

    Normal meta. Non-ASCII in title before.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/reftest.list b/parser/htmlparser/tests/reftest/reftest.list new file mode 100644 index 0000000000..6607a6112c --- /dev/null +++ b/parser/htmlparser/tests/reftest/reftest.list @@ -0,0 +1,73 @@ +== bug535530-1.html bug535530-1-ref.html +== view-source:bug535530-2.html bug535530-2-ref.html +== bug566280-1.html bug566280-1-ref.html +== bug569229-1.xml bug569229-1-ref.xml +== bug577418-1.html bug577418-1-ref.html +== bug582788-1.html bug582788-1-ref.html +fuzzy(0-2,0-5) skip-if(OSX) == bug582940-1.html bug582940-1-ref.html +== bug592656-1.html bug592656-1-ref.html +fuzzy(0-1,0-5) == bug599320-1.html bug599320-1-ref.html +fuzzy(0-2,0-5) == bug608373-1.html bug608373-1-ref.html +== view-source:bug482921-1.html bug482921-1-ref.html +== view-source:bug482921-2.xhtml bug482921-2-ref.html +fuzzy(0-2,0-5) == bug659763-1.html bug659763-1-ref.html +fuzzy(0-1,0-5) == bug659763-2.html bug659763-2-ref.html +fuzzy(0-1,0-5) == bug659763-3.html bug659763-3-ref.html +fuzzy(0-2,0-3) == bug659763-4.html bug659763-4-ref.html +fuzzy(0-1,0-5) == bug659763-5.html bug659763-5-ref.html +fuzzy(0-1,0-5) == bug659763-6.html bug659763-6-ref.html +== view-source:bug673094-1.html view-source:bug673094-1-ref.html +== bug696651-1.html bug696651-1-ref.html +== bug696651-2.html bug696651-2-ref.html +== view-source:bug700260-1.html view-source:bug700260-1-ref.html +== view-source:bug704667-1.html bug704667-1-ref.html +== view-source:bug731234-1.html bug731234-1-ref.html +== bug820508-1.html bug820508-1-ref.html +== view-source:bug910588-1.html bug910588-1-ref.html +== bug1636607-1.html bug1636607-1-ref.html +== bug1636607-2.html bug1636607-2-ref.html +== view-source:bug1319410-1.html bug1319410-1-ref.html +== view-source:bug1650087-1.html bug1650087-1-ref.html +== view-source:bug1726374-1.html bug1726374-1-ref.html +== view-source:bug1153920-1.html bug1153920-1-ref.html +== after-1kb.html after-1kb-ref.html +!= after-bogus-after-1kb.html after-bogus-after-1kb-ref.html +== after-bogus.html after-bogus-ref.html +!= after-head-after-1kb-crlf.html after-head-after-1kb-crlf-ref.html +!= after-head-after-1kb.html after-head-after-1kb-ref.html +== after-head-in-1kb-crlf.html after-head-in-1kb-crlf-ref.html +== after-head-in-1kb.html after-head-in-1kb-ref.html +== baseline.html baseline-ref.html +!= document-write.html document-write-ref.html +!= in-comment.html in-comment-ref.html +!= in-noscript-after-template-after-1kb.html in-noscript-after-template-after-1kb-ref.html +!= in-noscript-after-template.html in-noscript-after-template-ref.html +!= in-noscript.html in-noscript-ref.html +!= in-noscript-ncr.html in-noscript-ncr-ref.html +== in-object.html in-object-ref.html +!= in-script.html in-script-ref.html +!= in-style.html in-style-ref.html +== in-svg.html in-svg-ref.html +!= in-svg-in-cdata-after-gt.html in-svg-in-cdata-after-gt-ref.html +!= in-svg-in-cdata.html in-svg-in-cdata-ref.html +!= in-template-after-1kb.html in-template-after-1kb-ref.html +== in-template.html in-template-ref.html +!= in-title.html in-title-ref.html +== ncr.html ncr-ref.html +== non-ascii-in-comment-before.html non-ascii-in-comment-before-ref.html +== non-ascii-in-title-before.html non-ascii-in-title-before-ref.html +== view-source:xml-1.xml xml-ref.html +HTTP(..) == view-source:xml-trickle-1.sjs xml-ref.html +HTTP(..) == view-source:xml-trickle-2.sjs xml-ref.html +HTTP(..) == view-source:xml-trickle-3.sjs xml-ref.html +HTTP(..) == view-source:xml-trickle-4.sjs xml-utf-ref.html +HTTP(..) == view-source:xml-trickle-5.sjs xml-utf-ref.html +HTTP(..) == view-source:xml-trickle-6.sjs xml-utf-ref.html +skip-if(Android) HTTP(..) == view-source:vs-after-head-in-1kb.html vs-after-head-in-1kb-ref.html # Skipped on Android due to inconsistent scrollbar display +HTTP(..) != view-source:vs-after-head-after-1kb.html vs-after-head-after-1kb-ref.html +HTTP(..) == view-source:vs-non-ascii-in-comment-before.html vs-non-ascii-in-comment-before-ref.html +HTTP(..) == view-source:vs-non-ascii-in-comment-before.sjs vs-non-ascii-in-comment-before-ref.html +== view-source:xml-without-tags.xml xml-without-tags-ref.html +== view-source:incomplete-xml-decl.xml incomplete-xml-decl-ref.html +== view-source:view-source-bom.html view-source-bom-ref.html +skip-if(Android) == bug1749522-1.txt bug1749522-1-ref.txt # Skipped on Android due to suspicion of harness bug diff --git a/parser/htmlparser/tests/reftest/view-source-bom-ref.html b/parser/htmlparser/tests/reftest/view-source-bom-ref.html new file mode 100644 index 0000000000..0ed26be850 --- /dev/null +++ b/parser/htmlparser/tests/reftest/view-source-bom-ref.html @@ -0,0 +1,10 @@ +view-source-bom.html
    <!DOCTYPE html>
    +<html>
    +<head>
    +    <title>UTF-8 file with a BOM</title>
    +</head>
    +<body>
    +<p>UTF-8 file with a BOM. Euro sign: €</p>
    +</body>
    +</html>
    +
    diff --git a/parser/htmlparser/tests/reftest/view-source-bom.html b/parser/htmlparser/tests/reftest/view-source-bom.html new file mode 100644 index 0000000000..d10d94fbee --- /dev/null +++ b/parser/htmlparser/tests/reftest/view-source-bom.html @@ -0,0 +1,9 @@ + + + + UTF-8 file with a BOM + + +

    UTF-8 file with a BOM. Euro sign: €

    + + diff --git a/parser/htmlparser/tests/reftest/vs-after-head-after-1kb-ref.html b/parser/htmlparser/tests/reftest/vs-after-head-after-1kb-ref.html new file mode 100644 index 0000000000..5a721755b1 --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-after-head-after-1kb-ref.html @@ -0,0 +1,11 @@ +vs-after-head-after-1kb.html
    <!DOCTYPE html>
    +<head>
    +<link rel="mismatch" href="references/after-head-after-1kb-ref.html">
    +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           </head>
    +<meta charset="windows-1251">
    +<body>
    +<p>After <code>head</code>, before <code>body</code>, after first kilobyte.</p>
    +<p>Test: ж</p>
    +<p>If &#x0436;, meta takes effect</p>
    +</body>
    +
    diff --git a/parser/htmlparser/tests/reftest/vs-after-head-after-1kb.html b/parser/htmlparser/tests/reftest/vs-after-head-after-1kb.html new file mode 100644 index 0000000000..6637a2a8c5 --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-after-head-after-1kb.html @@ -0,0 +1,10 @@ + + + + + + +

    After head, before body, after first kilobyte.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/vs-after-head-in-1kb-ref.html b/parser/htmlparser/tests/reftest/vs-after-head-in-1kb-ref.html new file mode 100644 index 0000000000..706c20da6e --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-after-head-in-1kb-ref.html @@ -0,0 +1,12 @@ +vs-after-head-in-1kb.html
    <!DOCTYPE html>
    +<head>
    +<link rel="match" href="references/after-head-in-1kb-ref.html">
    +</head>
    +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
    +<meta charset="windows-1251">
    +<body>
    +<p>After <code>head</code>, before <code>body</code>, within first kilobyte.</p>
    +<p>Test: ж</p>
    +<p>If &#x0436;, meta takes effect</p>
    +</body>
    +
    diff --git a/parser/htmlparser/tests/reftest/vs-after-head-in-1kb.html b/parser/htmlparser/tests/reftest/vs-after-head-in-1kb.html new file mode 100644 index 0000000000..af63f06acb --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-after-head-in-1kb.html @@ -0,0 +1,11 @@ + + + + + + + +

    After head, before body, within first kilobyte.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before-ref.html b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before-ref.html new file mode 100644 index 0000000000..66f0338658 --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before-ref.html @@ -0,0 +1,12 @@ +vs-non-ascii-in-comment-before.html
    <!DOCTYPE html>
    +<head>
    +<link rel="match" href="references/non-ascii-in-comment-before-ref.html">
    +<!-- ж -->
    +<meta charset="windows-1251">
    +</head>
    +<body>
    +<p>Normal meta. Non-ASCII in comment before.</p>
    +<p>Test: ж</p>
    +<p>If &#x0436;, meta takes effect</p>
    +</body>
    +
    diff --git a/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.html b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.html new file mode 100644 index 0000000000..148c6544a3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.html @@ -0,0 +1,11 @@ + + + + + + + +

    Normal meta. Non-ASCII in comment before.

    +

    Test:

    +

    If ж, meta takes effect

    + diff --git a/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.sjs b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.sjs new file mode 100644 index 0000000000..12b1919ff8 --- /dev/null +++ b/parser/htmlparser/tests/reftest/vs-non-ascii-in-comment-before.sjs @@ -0,0 +1,16 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.write('\n\n\n\n'); + response.bodyOutputStream.flush(); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.write('\n\n\n

    Normal meta. Non-ASCII in comment before.

    \n

    Test: \u00E6

    \n

    If ж, meta takes effect

    \n\n'); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/parser/htmlparser/tests/reftest/xml-1.xml b/parser/htmlparser/tests/reftest/xml-1.xml new file mode 100644 index 0000000000..a6ac350ad3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-1.xml @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/reftest/xml-ref.html b/parser/htmlparser/tests/reftest/xml-ref.html new file mode 100644 index 0000000000..3bf58fb763 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-ref.html @@ -0,0 +1,2 @@ +
    <?xml version='1.0' encoding='windows-1251'?><root>ж</root>
    +
    diff --git a/parser/htmlparser/tests/reftest/xml-trickle-1.sjs b/parser/htmlparser/tests/reftest/xml-trickle-1.sjs new file mode 100644 index 0000000000..eaec0e37fc --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-1.sjs @@ -0,0 +1,17 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("<"); + response.bodyOutputStream.flush(); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.write("?xml version='1.0' encoding='windows-1251'?>\u00E6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-trickle-2.sjs b/parser/htmlparser/tests/reftest/xml-trickle-2.sjs new file mode 100644 index 0000000000..04c1354fa3 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-2.sjs @@ -0,0 +1,17 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("\u00E6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-trickle-3.sjs b/parser/htmlparser/tests/reftest/xml-trickle-3.sjs new file mode 100644 index 0000000000..e601f69038 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-3.sjs @@ -0,0 +1,21 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("\u00E6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-trickle-4.sjs b/parser/htmlparser/tests/reftest/xml-trickle-4.sjs new file mode 100644 index 0000000000..0ac01d84da --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-4.sjs @@ -0,0 +1,17 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("<"); + response.bodyOutputStream.flush(); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.write("?xml version='1.0'?>\u00D0\u00B6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-trickle-5.sjs b/parser/htmlparser/tests/reftest/xml-trickle-5.sjs new file mode 100644 index 0000000000..815295ac30 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-5.sjs @@ -0,0 +1,17 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("\u00D0\u00B6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-trickle-6.sjs b/parser/htmlparser/tests/reftest/xml-trickle-6.sjs new file mode 100644 index 0000000000..9e96687d19 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-trickle-6.sjs @@ -0,0 +1,21 @@ +var timer; // Place timer in global scope to avoid it getting GC'ed prematurely + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("\u00D0\u00B6\n"); + response.finish(); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + }, 10, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} + diff --git a/parser/htmlparser/tests/reftest/xml-utf-ref.html b/parser/htmlparser/tests/reftest/xml-utf-ref.html new file mode 100644 index 0000000000..98a3100b24 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-utf-ref.html @@ -0,0 +1,2 @@ +
    <?xml version='1.0'?><root>ж</root>
    +
    diff --git a/parser/htmlparser/tests/reftest/xml-without-tags-ref.html b/parser/htmlparser/tests/reftest/xml-without-tags-ref.html new file mode 100644 index 0000000000..d853e67634 --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-without-tags-ref.html @@ -0,0 +1,2 @@ +xml-without-tags.xml
    ill-formed
    +
    diff --git a/parser/htmlparser/tests/reftest/xml-without-tags.xml b/parser/htmlparser/tests/reftest/xml-without-tags.xml new file mode 100644 index 0000000000..ddc2f2135d --- /dev/null +++ b/parser/htmlparser/tests/reftest/xml-without-tags.xml @@ -0,0 +1 @@ +ill-formed -- cgit v1.2.3