// Copyright 2016 The Bazel Authors. 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. /* * Check processing jar with preamble. * * A jar/zip file may contain a preambleL: an arbitrary data before * the actual entries, and the decompressors (e.g., unzip) can handle * this. This feature can be used to create "self-extracting" * archives: use 'cat' command to prepend a binary implementing the * extractor to a zip archive, and then run 'zip -A' on the result to * adjust the entry offsets stored in the zip archive. Actually, some * of the archive reading code works even if 'zip -A' wasn't run. */ #include #include #include #include #include "src/main/cpp/util/file.h" #include "src/main/cpp/util/port.h" #include "src/main/cpp/util/strings.h" #include "src/tools/singlejar/input_jar.h" #include "src/tools/singlejar/test_util.h" #include "googletest/include/gtest/gtest.h" namespace { #if !defined(DATA_DIR_TOP) #define DATA_DIR_TOP #endif void Verify(const std::string &path) { InputJar input_jar; ASSERT_TRUE(input_jar.Open(path)); const LH *lh; const CDH *cdh; while ((cdh = input_jar.NextEntry(&lh))) { ASSERT_TRUE(cdh->is()) << "No expected tag in the Central Directory Entry."; ASSERT_NE(nullptr, lh) << "No local header."; ASSERT_TRUE(lh->is()) << "No expected tag in the Local Header."; EXPECT_EQ(lh->file_name_string(), cdh->file_name_string()); if (!cdh->no_size_in_local_header()) { EXPECT_EQ(lh->compressed_file_size(), cdh->compressed_file_size()) << "Entry: " << lh->file_name_string(); EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size()) << "Entry: " << cdh->file_name_string(); } } input_jar.Close(); } // Archive not containing 64-bit End of Central Directory/Locator with preamble. TEST(InputJarPreambledTest, Small) { std::string out_path = singlejar_test_util::OutputFilePath("out.jwp"); std::string exe_path = singlejar_test_util::OutputFilePath("exe"); ASSERT_TRUE(singlejar_test_util::AllocateFile(exe_path, 100)); ASSERT_EQ( 0, singlejar_test_util::RunCommand( "cat", exe_path.c_str(), DATA_DIR_TOP "src/tools/singlejar/libtest1.jar", ">", out_path.c_str(), nullptr)); Verify(out_path); } // Same as above with zip -A applied to the file. TEST(InputJarPreambledTest, SmallAdjusted) { std::string out_path = singlejar_test_util::OutputFilePath("out.jwp"); std::string exe_path = singlejar_test_util::OutputFilePath("exe"); ASSERT_TRUE(singlejar_test_util::AllocateFile(exe_path, 100)); ASSERT_EQ( 0, singlejar_test_util::RunCommand( "cat", exe_path.c_str(), DATA_DIR_TOP "src/tools/singlejar/libtest1.jar", ">", out_path.c_str(), nullptr)); ASSERT_EQ(0, singlejar_test_util::RunCommand("zip", "-A", out_path.c_str(), nullptr)); Verify(out_path); } // 64-bit Zip file with preamble TEST(InputJarPreambledTest, Huge) { std::string file4g = singlejar_test_util::OutputFilePath("file4g"); ASSERT_TRUE(singlejar_test_util::AllocateFile(file4g, 0x10000000F)); std::string huge_jar = singlejar_test_util::OutputFilePath("huge.jar"); ASSERT_EQ(0, singlejar_test_util::RunCommand("zip", "-0m", huge_jar.c_str(), file4g.c_str(), nullptr)); std::string exe_path = singlejar_test_util::OutputFilePath("exe"); std::string out_path = singlejar_test_util::OutputFilePath("out.jwp"); ASSERT_EQ(0, singlejar_test_util::RunCommand("cat", exe_path.c_str(), huge_jar.c_str(), ">", out_path.c_str(), nullptr)); Verify(out_path); } } // namespace