@@ -242,7 +242,7 @@ namespace vcpkg
242242#ifdef _WIN32
243243 void win32_extract_self_extracting_7z (const Filesystem& fs, const Path& archive, const Path& to_path)
244244 {
245- constexpr static const char header_7z[] = " 7z\xBC\xAF\x27\x1C " ;
245+ static constexpr StringLiteral header_7z = " 7z\xBC\xAF\x27\x1C " ;
246246 const Path stem = archive.stem ();
247247 const auto subext = stem.extension ();
248248 Checks::msg_check_exit (VCPKG_LINE_INFO,
@@ -251,14 +251,24 @@ namespace vcpkg
251251 .append (msgMissingExtension, msg::extension = " .7.exe" ));
252252
253253 auto contents = fs.read_contents (archive, VCPKG_LINE_INFO);
254- const auto pos = contents.find (header_7z);
254+
255+ // try to chop off the beginning of the self extractor before the embedded 7z archive
256+ // some 7z self extractors, such as PortableGit-2.43.0-32-bit.7z.exe have 1 header
257+ // some 7z self extractors, such as 7z2408-x64.exe, have 2 headers
258+ auto pos = contents.find (header_7z.data (), 0 , header_7z.size ());
255259 Checks::msg_check_exit (VCPKG_LINE_INFO,
256260 pos != std::string::npos,
257261 msg::format (msgPackageFailedtWhileExtracting, msg::value = " 7zip" , msg::path = archive)
258262 .append (msgMissing7zHeader));
263+ // no bounds check necessary because header_7z is nonempty:
264+ auto pos2 = contents.find (header_7z.data (), pos + 1 , header_7z.size ());
265+ if (pos2 != std::string::npos)
266+ {
267+ pos = pos2;
268+ }
259269
260- contents = contents. substr (pos) ;
261- fs.write_contents (to_path, contents , VCPKG_LINE_INFO);
270+ StringView contents_sv = contents;
271+ fs.write_contents (to_path, contents_sv. substr (pos) , VCPKG_LINE_INFO);
262272 }
263273#endif
264274
0 commit comments