Browse Source

Fix slice file name for Inno Setup < 4.1.7

For backwards compatibility we now always try both the slice filename
derived from the setup filename as well as the one derived from the
basename stored in the setup headers. The setup version only determines
which name to try first.

Fixes: issue #59
coverity_scan
Daniel Scharrer 8 years ago
parent
commit
94ffb9cd37
  1. 1
      CHANGELOG
  2. 17
      src/cli/extract.cpp
  3. 7
      src/cli/gog.cpp
  4. 2
      src/cli/gog.hpp
  5. 19
      src/stream/slice.cpp
  6. 5
      src/stream/slice.hpp

1
CHANGELOG

@ -3,6 +3,7 @@ innoextract 1.7 (TDB)
- Added (preliminary) support for Inno Setup 5.6.0 installers
- Fixed building in paths that contain regex expressions
- Fixed case-sensitivity in parent directory when creating subdirectories
- Fixed .bin slice file names used with Inno Setup versions older than 4.1.7
innoextract 1.6 (2016-03-24)
- Added support for Inno Setup 5.5.7 (and 5.5.8) installers

17
src/cli/extract.cpp

@ -782,15 +782,22 @@ void process_file(const fs::path & file, const extract_options & o) {
total_size += location.uncompressed_size;
}
fs::path dir = file.parent_path();
std::string basename = util::as_string(file.stem());
boost::scoped_ptr<stream::slice_reader> slice_reader;
if(o.extract || o.test) {
if(offsets.data_offset) {
slice_reader.reset(new stream::slice_reader(&ifs, offsets.data_offset));
} else {
slice_reader.reset(new stream::slice_reader(dir, basename, info.header.slices_per_disk));
fs::path dir = file.parent_path();
std::string basename = util::as_string(file.stem());
std::string basename2 = info.header.base_filename;
// Prevent access to unexpected files
std::replace(basename2.begin(), basename2.end(), '/', '_');
std::replace(basename2.begin(), basename2.end(), '\\', '_');
// Older Inno Setup versions used the basename stored in the headers, change our default accordingly
if(info.version < INNO_VERSION(4, 1, 7) && !basename2.empty()) {
std::swap(basename2, basename);
}
slice_reader.reset(new stream::slice_reader(dir, basename, basename2, info.header.slices_per_disk));
}
}
@ -963,7 +970,7 @@ void process_file(const fs::path & file, const extract_options & o) {
extract_progress.clear();
if(o.warn_unused || o.gog) {
gog::probe_bin_files(o, info, dir, basename, offsets.data_offset == 0);
gog::probe_bin_files(o, info, file, offsets.data_offset == 0);
}
}

7
src/cli/gog.cpp

@ -488,8 +488,11 @@ size_t probe_bin_file_series(const extract_options & o, const setup::info & info
} // anonymous namespace
void probe_bin_files(const extract_options & o, const setup::info & info, const fs::path & dir,
const std::string & basename, bool external) {
void probe_bin_files(const extract_options & o, const setup::info & info,
const fs::path & setup_file, bool external) {
boost::filesystem::path dir = setup_file.parent_path();
std::string basename = util::as_string(setup_file.stem());
size_t bin_count = 0;
bin_count += probe_bin_file_series(o, info, dir, basename + ".bin");

2
src/cli/gog.hpp

@ -41,7 +41,7 @@ namespace gog {
std::string get_game_id(const setup::info & info);
void probe_bin_files(const extract_options & o, const setup::info & info,
const boost::filesystem::path & dir, const std::string & basename, bool external);
const boost::filesystem::path & setup_file, bool external);
} // namespace gog

19
src/stream/slice.cpp

@ -57,10 +57,10 @@ slice_reader::slice_reader(std::istream * istream, boost::uint32_t data_offset)
}
}
slice_reader::slice_reader(const path_type & dir, const std::string & base_file,
size_t slices_per_disk)
slice_reader::slice_reader(const path_type & dir, const std::string & basename,
const std::string & basename2, size_t slices_per_disk)
: data_offset(0),
dir(dir), base_file(base_file),
dir(dir), base_file(basename), base_file2(basename2),
slices_per_disk(slices_per_disk), current_slice(0), slice_size(0),
is(&ifs) { }
@ -79,6 +79,10 @@ void slice_reader::seek(size_t slice) {
bool slice_reader::open_file(const path_type & file) {
if(!boost::filesystem::exists(file)) {
return false;
}
log_info << "Opening \"" << color::cyan << file.string() << color::reset << '"';
ifs.close();
@ -160,13 +164,20 @@ void slice_reader::open(size_t slice) {
ifs.close();
path_type slice_file = slice_filename(base_file, slice, slices_per_disk);
if(open_file(dir / slice_file)) {
return;
}
path_type slice_file2 = slice_filename(base_file2, slice, slices_per_disk);
if(!base_file2.empty() && slice_file2 != slice_file && open_file(dir / slice_file2)) {
return;
}
std::ostringstream oss;
oss << "could not open slice " << slice << ": " << slice_file;
if(!base_file2.empty() && slice_file2 != slice_file) {
oss << " or " << slice_file2;
}
throw slice_error(oss.str());
}

5
src/stream/slice.hpp

@ -64,6 +64,7 @@ class slice_reader : public boost::iostreams::source {
// Information for eading external setup data
path_type dir; //!< Slice directory specified at construction.
std::string base_file; //!< Base file name for slices.
std::string base_file2; //!< Fallback base filename for slices.
const size_t slices_per_disk; //!< Number of slices grouped into each disk (for names).
// Information about the current slice
@ -110,9 +111,11 @@ public:
*
* \param dir The directory containing the slice files.
* \param basename The base name for slice files.
* \param basename2 Alternative base name for slice files.
* \param slices_per_disk How many slices are grouped into one disk. Must not be \c 0.
*/
slice_reader(const path_type & dir, const std::string & basename, size_t slices_per_disk);
slice_reader(const path_type & dir, const std::string & basename, const std::string & basename2,
size_t slices_per_disk);
/*!
* Attempt to seek to an offset within a slice.

Loading…
Cancel
Save