@@ -2244,6 +2244,92 @@ TEMPLATE_TEST_CASE(
22442244 }
22452245}
22462246
2247+ // NOLINTNEXTLINE(*-err58-cpp)
2248+ TEST_CASE (
2249+ " BitInputArchive: Reading the main subfile of an archive with a specified archive start offset" ,
2250+ " [bitinputarchive]"
2251+ ) {
2252+ const TestDirectory testDir{ fs::path{ test_archives_dir } / " extraction" / " split" };
2253+
2254+ // A split archive exposes its reassembled content as the main subfile; here that content is a 7z
2255+ // archive located at the start of the subfile stream, so it can be opened both by checking only
2256+ // the file start and by scanning the whole subfile stream.
2257+ const fs::path splitArcFileName = " clouds.jpg.7z.001" ;
2258+ const BitArchiveReader splitArchive ( test::sevenzipLib (), splitArcFileName.string < tchar >(), BitFormat::Split );
2259+
2260+ const auto archiveStart = GENERATE ( ArchiveStartOffset::FileStart, ArchiveStartOffset::None );
2261+
2262+ const BitArchiveReader innerArchive ( test::sevenzipLib (), splitArchive, archiveStart, BitFormat::SevenZip );
2263+ REQUIRE ( innerArchive.itemsCount () == singleFileContent ().fileCount );
2264+ REQUIRE_ARCHIVE_TESTS ( innerArchive );
2265+ }
2266+
2267+ // NOLINTNEXTLINE(*-err58-cpp)
2268+ TEMPLATE_TEST_CASE (
2269+ " BitInputArchive: Reading a subfile by index of an archive with a specified archive start offset" ,
2270+ " [bitinputarchive]" ,
2271+ tstring,
2272+ buffer_t ,
2273+ stream_t
2274+ ) {
2275+ const TestDirectory testDir{ fs::path{ test_archives_dir } / " extraction" / " nested" };
2276+
2277+ const fs::path arcFileName = " multiple_nested2.tar" ;
2278+
2279+ TestType inputArchive{};
2280+ getInputArchive ( arcFileName, inputArchive );
2281+ const Bit7zLibrary lib{ test::sevenzipLibPath () };
2282+
2283+ // The outer Tar archive stores nested archives as its items; Tar supports retrieving each item's
2284+ // stream, which can then be opened as a nested archive at the specified archive start offset.
2285+ const BitArchiveReader outerArchive ( lib, inputArchive, BitFormat::Tar );
2286+
2287+ const auto archiveStart = GENERATE ( ArchiveStartOffset::FileStart, ArchiveStartOffset::None );
2288+
2289+ SECTION ( " Opening the nested 7z subfile" ) {
2290+ const BitArchiveReader innerArchive ( lib, outerArchive, 1U , archiveStart, BitFormat::SevenZip );
2291+ REQUIRE_NOTHROW ( innerArchive.test () );
2292+ }
2293+
2294+ SECTION ( " Opening the nested zip subfile" ) {
2295+ const BitArchiveReader innerArchive ( lib, outerArchive, 2U , archiveStart, BitFormat::Zip );
2296+ REQUIRE_NOTHROW ( innerArchive.test () );
2297+ }
2298+ }
2299+
2300+ // NOLINTNEXTLINE(*-err58-cpp)
2301+ TEST_CASE (
2302+ " BitInputArchive: Reading a subfile whose archive data does not start at the subfile stream start" ,
2303+ " [bitinputarchive]"
2304+ ) {
2305+ const TestDirectory testDir{ fs::path{ test_archives_dir } / " extraction" / " nested" };
2306+
2307+ const fs::path arcFileName = " multiple_nested2.tar" ;
2308+
2309+ const Bit7zLibrary lib{ test::sevenzipLibPath () };
2310+
2311+ // TODO: Add some fixture archives with an embedded archive at a non-zero offset *within* a subfile stream.
2312+ // Until then, build one at runtime: an outer Tar whose only item is multiple_nested2.tar (itself a Tar
2313+ // holding a nested 7z). The Tar handler returns that item's bytes verbatim, so within the subfile stream
2314+ // the nested 7z starts well after offset 0 (which is just a Tar header).
2315+ // This way we can test a case where the two ArchiveStartOffset values behave differently, proving that
2316+ // FileStart restricts the scan.
2317+ buffer_t outerArchiveBuffer;
2318+ BitArchiveWriter writer{ lib, BitFormat::Tar };
2319+ writer.addFile ( arcFileName.string < tchar >() );
2320+ writer.compressTo ( outerArchiveBuffer );
2321+
2322+ const BitArchiveReader outerArchive ( lib, outerArchiveBuffer, BitFormat::Tar );
2323+
2324+ // Scanning the whole subfile stream (None) finds the nested 7z archive, so the opening succeeds...
2325+ const BitArchiveReader innerArchive ( lib, outerArchive, 0U , ArchiveStartOffset::None, BitFormat::SevenZip );
2326+ REQUIRE_NOTHROW ( innerArchive.test () );
2327+
2328+ // ...while checking only the file start of the same subfile stream (FileStart) sees a Tar header
2329+ // instead of a 7z signature, so the opening must fail.
2330+ REQUIRE_THROWS ( BitArchiveReader ( lib, outerArchive, 0U , ArchiveStartOffset::FileStart, BitFormat::SevenZip ) );
2331+ }
2332+
22472333// NOLINTNEXTLINE(*-err58-cpp)
22482334TEMPLATE_TEST_CASE (
22492335 " BitInputArchive: Reading a nested archive with wrong extension" ,
0 commit comments