// Copyright 2015 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/include/fpdfapi/fpdf_parser.h"
#include "core/include/fxcrt/fx_stream.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/path_service.h"

class CPDF_TestParser : public CPDF_Parser {
 public:
  CPDF_TestParser() {}
  ~CPDF_TestParser() {}

  bool InitTest(const FX_CHAR* path) {
    IFX_FileRead* pFileAccess = FX_CreateFileRead(path);
    if (!pFileAccess)
      return false;

    // For the test file, the header is set at the beginning.
    m_Syntax.InitParser(pFileAccess, 0);
    return true;
  }

 private:
  // Add test case as private friend so that RebuildCrossRef in CPDF_Parser
  // can be accessed.
  FRIEND_TEST(fpdf_parser_parser, RebuildCrossRefCorrectly);
};

// TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal.
// Come up or wait for something better.
using ScopedFileStream =
    nonstd::unique_ptr<IFX_FileStream, ReleaseDeleter<IFX_FileStream>>;

TEST(fpdf_parser_parser, ReadHexString) {
  {
    // Empty string.
    uint8_t data[] = "";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 0, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("", parser.ReadHexString());
    EXPECT_EQ(0, parser.SavePos());
  }

  {
    // Blank string.
    uint8_t data[] = "  ";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 2, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("", parser.ReadHexString());
    EXPECT_EQ(2, parser.SavePos());
  }

  {
    // Skips unknown characters.
    uint8_t data[] = "z12b";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x12\xb0", parser.ReadHexString());
    EXPECT_EQ(4, parser.SavePos());
  }

  {
    // Skips unknown characters.
    uint8_t data[] = "*<&*#$^&@1";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 10, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x10", parser.ReadHexString());
    EXPECT_EQ(10, parser.SavePos());
  }

  {
    // Skips unknown characters.
    uint8_t data[] = "\x80zab";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\xab", parser.ReadHexString());
    EXPECT_EQ(4, parser.SavePos());
  }

  {
    // Skips unknown characters.
    uint8_t data[] = "\xffzab";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\xab", parser.ReadHexString());
    EXPECT_EQ(4, parser.SavePos());
  }

  {
    // Regular conversion.
    uint8_t data[] = "1A2b>abcd";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 9, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
    EXPECT_EQ(5, parser.SavePos());
  }

  {
    // Position out of bounds.
    uint8_t data[] = "12ab>";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    parser.RestorePos(5);
    EXPECT_EQ("", parser.ReadHexString());

    parser.RestorePos(6);
    EXPECT_EQ("", parser.ReadHexString());

    parser.RestorePos(-1);
    EXPECT_EQ("", parser.ReadHexString());

    parser.RestorePos(std::numeric_limits<FX_FILESIZE>::max());
    EXPECT_EQ("", parser.ReadHexString());

    // Check string still parses when set to 0.
    parser.RestorePos(0);
    EXPECT_EQ("\x12\xab", parser.ReadHexString());
  }

  {
    // Missing ending >.
    uint8_t data[] = "1A2b";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
    EXPECT_EQ(4, parser.SavePos());
  }

  {
    // Missing ending >.
    uint8_t data[] = "12abz";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x12\xab", parser.ReadHexString());
    EXPECT_EQ(5, parser.SavePos());
  }

  {
    // Uneven number of bytes.
    uint8_t data[] = "1A2>asdf";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x1a\x20", parser.ReadHexString());
    EXPECT_EQ(4, parser.SavePos());
  }

  {
    // Uneven number of bytes.
    uint8_t data[] = "1A2zasdf";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
    EXPECT_EQ(8, parser.SavePos());
  }

  {
    // Just ending character.
    uint8_t data[] = ">";
    ScopedFileStream stream(FX_CreateMemoryStream(data, 1, FALSE));

    CPDF_SyntaxParser parser;
    parser.InitParser(stream.get(), 0);
    EXPECT_EQ("", parser.ReadHexString());
    EXPECT_EQ(1, parser.SavePos());
  }
}

TEST(fpdf_parser_parser, RebuildCrossRefCorrectly) {
  CPDF_TestParser parser;
  std::string test_file;
  ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf",
                                           &test_file));
  ASSERT_TRUE(parser.InitTest(test_file.c_str())) << test_file;

  ASSERT_TRUE(parser.RebuildCrossRef());
  const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450};
  const FX_WORD versions[] = {0, 0, 2, 4, 6, 8, 0};
  static_assert(FX_ArraySize(offsets) == FX_ArraySize(versions),
                "numbers of offsets and versions should be same.");
  ASSERT_EQ(FX_ArraySize(offsets), parser.m_CrossRef.GetSize());
  ASSERT_EQ(FX_ArraySize(versions), parser.m_ObjVersion.GetSize());

  for (int i = 0; i < FX_ArraySize(offsets); ++i) {
    EXPECT_EQ(offsets[i], parser.m_CrossRef.GetAt(i));
    EXPECT_EQ(versions[i], parser.m_ObjVersion.GetAt(i));
  }
}
