summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp b/core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp
new file mode 100644
index 0000000000..b798e17377
--- /dev/null
+++ b/core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp
@@ -0,0 +1,339 @@
+// Copyright 2017 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/fpdfapi/parser/cpdf_cross_ref_avail.h"
+
+#include <memory>
+#include <string>
+
+#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
+#include "testing/fx_string_testhelpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+std::unique_ptr<CPDF_SyntaxParser> MakeParserForBuffer(
+ const unsigned char* buffer,
+ size_t buffer_size) {
+ auto parser = pdfium::MakeUnique<CPDF_SyntaxParser>();
+ parser->InitParser(
+ pdfium::MakeRetain<CFX_BufferSeekableReadStream>(buffer, buffer_size), 0);
+ return parser;
+}
+
+} // namespace
+
+TEST(CPDF_CrossRefAvailTest, CheckCrossRefV4) {
+ const unsigned char xref_table[] =
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "0000000017 00000 n \n"
+ "0000000081 00000 n \n"
+ "0000000000 00007 f \n"
+ "0000000331 00000 n \n"
+ "0000000409 00000 n \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16>>";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_table, FX_ArraySize(xref_table));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+
+ EXPECT_EQ(CPDF_DataAvail::DataAvailable, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, CheckCrossRefStream) {
+ const unsigned char xref_stream[] =
+ "16 0 obj\n"
+ "<</Filter /FlateDecode>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA\n"
+ "endstream\n"
+ "endobj\n";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_stream, FX_ArraySize(xref_stream));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+
+ EXPECT_EQ(CPDF_DataAvail::DataAvailable, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, IncorrectStartOffset) {
+ const unsigned char xref_stream[] =
+ "16 0 obj\n"
+ "<</Filter /FlateDecode>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA\n"
+ "endstream\n"
+ "endobj\n";
+
+ const FX_FILESIZE last_crossref_offset = 70000;
+
+ auto parser = MakeParserForBuffer(xref_stream, FX_ArraySize(xref_stream));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, IncorrectPrevOffset) {
+ const unsigned char xref_stream[] =
+ "16 0 obj\n"
+ "<</Type /XRef /Prev 70000>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA\n"
+ "endstream\n"
+ "endobj\n";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_stream, FX_ArraySize(xref_stream));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, IncorrectPrevStreamOffset) {
+ const unsigned char xref_table[] =
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "0000000017 00000 n \n"
+ "0000000081 00000 n \n"
+ "0000000000 00007 f \n"
+ "0000000331 00000 n \n"
+ "0000000409 00000 n \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16 /XRefStm 70000>>";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_table, FX_ArraySize(xref_table));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, IncorrectData) {
+ const unsigned char incorrect_data[] =
+ "fiajaoilf w9ifaoihwoiafhja wfijaofijoiaw fhj oiawhfoiah "
+ "wfoihoiwfghouiafghwoigahfi";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser =
+ MakeParserForBuffer(incorrect_data, FX_ArraySize(incorrect_data));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, ThreeCrossRefV4) {
+ char int_buffer[100];
+ int prev_offset = 0;
+ int cur_offset = 0;
+ std::string table = "pdf blah blah blah\n";
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table +=
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16>>\n";
+ table += "Dummy Data jgwhughouiwbahng";
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table += std::string(
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><"
+ "4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16"
+ "/Prev ") +
+ FXSYS_itoa(prev_offset, int_buffer, 10) + ">>\n";
+ table += "More Dummy Data jgwhughouiwbahng";
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table += std::string(
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><"
+ "4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16"
+ "/Prev ") +
+ FXSYS_itoa(prev_offset, int_buffer, 10) + ">>\n";
+ const FX_FILESIZE last_crossref_offset = cur_offset;
+
+ auto parser = MakeParserForBuffer(
+ reinterpret_cast<const unsigned char*>(table.data()), table.size());
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataAvailable, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, ThreeCrossRefV5) {
+ char int_buffer[100];
+ int prev_offset = 0;
+ int cur_offset = 0;
+ std::string table = "pdf blah blah blah\n";
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table +=
+ "16 0 obj\n"
+ "<</Type /XRef>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA ahfcuabfkuabfu\n"
+ "endstream\n"
+ "endobj\n";
+ table += "Dummy Data jgwhughouiwbahng";
+
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table += std::string(
+ "55 0 obj\n"
+ "<</Type /XRef /Prev ") +
+ FXSYS_itoa(prev_offset, int_buffer, 10) +
+ ">>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA\n"
+ "endstream\n"
+ "endobj\n";
+ table += "More Dummy Data jgwhughouiwbahng";
+ prev_offset = cur_offset;
+ cur_offset = static_cast<int>(table.size());
+ table += std::string(
+ "88 0 obj\n"
+ "<</Type /XRef /NNNN /Prev ") +
+ FXSYS_itoa(prev_offset, int_buffer, 10) +
+ ">>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA favav\n"
+ "endstream\n"
+ "endobj\n";
+ const FX_FILESIZE last_crossref_offset = cur_offset;
+
+ auto parser = MakeParserForBuffer(
+ reinterpret_cast<const unsigned char*>(table.data()), table.size());
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataAvailable, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, Mixed) {
+ char int_buffer[100];
+ std::string table = "pdf blah blah blah\n";
+
+ const int first_v5_table_offset = static_cast<int>(table.size());
+ table +=
+ "16 0 obj\n"
+ "<</Type /XRef>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA ahfcuabfkuabfu\n"
+ "endstream\n"
+ "endobj\n";
+ table += "Dummy Data jgwhughouiwbahng";
+
+ const int second_v4_table_offset = static_cast<int>(table.size());
+ table += std::string(
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><"
+ "4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16"
+ "/Prev ") +
+ FXSYS_itoa(first_v5_table_offset, int_buffer, 10) + ">>\n";
+ table += "More Dummy Data jgwhughouiwbahng";
+
+ const int last_v4_table_offset = static_cast<int>(table.size());
+ table += std::string(
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><"
+ "4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Info 15 0 R/Size 16"
+ "/Prev ") +
+ FXSYS_itoa(second_v4_table_offset, int_buffer, 10) + " /XRefStm " +
+ FXSYS_itoa(first_v5_table_offset, int_buffer, 10) + ">>\n";
+ const FX_FILESIZE last_crossref_offset = last_v4_table_offset;
+
+ auto parser = MakeParserForBuffer(
+ reinterpret_cast<const unsigned char*>(table.data()), table.size());
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataAvailable, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, CrossRefV5IsNotStream) {
+ const unsigned char invalid_xref_stream[] =
+ "16 0 obj\n"
+ "[/array /object]\n"
+ "endstream\n"
+ "endobj\n";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(invalid_xref_stream,
+ FX_ArraySize(invalid_xref_stream));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, CrossRefV4WithEncryptRef) {
+ const unsigned char xref_table[] =
+ "xref \n"
+ "0 6 \n"
+ "0000000003 65535 f \n"
+ "0000000017 00000 n \n"
+ "0000000081 00000 n \n"
+ "0000000000 00007 f \n"
+ "0000000331 00000 n \n"
+ "0000000409 00000 n \n"
+ "trailer\n"
+ "<</Root 14 0 R/ID "
+ "[<afbb0f593c2d2aea5b519cb61da1c17b><4f9bb2e7978401808f8f1f2a75c322c8>]"
+ "/Encrypt 77 0 R"
+ "/Info 15 0 R/Size 16>>";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_table, FX_ArraySize(xref_table));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}
+
+TEST(CPDF_CrossRefAvailTest, CrossRefStreamWithEncryptRef) {
+ const unsigned char xref_stream[] =
+ "16 0 obj\n"
+ "<</Filter /FlateDecode /Encrypt 77 0 R>>"
+ " stream \n"
+ "STREAM DATA STREAM DATA STREAM DATA\n"
+ "endstream\n"
+ "endobj\n";
+ const FX_FILESIZE last_crossref_offset = 0;
+
+ auto parser = MakeParserForBuffer(xref_stream, FX_ArraySize(xref_stream));
+ auto cross_ref_avail = pdfium::MakeUnique<CPDF_CrossRefAvail>(
+ parser.get(), last_crossref_offset);
+ EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail());
+}