From 626c2a528fdbb53ddc6fede8ce879f56bfe87716 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Thu, 2 Nov 2017 19:59:38 +0000 Subject: Refactoring of cross refs availability check. Use CPDF_CrossRefAvail to check crossrefs. Change-Id: Ia333cff4e86eaab5bad17424c1bb8ef9bdbca8ff Reviewed-on: https://pdfium-review.googlesource.com/15510 Commit-Queue: Art Snake Reviewed-by: dsinclair --- .../parser/cpdf_cross_ref_avail_unittest.cpp | 339 +++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp (limited to 'core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp') 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 +#include + +#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 MakeParserForBuffer( + const unsigned char* buffer, + size_t buffer_size) { + auto parser = pdfium::MakeUnique(); + parser->InitParser( + pdfium::MakeRetain(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" + "<<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( + 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" + "<>" + " 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( + 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" + "<>" + " 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( + 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" + "<>" + " 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( + 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" + "<<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( + 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( + 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(table.size()); + table += + "xref \n" + "0 6 \n" + "0000000003 65535 f \n" + "trailer\n" + "<<4f9bb2e7978401808f8f1f2a75c322c8>]" + "/Info 15 0 R/Size 16>>\n"; + table += "Dummy Data jgwhughouiwbahng"; + prev_offset = cur_offset; + cur_offset = static_cast(table.size()); + table += std::string( + "xref \n" + "0 6 \n" + "0000000003 65535 f \n" + "trailer\n" + "<<" + "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(table.size()); + table += std::string( + "xref \n" + "0 6 \n" + "0000000003 65535 f \n" + "trailer\n" + "<<" + "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(table.data()), table.size()); + auto cross_ref_avail = pdfium::MakeUnique( + 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(table.size()); + table += + "16 0 obj\n" + "<>" + " 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(table.size()); + table += std::string( + "55 0 obj\n" + "<>" + " 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(table.size()); + table += std::string( + "88 0 obj\n" + "<>" + " 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(table.data()), table.size()); + auto cross_ref_avail = pdfium::MakeUnique( + 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(table.size()); + table += + "16 0 obj\n" + "<>" + " 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(table.size()); + table += std::string( + "xref \n" + "0 6 \n" + "0000000003 65535 f \n" + "trailer\n" + "<<" + "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(table.size()); + table += std::string( + "xref \n" + "0 6 \n" + "0000000003 65535 f \n" + "trailer\n" + "<<" + "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(table.data()), table.size()); + auto cross_ref_avail = pdfium::MakeUnique( + 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( + 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" + "<<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( + 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" + "<>" + " 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( + parser.get(), last_crossref_offset); + EXPECT_EQ(CPDF_DataAvail::DataError, cross_ref_avail->CheckAvail()); +} -- cgit v1.2.3