innoextract icon indicating copy to clipboard operation
innoextract copied to clipboard

infinite loop on after "Unexpected output file size"

Open corwinn opened this issue 4 years ago • 0 comments

hi, while unpacking foo-gog.exe using "innoextract-1.9-windows.zip" I got "Unexpected output file size" followed by an infinite loop (100% CPU usage ; "procmon" shows no activity at all);

innoextract.exe -t shows the same warning, but there is no inf. loop afterwards.

command: innoextract.exe -m -g --language en-US foo-gog.exe

Unfortunately the issue ain't reproducible with "innoextract-1.9.tar.gz" built by "clang"-10.0.1 on "linux" x86_64 - no infinite loop, but more messages: "Warning: Unexpected output file size: "... Warning: Could not read back "bar" to calculate output checksum for multi-part file". "bar" exists and is completely readable. State (on "linux") on function entry:

  • stream_.eof() = 0
  • max = 2305843009213693951
  • diff = checksum_position_ = file size (18876436)
  • "seekg(diff" sets the read pointer to the last byte of the file
  • "diff -=" sets "diff" to 0 ; the 1st "while" does not execute
  • the 2nd "while" executes once, since the 1st "read" raises "eof"

Perhaps, you should try the above in your "windows" environment.

Given "http://www.cplusplus.com/reference/istream/istream/read/", could you create a test "windows" build with this patch:

diff --git a/innoextract-1.9/src/cli/extract.cpp b/../innoextract-1.9/src/cli/extract.cpp
index 91c3152..82e04e3 100644
--- a/innoextract-1.9/src/cli/extract.cpp
+++ b/../innoextract-1.9/src/cli/extract.cpp
@@ -255,11 +255,16 @@ public:
                while(!stream_.eof()) {
                        char buffer[8192];
                        std::streamsize n = stream_.read(buffer, sizeof(buffer)).gcount();
+                       if ((n <= 0 || not stream_) && not stream_.eof()) {
+                               log_warning << "TODO: calculate_checksum(): handle !eof can't read"
+                                       << "at " << __FILE__ << ":" << __LINE__;
+                               goto _has_checksum__aint_a_state;
+                       }
                        checksum_.update(buffer, size_t(n));
                        checksum_position_ += boost::uint64_t(n);
                }

-               if(!has_checksum()) {
+               if(!has_checksum()) { _has_checksum__aint_a_state:
                        log_warning << "Could not read back " << path_ << " to calculate output checksum for multi-part file";
                        return false;
                }

Thanks.

corwinn avatar Oct 21 '20 18:10 corwinn