/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/dom_parser/xml_decoder.h"

#include "base/callback.h"
#include "cobalt/dom/attr.h"
#include "cobalt/dom/cdata_section.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/named_node_map.h"
#include "cobalt/dom/text.h"
#include "cobalt/dom/xml_document.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace dom_parser {

const int kDOMMaxElementDepth = 32;

class MockErrorCallback : public base::Callback<void(const std::string&)> {
 public:
  MOCK_METHOD1(Run, void(const std::string&));
};

class XMLDecoderTest : public ::testing::Test {
 protected:
  XMLDecoderTest();
  ~XMLDecoderTest() OVERRIDE {}

  dom::HTMLElementContext html_element_context_;
  scoped_refptr<dom::XMLDocument> document_;
  base::SourceLocation source_location_;
  MockErrorCallback mock_error_callback_;
  scoped_ptr<XMLDecoder> xml_decoder_;
};

XMLDecoderTest::XMLDecoderTest()
    : html_element_context_(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                            NULL, NULL, NULL, NULL, ""),
      document_(new dom::XMLDocument(&html_element_context_)),
      source_location_(base::SourceLocation("[object XMLDecoderTest]", 1, 1)) {}

TEST_F(XMLDecoderTest, ShouldNotAddImpliedTags) {
  const std::string input = "<ELEMENT></ELEMENT>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("ELEMENT", element->tag_name());
  EXPECT_FALSE(element->HasChildNodes());
}

TEST_F(XMLDecoderTest, CanParseCDATASection) {
  // Libxml requires that a CDATA must be inside an element.
  const std::string input =
      "<ELEMENT>"
      "<![CDATA["
      "<tag> <!--comment--> <![CDATA[ & &amp; ]]&gt;"
      "]]>"
      "<![CDATA["
      "another CDATA section"
      "]]>"
      "</ELEMENT>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("ELEMENT", element->tag_name());

  dom::CDATASection* cdata_section1 = element->first_child()->AsCDATASection();
  ASSERT_TRUE(cdata_section1);
  EXPECT_EQ("<tag> <!--comment--> <![CDATA[ & &amp; ]]&gt;",
            cdata_section1->data());

  dom::CDATASection* cdata_section2 = element->last_child()->AsCDATASection();
  ASSERT_TRUE(cdata_section2);
  EXPECT_EQ("another CDATA section", cdata_section2->data());
}

TEST_F(XMLDecoderTest, CanParseAttributesWithValue) {
  const std::string input = "<ELEMENT a=\"1\" b=\"2\"></ELEMENT>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("ELEMENT", element->tag_name());
  EXPECT_TRUE(element->HasAttributes());
  EXPECT_EQ(2, element->attributes()->length());
  EXPECT_EQ("a", element->attributes()->Item(0)->name());
  EXPECT_EQ("1", element->attributes()->Item(0)->value());
  EXPECT_EQ("b", element->attributes()->Item(1)->name());
  EXPECT_EQ("2", element->attributes()->Item(1)->value());
}

TEST_F(XMLDecoderTest, TagNamesShouldBeCaseSensitive) {
  const std::string input = "<ELEMENT><element></element></ELEMENT>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("ELEMENT", element->tag_name());

  element = element->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, AttributesShouldBeCaseSensitive) {
  const std::string input = "<ELEMENT A=\"1\" a=\"2\"></ELEMENT>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("ELEMENT", element->tag_name());
  EXPECT_TRUE(element->HasAttributes());
  EXPECT_EQ(2, element->attributes()->length());
  EXPECT_EQ("A", element->attributes()->Item(0)->name());
  EXPECT_EQ("1", element->attributes()->Item(0)->value());
  EXPECT_EQ("a", element->attributes()->Item(1)->name());
  EXPECT_EQ("2", element->attributes()->Item(1)->value());
}

TEST_F(XMLDecoderTest, CanDealWithFileAttack) {
  const std::string input =
      "<!DOCTYPE doc [ <!ENTITY ent SYSTEM \"file:///dev/tty\"> ]>"
      "<element>&ent;</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithHTMLAttack) {
  const std::string input =
      "<!DOCTYPE doc [ <!ENTITY ent SYSTEM \"file:///dev/tty\"> ]>"
      "<element>&ent;</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithAttack) {
  const std::string input =
      "<!DOCTYPE doc [ <!ENTITY % ent SYSTEM \"http://www.google.com/\"> ]>"
      "<element>&ent;</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithPEAttack) {
  const std::string input =
      "<!DOCTYPE doc [ <!ENTITY % ent SYSTEM \"file:///dev/tty\"> ]>"
      "<element>hey</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithDTDAttack) {
  const std::string input =
      "<!DOCTYPE doc SYSTEM \"file:///dev/tty\">"
      "<element>hey</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithLaughsAttack) {
  const std::string input =
      "<!DOCTYPE doc ["
      "<!ENTITY ha \"Ha !\">"
      "<!ENTITY ha2 \"&ha; &ha; &ha; &ha; &ha;\">"
      "<!ENTITY ha3 \"&ha2; &ha2; &ha2; &ha2; &ha2;\">"
      "<!ENTITY ha4 \"&ha3; &ha3; &ha3; &ha3; &ha3;\">"
      "<!ENTITY ha5 \"&ha4; &ha4; &ha4; &ha4; &ha4;\">"
      "<!ENTITY ha6 \"&ha5; &ha5; &ha5; &ha5; &ha5;\">"
      "<!ENTITY ha7 \"&ha6; &ha6; &ha6; &ha6; &ha6;\">"
      "<!ENTITY ha8 \"&ha7; &ha7; &ha7; &ha7; &ha7;\">"
      "<!ENTITY ha9 \"&ha8; &ha8; &ha8; &ha8; &ha8;\">"
      "<!ENTITY ha10 \"&ha9; &ha9; &ha9; &ha9; &ha9;\">"
      "<!ENTITY ha11 \"&ha10; &ha10; &ha10; &ha10; &ha10;\">"
      "<!ENTITY ha12 \"&ha11; &ha11; &ha11; &ha11; &ha11;\">"
      "<!ENTITY ha13 \"&ha12; &ha12; &ha12; &ha12; &ha12;\">"
      "<!ENTITY ha14 \"&ha13; &ha13; &ha13; &ha13; &ha13;\">"
      "<!ENTITY ha15 \"&ha14; &ha14; &ha14; &ha14; &ha14;\">"
      "]>"
      "<element>&ha15;</element>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("element", element->tag_name());
}

TEST_F(XMLDecoderTest, CanDealWithXIncludeAttack) {
  const std::string input =
      "<?xml version=\"1.0\"?>"
      "<root xmlns:xi=\"http://www.w3.org/2001/XInclude\">"
      "<child>"
      "<name><xi:include href=\"file:///dev/tty\" parse=\"text\"/></name>"
      "</child>"
      "</root>";
  xml_decoder_.reset(new XMLDecoder(
      document_, document_, NULL, kDOMMaxElementDepth, source_location_,
      base::Closure(), base::Bind(&MockErrorCallback::Run,
                                  base::Unretained(&mock_error_callback_))));
  xml_decoder_->DecodeChunk(input.c_str(), input.length());
  xml_decoder_->Finish();

  dom::Element* element = document_->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("root", element->tag_name());

  element = element->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("child", element->tag_name());

  element = element->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("name", element->tag_name());

  element = element->first_element_child();
  ASSERT_TRUE(element);
  EXPECT_EQ("xi:include", element->tag_name());
}

}  // namespace dom_parser
}  // namespace cobalt
