| // 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 <errno.h> |
| #ifndef _WIN32 |
| #include <unistd.h> |
| #endif |
| #include <memory> |
| #include <string> |
| |
| #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 { |
| |
| using bazel::tools::cpp::runfiles::Runfiles; |
| |
| 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::unique_ptr<Runfiles> runfiles(Runfiles::CreateForTest()); |
| 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(), |
| runfiles |
| ->Rlocation( |
| "io_bazel/src/tools/singlejar/libtest1.jar") |
| .c_str(), |
| ">", out_path.c_str(), nullptr)); |
| Verify(out_path); |
| } |
| |
| // Same as above with zip -A applied to the file. |
| TEST(InputJarPreambledTest, SmallAdjusted) { |
| std::unique_ptr<Runfiles> runfiles(Runfiles::CreateForTest()); |
| 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(), |
| runfiles |
| ->Rlocation( |
| "io_bazel/src/tools/singlejar/libtest1.jar") |
| .c_str(), |
| ">", 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 |