// Copyright 2016 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 #include #include #include "core/fxcodec/codec/ccodec_basicmodule.h" #include "core/fxcodec/fx_codec.h" #include "testing/gtest/include/gtest/gtest.h" TEST(fxcodec, A85TestBadInputs) { const uint8_t src_buf[] = {1, 2, 3, 4}; std::unique_ptr dest_buf; uint32_t dest_size = 0; CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule(); EXPECT_TRUE(pEncoders); // Error codes, not segvs, should callers pass us a nullptr pointer. EXPECT_FALSE(pEncoders->A85Encode(src_buf, &dest_buf, nullptr)); EXPECT_FALSE(pEncoders->A85Encode(src_buf, nullptr, &dest_size)); EXPECT_FALSE(pEncoders->A85Encode({}, &dest_buf, &dest_size)); } // No leftover bytes, just translate 2 sets of symbols. TEST(fxcodec, A85TestBasic) { CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule(); EXPECT_TRUE(pEncoders); // Make sure really big values don't break. const uint8_t src_buf[] = {1, 2, 3, 4, 255, 255, 255, 255}; std::unique_ptr dest_buf; uint32_t dest_size = 0; EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size)); // Should have 5 chars for each set of 4 and 2 terminators. const uint8_t expected_out[] = {33, 60, 78, 63, 43, 115, 56, 87, 45, 33, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out[i], dest_buf_span[i]) << " at " << i; } // Leftover bytes. TEST(fxcodec, A85TestLeftoverBytes) { CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule(); EXPECT_TRUE(pEncoders); std::unique_ptr dest_buf; uint32_t dest_size = 0; { // 1 Leftover Byte: const uint8_t src_buf_1leftover[] = {1, 2, 3, 4, 255}; EXPECT_TRUE(pEncoders->A85Encode(src_buf_1leftover, &dest_buf, &dest_size)); // 5 chars for first symbol + 2 + 2 terminators. uint8_t expected_out_1leftover[] = {33, 60, 78, 63, 43, 114, 114, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out_1leftover), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out_1leftover[i], dest_buf_span[i]) << " at " << i; } { // 2 Leftover bytes: const uint8_t src_buf_2leftover[] = {1, 2, 3, 4, 255, 254}; dest_buf.reset(); dest_size = 0; EXPECT_TRUE(pEncoders->A85Encode(src_buf_2leftover, &dest_buf, &dest_size)); // 5 chars for first symbol + 3 + 2 terminators. const uint8_t expected_out_2leftover[] = {33, 60, 78, 63, 43, 115, 56, 68, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out_2leftover), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out_2leftover[i], dest_buf_span[i]) << " at " << i; } { // 3 Leftover bytes: const uint8_t src_buf_3leftover[] = {1, 2, 3, 4, 255, 254, 253}; dest_buf.reset(); dest_size = 0; EXPECT_TRUE(pEncoders->A85Encode(src_buf_3leftover, &dest_buf, &dest_size)); // 5 chars for first symbol + 4 + 2 terminators. const uint8_t expected_out_3leftover[] = {33, 60, 78, 63, 43, 115, 56, 77, 114, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out_3leftover), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out_3leftover[i], dest_buf_span[i]) << " at " << i; } } // Test all zeros comes through as "z". TEST(fxcodec, A85TestZeros) { CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule(); EXPECT_TRUE(pEncoders); std::unique_ptr dest_buf; uint32_t dest_size = 0; { // Make sure really big values don't break. const uint8_t src_buf[] = {1, 2, 3, 4, 0, 0, 0, 0}; EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size)); // Should have 5 chars for first set of 4 + 1 for z + 2 terminators. const uint8_t expected_out[] = {33, 60, 78, 63, 43, 122, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out[i], dest_buf_span[i]) << " at " << i; } { // Should also work if it is at the start: const uint8_t src_buf_2[] = {0, 0, 0, 0, 1, 2, 3, 4}; dest_buf.reset(); dest_size = 0; EXPECT_TRUE(pEncoders->A85Encode(src_buf_2, &dest_buf, &dest_size)); // Should have 5 chars for set of 4 + 1 for z + 2 terminators. const uint8_t expected_out_2[] = {122, 33, 60, 78, 63, 43, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out_2), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out_2[i], dest_buf_span[i]) << " at " << i; } { // Try with 2 leftover zero bytes. Make sure we don't get a "z". const uint8_t src_buf_3[] = {1, 2, 3, 4, 0, 0}; dest_buf.reset(); dest_size = 0; EXPECT_TRUE(pEncoders->A85Encode(src_buf_3, &dest_buf, &dest_size)); // Should have 5 chars for set of 4 + 3 for last 2 + 2 terminators. const uint8_t expected_out_leftover[] = {33, 60, 78, 63, 43, 33, 33, 33, 126, 62}; ASSERT_EQ(FX_ArraySize(expected_out_leftover), dest_size); // Check the output auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); for (uint32_t i = 0; i < dest_size; i++) EXPECT_EQ(expected_out_leftover[i], dest_buf_span[i]) << " at " << i; } } // Make sure we get returns in the expected locations. TEST(fxcodec, A85TestLineBreaks) { // Make sure really big values don't break. uint8_t src_buf[131] = {0}; // 1 full line + most of a line of normal symbols. for (int k = 0; k < 116; k += 4) { src_buf[k] = 1; src_buf[k + 1] = 2; src_buf[k + 2] = 3; src_buf[k + 3] = 4; } // Fill in the end, leaving an all zero gap + 3 extra zeros at the end. for (int k = 120; k < 128; k++) { src_buf[k] = 1; src_buf[k + 1] = 2; src_buf[k + 2] = 3; src_buf[k + 3] = 4; } std::unique_ptr dest_buf; uint32_t dest_size = 0; CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule(); EXPECT_TRUE(pEncoders); // Should succeed. EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size)); // Should have 75 chars in the first row plus 2 char return, // 76 chars in the second row plus 2 char return, // and 9 chars in the last row with 2 terminators. ASSERT_EQ(166u, dest_size); // Check for the returns. auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size); EXPECT_EQ(13, dest_buf_span[75]); EXPECT_EQ(10, dest_buf_span[76]); EXPECT_EQ(13, dest_buf_span[153]); EXPECT_EQ(10, dest_buf_span[154]); }