// Copyright 2018 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "xfa/fxfa/parser/cxfa_document_builder.h" #include #include "core/fxcrt/cfx_read_only_span_stream.h" #include "core/fxcrt/xml/cfx_xmldocument.h" #include "core/fxcrt/xml/cfx_xmlparser.h" #include "testing/fxgc_unittest.h" #include "testing/gtest/include/gtest/gtest.h" #include "v8/include/cppgc/allocation.h" #include "v8/include/cppgc/persistent.h" #include "xfa/fxfa/parser/cxfa_document.h" class CXFA_DocumentBuilderTest : public FXGCUnitTest { public: void SetUp() override { FXGCUnitTest::SetUp(); doc_ = cppgc::MakeGarbageCollected( heap()->GetAllocationHandle(), nullptr, heap(), nullptr); } void TearDown() override { doc_ = nullptr; FXGCUnitTest::TearDown(); } CXFA_Document* GetDoc() const { return doc_; } CXFA_Node* ParseAndBuild(const RetainPtr& stream) { xml_ = CFX_XMLParser(stream).Parse(); if (!xml_) return nullptr; CXFA_DocumentBuilder builder(doc_); if (!builder.BuildDocument(xml_.get(), XFA_PacketType::Config)) return nullptr; return builder.GetRootNode(); } private: std::unique_ptr xml_; cppgc::Persistent doc_; }; TEST_F(CXFA_DocumentBuilderTest, EmptyInput) { static const char kInput[] = ""; auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); EXPECT_FALSE(ParseAndBuild(stream)); } TEST_F(CXFA_DocumentBuilderTest, BadInput) { static const char kInput[] = "<<<>bar?>>>>>>>"; auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); EXPECT_FALSE(ParseAndBuild(stream)); } TEST_F(CXFA_DocumentBuilderTest, XMLInstructionsScriptOff) { static const char kInput[] = "\n" "\n" ""; EXPECT_FALSE(GetDoc()->is_scripting()); auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); CXFA_Node* root = ParseAndBuild(stream); ASSERT_TRUE(root); EXPECT_FALSE(GetDoc()->is_scripting()); } TEST_F(CXFA_DocumentBuilderTest, XMLInstructionsScriptOn) { static const char kInput[] = "\n" "\n" ""; EXPECT_FALSE(GetDoc()->is_scripting()); auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); CXFA_Node* root = ParseAndBuild(stream); ASSERT_TRUE(root); EXPECT_TRUE(GetDoc()->is_scripting()); } TEST_F(CXFA_DocumentBuilderTest, XMLInstructionsStrictScope) { static const char kInput[] = "" "\n" ""; EXPECT_FALSE(GetDoc()->is_strict_scoping()); auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); CXFA_Node* root = ParseAndBuild(stream); ASSERT_TRUE(root); EXPECT_TRUE(GetDoc()->is_strict_scoping()); } TEST_F(CXFA_DocumentBuilderTest, XMLInstructionsStrictScopeBad) { static const char kInput[] = "" "\n" ""; EXPECT_FALSE(GetDoc()->is_strict_scoping()); auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); CXFA_Node* root = ParseAndBuild(stream); ASSERT_TRUE(root); EXPECT_FALSE(GetDoc()->is_strict_scoping()); } TEST_F(CXFA_DocumentBuilderTest, MultipleXMLInstructions) { static const char kInput[] = "" "\n" "\n" ""; EXPECT_FALSE(GetDoc()->is_scripting()); EXPECT_FALSE(GetDoc()->is_strict_scoping()); auto stream = pdfium::MakeRetain( pdfium::as_bytes(pdfium::make_span(kInput))); CXFA_Node* root = ParseAndBuild(stream); ASSERT_TRUE(root); EXPECT_TRUE(GetDoc()->is_scripting()); EXPECT_TRUE(GetDoc()->is_strict_scoping()); }