I am sponsoring NMU 1.9-0.1. debdiff attached.
diff -Nru innoextract-1.8/CHANGELOG innoextract-1.9/CHANGELOG
--- innoextract-1.8/CHANGELOG   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/CHANGELOG   2020-08-09 20:48:04.000000000 +0200
@@ -1,4 +1,14 @@
 
+innoextract 1.9 (2020-08-09)
+ - Added preliminary support for Inno Setup 6.1.0
+ - Added support for a modified Inno Setup 5.4.2 variant
+ - Fixed output directory being created for unsupported installers
+ - Fixed some safe non-ASCII characters being stripped from filenames
+ - Fixed handling of path separators in Japanese and Korean installers
+ - Fixed build with newer Boost versions
+ - Windows: Fixed heap corruption
+ - Windows: Fixed garbled output
+
 innoextract 1.8 (2019-09-15)
  - Added support for Inno Setup 6.0.0 installers
  - Added support for pre-release Inno Setup 5.6.2 installers used by GOG
diff -Nru innoextract-1.8/cmake/CompileCheck.cmake 
innoextract-1.9/cmake/CompileCheck.cmake
--- innoextract-1.8/cmake/CompileCheck.cmake    2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/cmake/CompileCheck.cmake    2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2019 Daniel Scharrer
+# Copyright (C) 2011-2020 Daniel Scharrer
 #
 # This software is provided 'as-is', without any express or implied
 # warranty.  In no event will the author(s) be held liable for any damages
@@ -131,7 +131,7 @@
 endfunction(check_flag)
 
 macro(strip_warning_flags VAR)
-       string(REGEX REPLACE "(^| )\\-(W[^ ]*|pedantic)" "" ${VAR} "${${VAR}}")
+       string(REGEX REPLACE "(^| )\\-(W[^ l][^ ]*|Wl[^,][^ ]*|pedantic)" "" 
${VAR} "${${VAR}}")
 endmacro()
 
 function(check_builtin RESULT EXPR)
@@ -191,96 +191,3 @@
        endif()
        
 endfunction(add_ldflag)
-
-function(try_link_library LIBRARY_NAME LIBRARY_FILE ERROR_VAR)
-       # See if we can link a simple program with the library using the 
configured c++ compiler
-       set(link_test_file "${CMAKE_CURRENT_BINARY_DIR}/link_test.cpp")
-       file(WRITE ${link_test_file} "int main(){}\n")
-       if(CMAKE_THREAD_LIBS_INIT)
-               list(APPEND LIBRARY_FILE "${CMAKE_THREAD_LIBS_INIT}")
-       endif()
-       try_compile(
-               CHECK_${LIBRARY_NAME}_LINK "${PROJECT_BINARY_DIR}" 
"${link_test_file}"
-               CMAKE_FLAGS "-DLINK_LIBRARIES=${LIBRARY_FILE}"
-                           "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
-                           "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}"
-                           
"-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}"
-                           
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
-               OUTPUT_VARIABLE ERRORLOG
-       )
-       set(${ERROR_VAR} "${ERRORLOG}" PARENT_SCOPE)
-endfunction(try_link_library)
-
-##############################################################################
-# Check that a a library actually works for the current configuration
-# This is neede because CMake prefers /usr/lib over /usr/lib32 for -m32 builds
-# See https://public.kitware.com/Bug/view.php?id=11260
-function(check_link_library LIBRARY_NAME LIBRARY_VARIABLE)
-       
-       if(MSVC)
-               # The main point of this is to work around CMakes ignorance of 
lib32.
-               # This doesn't really apply for systems that don't use a 
unix-like library dir layout.
-               return()
-       endif()
-       
-       set(lib_current "${${LIBRARY_VARIABLE}}")
-       set(found_var "ARX_CLL_${LIBRARY_NAME}_FOUND")
-       set(working_var "ARX_CLL_${LIBRARY_NAME}_WORKING")
-       
-       if(CHECK_${LIBRARY_NAME}_LINK)
-               set(lib_found "${${found_var}}")
-               set(lib_working "${${working_var}}")
-               if((lib_current STREQUAL lib_found) OR (lib_current STREQUAL 
lib_working))
-                       set("${LIBRARY_VARIABLE}" "${lib_working}" PARENT_SCOPE)
-                       return()
-               endif()
-       endif()
-       
-       set("${found_var}" "${lib_current}" CACHE INTERNAL "...")
-       
-       if(NOT lib_current STREQUAL "")
-               message(STATUS "Checking ${LIBRARY_NAME}: ${lib_current}")
-       endif()
-       
-       # Check if we can link to the full path found by find_package
-       try_link_library(${LIBRARY_NAME} "${lib_current}" ERRORLOG1)
-       
-       if(CHECK_${LIBRARY_NAME}_LINK)
-               set("${working_var}" "${lib_current}" CACHE INTERNAL "...")
-               return()
-       endif()
-       
-       # Check if the linker is smarter than cmake and try to link with only 
the library name
-       string(REGEX REPLACE "(^|;)[^;]*/lib([^;/]*)\\.so" "\\1-l\\2"
-              LIBRARY_FILE "${lib_current}")
-       
-       if(NOT LIBRARY_FILE STREQUAL lib_current)
-               
-               try_link_library(${LIBRARY_NAME} "${LIBRARY_FILE}" ERRORLOG2)
-               
-               if(CHECK_${LIBRARY_NAME}_LINK)
-                       message(STATUS " -> using ${LIBRARY_FILE} instead")
-                       set("${LIBRARY_VARIABLE}" "${LIBRARY_FILE}" 
PARENT_SCOPE)
-                       set("${working_var}" "${LIBRARY_FILE}" CACHE INTERNAL 
"...")
-                       return()
-               endif()
-               
-       endif()
-       
-       # Force cmake to search again, as the cached library doesn't work
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV2} CACHE)
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
-       
-       message(FATAL_ERROR "\n${ERRORLOG1}\n\n${ERRORLOG2}\n\n"
-               "!! No suitable version of ${LIBRARY_NAME} found.\n"
-               "   Maybe you don't have the right (32 vs.64 bit) architecture 
installed?\n\n"
-               "   Tried ${lib_current} and ${LIBRARY_FILE}\n"
-               "   Using compiler ${CMAKE_CXX_COMPILER} 
${CMAKE_CXX_FLAGS}\n\n\n")
-       
-endfunction(check_link_library)
-
-function(force_recheck_library LIBRARY_NAME)
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV1} CACHE)
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
-       unset(CHECK_${LIBRARY_NAME}_LINK CACHE)
-endfunction()
diff -Nru innoextract-1.8/cmake/CXXVersionCheck.cmake 
innoextract-1.9/cmake/CXXVersionCheck.cmake
--- innoextract-1.8/cmake/CXXVersionCheck.cmake 2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/cmake/CXXVersionCheck.cmake 2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2013-2019 Daniel Scharrer
+# Copyright (C) 2013-2020 Daniel Scharrer
 #
 # This software is provided 'as-is', without any express or implied
 # warranty.  In no event will the author(s) be held liable for any damages
@@ -21,7 +21,8 @@
 include(CompileCheck)
 
 set(CXX_VERSION 2003)
-set(CXX_CHECK_DIR "${CMAKE_CURRENT_LIST_DIR}/check")
+get_filename_component(CXX_CHECK_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(CXX_CHECK_DIR "${CXX_CHECK_DIR}/check")
 
 function(enable_cxx_version version)
        
diff -Nru innoextract-1.8/cmake/VersionScript.cmake 
innoextract-1.9/cmake/VersionScript.cmake
--- innoextract-1.8/cmake/VersionScript.cmake   2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/cmake/VersionScript.cmake   2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2016 Daniel Scharrer
+# Copyright (C) 2011-2020 Daniel Scharrer
 #
 # This software is provided 'as-is', without any express or implied
 # warranty.  In no event will the author(s) be held liable for any damages
@@ -26,102 +26,30 @@
        message(SEND_ERROR "Invalid arguments.")
 endif()
 
+get_filename_component(VERSION_SCRIPT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include("${VERSION_SCRIPT_DIR}/VersionString.cmake")
+
 # configure_file doesn't handle newlines correctly - pre-escape variables
-function(escape_var VAR)
+macro(_version_escape var string)
        # Escape the escape character and quotes
-       string(REGEX REPLACE "([\\\\\"])" "\\\\\\1" escaped "${${VAR}}")
+       string(REGEX REPLACE "([\\\\\"])" "\\\\\\1" ${var} "${string}")
        # Pull newlines out of string
-       string(REGEX REPLACE "\n" "\\\\n\"\n\t\"" escaped "${escaped}")
-       set(${VAR} "${escaped}" PARENT_SCOPE)
-endfunction(escape_var)
+       string(REGEX REPLACE "\n" "\\\\n\"\n\t\"" ${var} "${${var}}")
+endmacro()
 
 set(var "")
 foreach(arg IN LISTS VERSION_SOURCES)
-       
        if(var STREQUAL "")
                set(var ${arg})
        else()
-               
-               file(READ "${arg}" ${var})
-               string(STRIP "${${var}}" ${var})
-               string(REGEX REPLACE "\r\n" "\n" ${var} "${${var}}")
-               string(REGEX REPLACE "\r" "\n" ${var} "${${var}}")
-               
-               # Split the version file into lines.
-               string(REGEX MATCHALL "[^\r\n]+" lines "${${var}}")
-               set(${var}_COUNT 0)
-               foreach(line IN LISTS lines)
-                       
-                       set(${var}_${${var}_COUNT} "${line}")
-                       escape_var(${var}_${${var}_COUNT})
-                       
-                       # Find the first and last spaces
-                       string(STRIP "${line}" line)
-                       string(LENGTH "${line}" line_length)
-                       set(first_space -1)
-                       set(last_space ${line_length})
-                       foreach(i RANGE ${line_length})
-                               if(i LESS line_length)
-                                       string(SUBSTRING "${line}" ${i} 1 
line_char)
-                                       if(line_char STREQUAL " ")
-                                               set(last_space ${i})
-                                               if(first_space EQUAL -1)
-                                                       set(first_space ${i})
-                                               endif()
-                                       endif()
-                               endif()
-                       endforeach()
-                       
-                       if(first_space GREATER -1)
-                               
-                               # Get everything before the first space
-                               string(SUBSTRING "${line}" 0 ${first_space} 
line_name)
-                               string(STRIP "${line_name}" 
${var}_${${var}_COUNT}_SHORTNAME)
-                               escape_var(${var}_${${var}_COUNT}_SHORTNAME)
-                               
-                               # Get everything after the first space
-                               math(EXPR num_length "${line_length} - 
${first_space}")
-                               string(SUBSTRING "${line}" ${first_space} 
${num_length} line_num)
-                               string(STRIP "${line_num}" 
${var}_${${var}_COUNT}_STRING)
-                               escape_var(${var}_${${var}_COUNT}_STRING)
-                               
-                       endif()
-                       
-                       if(line MATCHES " ([0-9]\\.[^ ]* \\+ )?[^ ]*$")
-                               string(REGEX REPLACE " (([0-9]\\.[^ ]* \\+ )?[^ 
]*)$" ""
-                                      ${var}_${${var}_COUNT}_NAME "${line}")
-                               string(LENGTH ${${var}_${${var}_COUNT}_NAME} 
begin)
-                               math(EXPR begin "${begin} + 1")
-                               math(EXPR length "${line_length} - ${begin}")
-                               string(SUBSTRING "${line}" "${begin}" 
"${length}" ${var}_${${var}_COUNT}_NUMBER)
-                               
-                       else()
-                               set(${var}_${${var}_COUNT}_NAME "${line}")
-                               set(${var}_${${var}_COUNT}_NUMBER)
-                       endif()
-                       escape_var(${var}_${${var}_COUNT}_NAME)
-                       escape_var(${var}_${${var}_COUNT}_NUMBER)
-                       
-                       math(EXPR ${var}_COUNT "${${var}_COUNT} + 1")
-               endforeach()
-               
-               string(REGEX REPLACE "\n\n.*$" "" ${var}_HEAD "${${var}}")
-               string(STRIP "${${var}_HEAD}" ${var}_HEAD)
-               string(REGEX MATCH "\n\n.*" ${var}_TAIL "${${var}}")
-               string(STRIP "${${var}_TAIL}" ${var}_TAIL)
-               
-               escape_var(${var})
-               escape_var(${var}_HEAD)
-               escape_var(${var}_TAIL)
-               
+               parse_version_file(${var} "${arg}" ON)
                set(var "")
        endif()
-       
 endforeach()
 
 # Check for a git directory and fill in the git commit hash if one exists.
 unset(GIT_COMMIT)
-if(EXISTS "${GIT_DIR}")
+if(NOT GIT_DIR STREQUAL "")
        
        unset(git_head)
        
diff -Nru innoextract-1.8/cmake/VersionString.cmake 
innoextract-1.9/cmake/VersionString.cmake
--- innoextract-1.8/cmake/VersionString.cmake   2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/cmake/VersionString.cmake   2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2016 Daniel Scharrer
+# Copyright (C) 2011-2020 Daniel Scharrer
 #
 # This software is provided 'as-is', without any express or implied
 # warranty.  In no event will the author(s) be held liable for any damages
@@ -17,8 +17,8 @@
 #    misrepresented as being the original software.
 # 3. This notice may not be removed or altered from any source distribution.
 
-get_filename_component(VERSION_STRING_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-set(VERSION_STRING_SCRIPT "${VERSION_STRING_DIR}/VersionScript.cmake")
+get_filename_component(VERSION_SCRIPT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(VERSION_STRING_SCRIPT "${VERSION_SCRIPT_DIR}/VersionScript.cmake")
 
 # Create a rule to generate a version string at compile time.
 #
@@ -33,11 +33,20 @@
 # for each variable ${var}
 # - ${var}: The contents of the associated file
 # - ${var}_COUNT: Number of lines in the associated file
-# - ${var}_${i}: The ${i}-th line of the associated file
-# - ${var}_${i}_SHORTNAME: The first component of the ${i}-th line of the 
associated file
-# - ${var}_${i}_STRING: Everything except the first component of the ${i}-th 
line of the associated file
-# - ${var}_${i}_NAME: Everything except the last component of the ${i}-th line 
of the associated file
-# - ${var}_${i}_NUMBER: The last component of the ${i}-th line of the 
associated file
+# - For each line ${i}:
+#   - ${var}_${i}: The ${i}-th line of the associated file
+#    - ${var}_${i}_PREFIX: The first component in the line
+#    - ${var}_${i}_LINE: Everything except the first component of the line
+#    - ${var}_${i}_NAME: Everything except the last component of the line
+#    - ${var}_${i}_STRING: The last component (excluding optional suffix) of 
the line
+#    - ${var}_${i}_SUFFIX: Suffix (seperated by " + ") of the line
+#    - ${var}_${i}_MAJOR: First version component in ${var}_${i}_STRING
+#    - ${var}_${i}_MINOR: Second version component in ${var}_${i}_STRING
+#    - ${var}_${i}_PATCH: Third version component in ${var}_${i}_STRING
+#    - ${var}_${i}_BUILD: Fourth version component in ${var}_${i}_STRING
+#    - ${var}_${i}_NUMBER: Reassembled verion components
+#    - ${var}_${i}_PRERELEASE: If the version indicates a prerelease build
+#    - ${var}_${i}_PRIVATE: If the version indicates a private build
 # - ${var}_HEAD: The first paragraph of the associated file
 # - ${var}_TAIL: The remaining paragraphs of the associated file
 #
@@ -92,6 +101,8 @@
                if(EXISTS "${abs_git_dir}/logs/HEAD")
                        list(APPEND dependencies "${abs_git_dir}/logs/HEAD")
                endif()
+       else()
+               set(abs_git_dir "")
        endif()
        
        add_custom_command(
@@ -106,6 +117,8 @@
                        "-DGIT_COMMAND=${GIT_COMMAND}"
                        ${defines}
                        -P "${VERSION_STRING_SCRIPT}"
+               COMMAND
+                       ${CMAKE_COMMAND} -E touch "${abs_dst}"
                MAIN_DEPENDENCY
                        "${abs_src}"
                DEPENDS
@@ -114,4 +127,198 @@
                VERBATIM
        )
        
-endfunction(version_file)
+endfunction()
+
+macro(_version_escape var string)
+       set(${var} "${string}")
+endmacro()
+
+macro(_define_version_var_nostrip suffix contents)
+       _version_escape(${var}_${suffix} "${${contents}}")
+       list(APPEND variables ${var}_${suffix})
+endmacro()
+
+macro(_define_version_var suffix contents)
+       string(STRIP "${${contents}}" tmp)
+       _define_version_var_nostrip(${suffix} tmp)
+endmacro()
+
+macro(_define_version_line_var_nostrip suffix contents)
+       _define_version_var_nostrip(${i}_${suffix} ${contents})
+       if(line_name)
+               set(${line_name}_${suffix} "${${var}_${i}_${suffix}}")
+               list(APPEND variables ${line_name}_${suffix})
+       endif()
+endmacro()
+
+macro(_define_version_line_var suffix contents)
+       string(STRIP "${${contents}}" tmp)
+       _define_version_line_var_nostrip(${suffix} tmp)
+endmacro()
+
+function(parse_version_file names file)
+       
+       list(GET names 0 var)
+       
+       list(LENGTH names names_count)
+       
+       set(variables)
+       
+       file(READ "${file}" contents)
+       string(STRIP "${contents}" contents)
+       string(REGEX REPLACE "\r\n" "\n" contents "${contents}")
+       string(REGEX REPLACE "\r" "\n" contents "${contents}")
+       _version_escape(${var} "${contents}")
+       list(APPEND variables ${var})
+       
+       # Split the version file into lines.
+       string(REGEX MATCHALL "[^\r\n]+" lines "${contents}")
+       set(i 0)
+       foreach(line IN LISTS lines)
+               
+               if(i LESS names_count)
+                       list(GET names ${i} line_name)
+               else()
+                       set(line_name)
+               endif()
+               
+               _define_version_var(${i} line)
+               
+               if(line MATCHES "^([^ ]*) (.*)$")
+                       set(prefix "${CMAKE_MATCH_1}")
+                       set(notprefix "${CMAKE_MATCH_2}")
+                       _define_version_line_var(PREFIX prefix)
+                       _define_version_line_var(LINE notprefix)
+               else()
+                       _define_version_line_var(PREFIX line)
+               endif()
+               
+               if(line MATCHES "^(.*[^+] )?([^ ]+)( \\+ [^ ]+)?$")
+                       
+                       set(name "${CMAKE_MATCH_1}")
+                       set(string "${CMAKE_MATCH_2}")
+                       set(suffix "${CMAKE_MATCH_3}")
+                       
+                       _define_version_line_var(NAME name)
+                       _define_version_line_var(STRING string)
+                       _define_version_line_var_nostrip(SUFFIX suffix)
+                       
+                       if(i GREATER 0 AND line_name)
+                               set(${line_name} "${${var}_${i}_STRING}")
+                               list(APPEND variables ${line_name})
+                       endif()
+                       
+                       if(string MATCHES 
"^([0-9]+)(\\.([0-9]+)(\\.([0-9]+)(\\.([0-9]+))?)?)?(.*)?$")
+                               
+                               set(major "${CMAKE_MATCH_1}")
+                               set(minor "${CMAKE_MATCH_3}")
+                               set(patch "${CMAKE_MATCH_5}")
+                               set(build "${CMAKE_MATCH_7}")
+                               set(release "${CMAKE_MATCH_8}")
+                               
+                               set(error 0)
+                               set(newpatch)
+                               set(newbuild)
+                               set(prerelease 0)
+                               set(private 0)
+                               if(release MATCHES 
"^\\-dev\\-([2-9][0-9][0-9][0-9]+)\\-([0-9][0-9])\\-([0-9][0-9])$")
+                                       set(prerelease 1)
+                                       set(newpatch "${CMAKE_MATCH_1}")
+                                       set(newbuild 
"${CMAKE_MATCH_2}${CMAKE_MATCH_3}")
+                               elseif(release MATCHES "^\\-rc([0-9]+)$")
+                                       set(prerelease 1)
+                                       set(newpatch "9999")
+                                       set(newbuild "${CMAKE_MATCH_1}")
+                               elseif(release MATCHES "^\\-r([0-9]+)$")
+                                       if(build STREQUAL "")
+                                               set(build "${CMAKE_MATCH_1}")
+                                       else()
+                                               set(error 1)
+                                       endif()
+                               elseif(release OR suffix)
+                                       set(prerelease 1)
+                                       set(private 1)
+                                       set(newpatch 9999)
+                                       set(newbuild 9999)
+                               endif()
+                               
+                               foreach(component IN ITEMS major minor patch 
build newpatch newbuild)
+                                       string(REGEX REPLACE "^0+" "" 
${component} "${${component}}")
+                                       if(NOT ${component})
+                                               set(${component} 0)
+                                       endif()
+                               endforeach()
+                               
+                               if(newpatch)
+                                       set(prerelease 1)
+                                       if(build)
+                                               set(error 1)
+                                       else()
+                                               if(patch)
+                                                       if(newpatch EQUAL 9999)
+                                                               math(EXPR patch 
"${patch} - 1")
+                                                               if(newbuild 
EQUAL 9999)
+                                                                       
set(build 9999)
+                                                               else()
+                                                                       
math(EXPR build "${newbuild} + 1000")
+                                                               endif()
+                                                       else()
+                                                               set(error 1)
+                                                       endif()
+                                               else()
+                                                       if(minor)
+                                                               math(EXPR minor 
"${minor} - 1")
+                                                       else()
+                                                               if(major)
+                                                                       
math(EXPR major "${major} - 1")
+                                                               else()
+                                                                       
set(error 1)
+                                                               endif()
+                                                               set(minor 9999)
+                                                       endif()
+                                                       set(patch "${newpatch}")
+                                                       set(build "${newbuild}")
+                                               endif()
+                                       endif()
+                               endif()
+                               
+                               set(number "${major}")
+                               if(minor OR patch OR build)
+                                       set(number "${number}.${minor}")
+                                       if(patch OR build)
+                                               set(number "${number}.${patch}")
+                                               if(build)
+                                                       set(number 
"${number}.${build}")
+                                               endif()
+                                       endif()
+                               endif()
+                               
+                               _define_version_line_var(MAJOR major)
+                               _define_version_line_var(MINOR minor)
+                               _define_version_line_var(PATCH patch)
+                               _define_version_line_var(BUILD build)
+                               _define_version_line_var(PRERELEASE prerelease)
+                               _define_version_line_var(PRIVATE private)
+                               _define_version_line_var(NUMBER number)
+                               _define_version_line_var(ERROR error)
+                               
+                       endif()
+                       
+               endif()
+               
+               math(EXPR i "${i} + 1")
+       endforeach()
+       
+       set(${var}_COUNT ${i} PARENT_SCOPE)
+       
+       string(REGEX REPLACE "\n\n.*$" "" head "${contents}")
+       _define_version_var(HEAD head)
+       
+       string(REGEX MATCH "\n\n.*" tail "${contents}")
+       _define_version_var(TAIL tail)
+       
+       foreach(var IN LISTS variables)
+               set(${var} "${${var}}" PARENT_SCOPE)
+       endforeach()
+       
+endfunction()
diff -Nru innoextract-1.8/CMakeLists.txt innoextract-1.9/CMakeLists.txt
--- innoextract-1.8/CMakeLists.txt      2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/CMakeLists.txt      2020-08-09 20:48:04.000000000 +0200
@@ -1,13 +1,11 @@
-project(innoextract)
-
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8...3.15)
 
-if(CMAKE_VERSION VERSION_GREATER 3.15)
-       cmake_policy(VERSION 3.15)
-else()
+if(CMAKE_VERSION VERSION_LESS 3.12)
        cmake_policy(VERSION ${CMAKE_VERSION})
 endif()
 
+project(innoextract)
+
 
 # Define configuration options
 
@@ -135,21 +133,6 @@
        add_ldflag("-static-libgcc")
 endif()
 
-# Force re-checking libraries if the compiler or compiler flags change
-if((NOT LAST_CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS)
-   OR (NOT LAST_CMAKE_CXX_COMPILER STREQUAL CMAKE_CXX_COMPILER))
-       force_recheck_library(LZMA)
-       force_recheck_library(Boost)
-       force_recheck_library(ZLIB)
-       force_recheck_library(BZip2)
-       force_recheck_library(iconv)
-       unset(Boost_INCLUDE_DIR CACHE)
-       set(LAST_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE INTERNAL
-           "The last C++ compiler flags")
-       set(LAST_CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}" CACHE INTERNAL
-           "The last C++ compiler")
-endif()
-
 unset(LIBRARIES)
 
 if(USE_ARC4)
@@ -158,7 +141,6 @@
 
 if(USE_LZMA)
        find_package(LZMA REQUIRED)
-       check_link_library(LZMA LZMA_LIBRARIES)
        list(APPEND LIBRARIES ${LZMA_LIBRARIES})
        include_directories(SYSTEM ${LZMA_INCLUDE_DIR})
        add_definitions(${LZMA_DEFINITIONS})
@@ -176,7 +158,6 @@
        system
        program_options
 )
-check_link_library(Boost Boost_LIBRARIES)
 list(APPEND LIBRARIES ${Boost_LIBRARIES})
 link_directories(${Boost_LIBRARY_DIRS})
 include_directories(SYSTEM ${Boost_INCLUDE_DIR})
@@ -210,7 +191,6 @@
                                break()
                        endif()
                endforeach()
-               check_link_library(${Lib} ${LIB}_LIBRARIES)
                list(APPEND LIBRARIES ${${LIB}_LIBRARIES})
        endforeach()
 endif()
@@ -227,7 +207,6 @@
        endif()
        find_package(iconv ${ICONV_REQUIRED})
        if(ICONV_FOUND)
-               check_link_library(iconv iconv_LIBRARIES)
                list(APPEND LIBRARIES ${iconv_LIBRARIES})
                include_directories(SYSTEM ${iconv_INCLUDE_DIR})
                add_definitions(${iconv_DEFINITIONS})
@@ -337,6 +316,11 @@
        
 endif()
 
+if($ENV{PORTAGE_REPO_NAME} MATCHES "gentoo")
+       # Meh
+       unset(LIBRARIES)
+endif()
+
 
 # All sources:
 
@@ -539,3 +523,12 @@
        1                             "builtin"
 )
 message("")
+
+if(DEVELOPER)
+       file(READ "README.md" readme)
+       parse_version_file("VERSION" "VERSION")
+       string(REPLACE "${VERSION_2}" "" readme_without_version "${readme}")
+       if(readme_without_version STREQUAL readme)
+               message(WARNING "Could not find '${VERSION_2}' in README.md.")
+       endif()
+endif()
diff -Nru innoextract-1.8/debian/changelog innoextract-1.9/debian/changelog
--- innoextract-1.8/debian/changelog    2020-06-07 22:00:19.000000000 +0200
+++ innoextract-1.9/debian/changelog    2022-11-07 17:08:30.000000000 +0100
@@ -1,3 +1,13 @@
+innoextract (1.9-0.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * New upstream release. (Closes: #1018828)
+  * debian/copyright: Update years.
+  * debian/patches: Remove the last patch.
+  * debian/watch: Update for the latest github changes.
+
+ -- Anatoliy Gunya <csm.su...@gmail.com>  Mon, 07 Nov 2022 19:08:30 +0300
+
 innoextract (1.8-1.2) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru innoextract-1.8/debian/copyright innoextract-1.9/debian/copyright
--- innoextract-1.8/debian/copyright    2020-01-15 16:30:07.000000000 +0100
+++ innoextract-1.9/debian/copyright    2022-11-07 17:08:30.000000000 +0100
@@ -3,11 +3,12 @@
 Source: https://github.com/dscharrer/InnoExtract 
 
 Files: *
-Copyright: Copyright 2011-2012 Daniel Scharrer <dan...@constexpr.org>
+Copyright: 2011-2020 Daniel Scharrer <dan...@constexpr.org>
 License: Zlib
 
 Files: cmake/cpplint.py
-Copyright: 2009 Google Inc.
+Copyright: 2011-2018 Daniel Scharrer
+           2009 Google Inc.
 License: BSD-3-clause
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
@@ -17,7 +18,7 @@
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of contributors
+ 3. Neither the name of of Google Inc. nor the names of its contributors
     may be used to endorse or promote products derived from this software
     without specific prior written permission.
  .
diff -Nru 
innoextract-1.8/debian/patches/b47f46102bccf1d813ca159230029b0cd820ceff.patch 
innoextract-1.9/debian/patches/b47f46102bccf1d813ca159230029b0cd820ceff.patch
--- 
innoextract-1.8/debian/patches/b47f46102bccf1d813ca159230029b0cd820ceff.patch   
    2020-06-07 21:59:01.000000000 +0200
+++ 
innoextract-1.9/debian/patches/b47f46102bccf1d813ca159230029b0cd820ceff.patch   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,158 +0,0 @@
-From b47f46102bccf1d813ca159230029b0cd820ceff Mon Sep 17 00:00:00 2001
-From: Daniel Scharrer <dan...@constexpr.org>
-Date: Mon, 23 Sep 2019 00:00:52 +0200
-Subject: [PATCH] CMake: Remove library link checks
-
-This was needed with older CMake versions to work around CMake searching
-under lib with -m32 instead of under lib32 for platforms where lib
-contains 64-bit binaries. This has since been fixed in CMake and users
-of older CMake versions can add the lib32 directories to
-CMAKE_LIBRARY_PATH to work around the issue on their end.
-
-With newer CMake and Boost versions these checks fail because the
-boost-config.cmake files shipped with Boost use imported targets instead
-of library paths and try_compile does not add these imported targets to
-the generated project.
-
-See: https://gitlab.kitware.com/cmake/cmake/issues/11260
----
- CMakeLists.txt           |  4 --
- cmake/CompileCheck.cmake | 88 ----------------------------------------
- 2 files changed, 92 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index b98e59d..8aba97c 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -158,7 +158,6 @@ endif()
- 
- if(USE_LZMA)
-       find_package(LZMA REQUIRED)
--      check_link_library(LZMA LZMA_LIBRARIES)
-       list(APPEND LIBRARIES ${LZMA_LIBRARIES})
-       include_directories(SYSTEM ${LZMA_INCLUDE_DIR})
-       add_definitions(${LZMA_DEFINITIONS})
-@@ -176,7 +175,6 @@ find_package(Boost REQUIRED COMPONENTS
-       system
-       program_options
- )
--check_link_library(Boost Boost_LIBRARIES)
- list(APPEND LIBRARIES ${Boost_LIBRARIES})
- link_directories(${Boost_LIBRARY_DIRS})
- include_directories(SYSTEM ${Boost_INCLUDE_DIR})
-@@ -210,7 +208,6 @@ if(Boost_HAS_STATIC_LIBS)
-                               break()
-                       endif()
-               endforeach()
--              check_link_library(${Lib} ${LIB}_LIBRARIES)
-               list(APPEND LIBRARIES ${${LIB}_LIBRARIES})
-       endforeach()
- endif()
-@@ -227,7 +224,6 @@ elseif(NOT WITH_CONV OR WITH_CONV STREQUAL "iconv")
-       endif()
-       find_package(iconv ${ICONV_REQUIRED})
-       if(ICONV_FOUND)
--              check_link_library(iconv iconv_LIBRARIES)
-               list(APPEND LIBRARIES ${iconv_LIBRARIES})
-               include_directories(SYSTEM ${iconv_INCLUDE_DIR})
-               add_definitions(${iconv_DEFINITIONS})
-diff --git a/cmake/CompileCheck.cmake b/cmake/CompileCheck.cmake
-index 1e88599..4a72d38 100644
---- a/cmake/CompileCheck.cmake
-+++ b/cmake/CompileCheck.cmake
-@@ -192,95 +192,7 @@ function(add_ldflag FLAG)
-       
- endfunction(add_ldflag)
- 
--function(try_link_library LIBRARY_NAME LIBRARY_FILE ERROR_VAR)
--      # See if we can link a simple program with the library using the 
configured c++ compiler
--      set(link_test_file "${CMAKE_CURRENT_BINARY_DIR}/link_test.cpp")
--      file(WRITE ${link_test_file} "int main(){}\n")
--      if(CMAKE_THREAD_LIBS_INIT)
--              list(APPEND LIBRARY_FILE "${CMAKE_THREAD_LIBS_INIT}")
--      endif()
--      try_compile(
--              CHECK_${LIBRARY_NAME}_LINK "${PROJECT_BINARY_DIR}" 
"${link_test_file}"
--              CMAKE_FLAGS "-DLINK_LIBRARIES=${LIBRARY_FILE}"
--                          "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
--                          "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}"
--                          
"-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}"
--                          
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
--              OUTPUT_VARIABLE ERRORLOG
--      )
--      set(${ERROR_VAR} "${ERRORLOG}" PARENT_SCOPE)
--endfunction(try_link_library)
--
--##############################################################################
--# Check that a a library actually works for the current configuration
--# This is neede because CMake prefers /usr/lib over /usr/lib32 for -m32 builds
--# See https://public.kitware.com/Bug/view.php?id=11260
--function(check_link_library LIBRARY_NAME LIBRARY_VARIABLE)
--      
--      if(MSVC)
--              # The main point of this is to work around CMakes ignorance of 
lib32.
--              # This doesn't really apply for systems that don't use a 
unix-like library dir layout.
--              return()
--      endif()
--      
--      set(lib_current "${${LIBRARY_VARIABLE}}")
--      set(found_var "ARX_CLL_${LIBRARY_NAME}_FOUND")
--      set(working_var "ARX_CLL_${LIBRARY_NAME}_WORKING")
--      
--      if(CHECK_${LIBRARY_NAME}_LINK)
--              set(lib_found "${${found_var}}")
--              set(lib_working "${${working_var}}")
--              if((lib_current STREQUAL lib_found) OR (lib_current STREQUAL 
lib_working))
--                      set("${LIBRARY_VARIABLE}" "${lib_working}" PARENT_SCOPE)
--                      return()
--              endif()
--      endif()
--      
--      set("${found_var}" "${lib_current}" CACHE INTERNAL "...")
--      
--      if(NOT lib_current STREQUAL "")
--              message(STATUS "Checking ${LIBRARY_NAME}: ${lib_current}")
--      endif()
--      
--      # Check if we can link to the full path found by find_package
--      try_link_library(${LIBRARY_NAME} "${lib_current}" ERRORLOG1)
--      
--      if(CHECK_${LIBRARY_NAME}_LINK)
--              set("${working_var}" "${lib_current}" CACHE INTERNAL "...")
--              return()
--      endif()
--      
--      # Check if the linker is smarter than cmake and try to link with only 
the library name
--      string(REGEX REPLACE "(^|;)[^;]*/lib([^;/]*)\\.so" "\\1-l\\2"
--             LIBRARY_FILE "${lib_current}")
--      
--      if(NOT LIBRARY_FILE STREQUAL lib_current)
--              
--              try_link_library(${LIBRARY_NAME} "${LIBRARY_FILE}" ERRORLOG2)
--              
--              if(CHECK_${LIBRARY_NAME}_LINK)
--                      message(STATUS " -> using ${LIBRARY_FILE} instead")
--                      set("${LIBRARY_VARIABLE}" "${LIBRARY_FILE}" 
PARENT_SCOPE)
--                      set("${working_var}" "${LIBRARY_FILE}" CACHE INTERNAL 
"...")
--                      return()
--              endif()
--              
--      endif()
--      
--      # Force cmake to search again, as the cached library doesn't work
--      unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV2} CACHE)
--      unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
--      
--      message(FATAL_ERROR "\n${ERRORLOG1}\n\n${ERRORLOG2}\n\n"
--              "!! No suitable version of ${LIBRARY_NAME} found.\n"
--              "   Maybe you don't have the right (32 vs.64 bit) architecture 
installed?\n\n"
--              "   Tried ${lib_current} and ${LIBRARY_FILE}\n"
--              "   Using compiler ${CMAKE_CXX_COMPILER} 
${CMAKE_CXX_FLAGS}\n\n\n")
--      
--endfunction(check_link_library)
--
- function(force_recheck_library LIBRARY_NAME)
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV1} CACHE)
-       unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
--      unset(CHECK_${LIBRARY_NAME}_LINK CACHE)
- endfunction()
diff -Nru innoextract-1.8/debian/patches/series 
innoextract-1.9/debian/patches/series
--- innoextract-1.8/debian/patches/series       2020-06-07 21:59:07.000000000 
+0200
+++ innoextract-1.9/debian/patches/series       1970-01-01 01:00:00.000000000 
+0100
@@ -1 +0,0 @@
-b47f46102bccf1d813ca159230029b0cd820ceff.patch
diff -Nru innoextract-1.8/debian/watch innoextract-1.9/debian/watch
--- innoextract-1.8/debian/watch        2020-01-15 16:30:07.000000000 +0100
+++ innoextract-1.9/debian/watch        2022-11-07 16:38:35.000000000 +0100
@@ -1,3 +1,4 @@
-version=3
-opts=pgpsigurlmangle=s/$/.sig/ \
-       https://github.com/dscharrer/innoextract/releases 
.*?/(?:\d\S*)/innoextract-(\d\S*)\.tar\.gz
+version=4
+opts="downloadurlmangle=s/archive\/refs\/tags\/(.*)\.tar\.gz/releases\/download\/$1\/@PACKAGE@-$1\.tar\.gz/,
 \
+pgpsigurlmangle=s/$/\.sig/" \
+https://github.com/dscharrer/@PACKAGE@/tags 
/dscharrer/@PACKAGE@/archive/refs/tags/(.*)\.tar\.gz
diff -Nru innoextract-1.8/doc/innoextract.1.in 
innoextract-1.9/doc/innoextract.1.in
--- innoextract-1.8/doc/innoextract.1.in        2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/doc/innoextract.1.in        2020-08-09 20:48:04.000000000 
+0200
@@ -1,6 +1,6 @@
 .\" Manpage for innoextract.
 .\" Contact dan...@constexpr.org to correct errors or typos.
-.TH innoextract 1 "@CHANGELOG_0_NUMBER@" "@VERSION_0_NUMBER@@GIT_SUFFIX_7@"
+.TH innoextract 1 "@CHANGELOG_0_STRING@" 
"@VERSION_0_STRING@@VERSION_SUFFIX@@GIT_SUFFIX_7@"
 .SH NAME
 innoextract - tool to extract installers created by Inno Setup
 .SH SYNOPSIS
@@ -167,7 +167,7 @@
 
 Extracting these RAR archives requires rar, unrar or lsar/unar command-line 
utilities to be in the PATH.
 
-The \fB\-\-list\fP, \fB\-\-test\fP, \fB\-\-extract\fP and 
\fB\-\-output\-dir\fP options are passed along to unrar/unar, but other options 
may be ignored for the RAR files. For multi-part RAR archives, the 
\fB\-\-test\fP requires a writable output directory for temporary files.
+The \fB\-\-list\fP, \fB\-\-test\fP, \fB\-\-extract\fP and 
\fB\-\-output\-dir\fP options are passed along to unrar/unar, but other options 
may be ignored for the RAR files. For multi-part RAR archives, the 
\fB\-\-test\fP requires a writable output directory for temporary files which 
can be specified using the \fB\-\-output\-dir\fP option. If the output 
directory does not exist it will be created and then removed after testing is 
done. Parent directories are not created. Temporary files created inside the 
directory are always removed.
 
 Note that is option is geared towards GOG.com installers. Other installers may 
come be bundled with different extraneous \fI.bin\fP which this option might 
not be able to handle.
 
@@ -358,12 +358,12 @@
 \fBcabextract\fP(1), \fBunar\fP(1), \fBunrar\fP(1), \fBunshield\fP(1), 
\fBtzset\fP(3)
 .SH BUGS
 .PP
-Please report bugs to http://innoextract.constexpr.org/issues.
+Please report bugs to https://innoextract.constexpr.org/issues.
 .SH CREDITS
 .PP
 \fBinnoextract\fP is distributed under the zlib/libpng license.  See the 
LICENSE file for details.
 .PP
-A website is available at http://constexpr.org/innoextract/.
+A website is available at https://constexpr.org/innoextract/.
 .PP
 This program uses the excellent lzma/xz decompression library written by Lasse 
Collin.
 .SH AUTHOR
diff -Nru innoextract-1.8/LICENSE innoextract-1.9/LICENSE
--- innoextract-1.8/LICENSE     2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/LICENSE     2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 
-Copyright (C) 2011-2019 Daniel Scharrer <dan...@constexpr.org>
+Copyright (C) 2011-2020 Daniel Scharrer <dan...@constexpr.org>
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author(s) be held liable for any damages
diff -Nru innoextract-1.8/README.md innoextract-1.9/README.md
--- innoextract-1.8/README.md   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/README.md   2020-08-09 20:48:04.000000000 +0200
@@ -1,33 +1,33 @@
 
 # innoextract - A tool to unpack installers created by Inno Setup
 
-[Inno Setup](http://www.jrsoftware.org/isinfo.php) is a tool to create 
installers for Microsoft Windows applications. innoextract allows to extract 
such installers under non-Windows systems without running the actual installer 
using wine. innoextract currently supports installers created by Inno Setup 
1.2.10 to 5.6.0.
+[Inno Setup](https://jrsoftware.org/isinfo.php) is a tool to create installers 
for Microsoft Windows applications. innoextract allows to extract such 
installers under non-Windows systems without running the actual installer using 
wine. innoextract currently supports installers created by Inno Setup 1.2.10 to 
6.0.5.
 
 In addition to standard Inno Setup installers, innoextract also supports some 
modified Inno Setup variants including Martijn Laan's My Inno Setup Extensions 
3.0.6.1 as well as GOG.com's Inno Setup-based game installers.
 
 innoextract is available under the ZLIB license - see the LICENSE file.
 
-See the website for [Linux 
packages](http://constexpr.org/innoextract/#packages).
+See the website for [Linux 
packages](https://constexpr.org/innoextract/#packages).
 
 ## Contact
 
-[Website](http://constexpr.org/innoextract/)
+[Website](https://constexpr.org/innoextract/)
 
-Author: [Daniel Scharrer](http://constexpr.org/)
+Author: [Daniel Scharrer](https://constexpr.org/)
 
 ## Dependencies
 
-* **[Boost](http://www.boost.org/) 1.37** or newer
-* **liblzma** from [xz-utils](http://tukaani.org/xz/) *(optional)*
-* **iconv** (*optional*, either as part of the system libc, as is the case 
with [glibc](http://www.gnu.org/software/libc/) and 
[uClibc](http://www.uclibc.org/), or as a separate 
[libiconv](http://www.gnu.org/software/libiconv/))
+* **[Boost](https://www.boost.org/) 1.37** or newer
+* **liblzma** from [xz-utils](https://tukaani.org/xz/) *(optional)*
+* **iconv** (*optional*, either as part of the system libc, as is the case 
with [glibc](https://www.gnu.org/software/libc/) and 
[uClibc](https://uclibc.org/), or as a separate 
[libiconv](https://www.gnu.org/software/libiconv/))
 
 For Boost you will need the headers as well as the `iostreams`, `filesystem`, 
`date_time`, `system` and `program_options` libraries. Older Boost version may 
work but are not actively supported. The boost `iostreams` library needs to be 
build with zlib and bzip2 support.
 
 While innoextract can be built without liblzma by manually setting 
`-DUSE_LZMA=OFF`, it is highly recommended and you won't be able to extract 
most installers created by newer Inno Setup versions without it.
 
-To build innoextract you will also need **[CMake](http://cmake.org/) 2.8** and 
a working C++ compiler, as well as the development headers for liblzma and 
boost.
+To build innoextract you will also need **[CMake](https://cmake.org/) 2.8** 
and a working C++ compiler, as well as the development headers for liblzma and 
boost.
 
-See the Website for [operating system-specific 
instructions](http://constexpr.org/innoextract/install).
+See the Website for [operating system-specific 
instructions](https://constexpr.org/innoextract/install).
 
 ## Compile and install
 
@@ -115,10 +115,10 @@
 
 Extracting Windows installer executables created by programs other than Inno 
Setup is out of the scope of this project. Some of these can be unpacked by the 
following programs:
 
-* [cabextract](http://www.cabextract.org.uk/)
+* [cabextract](https://cabextract.org.uk/)
 
 * [unshield](https://github.com/twogood/unshield)
 
 ## Disclaimer
 
-This project is in no way associated with Inno Setup or 
[www.jrsoftware.org](http://www.jrsoftware.org/).
+This project is in no way associated with Inno Setup or 
[jrsoftware.org](https://jrsoftware.org/).
diff -Nru innoextract-1.8/src/cli/debug.cpp innoextract-1.9/src/cli/debug.cpp
--- innoextract-1.8/src/cli/debug.cpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/debug.cpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -24,9 +24,11 @@
 #include <iostream>
 
 #include <boost/foreach.hpp>
+#include <boost/filesystem/operations.hpp>
 #include <boost/range/size.hpp>
 
 #include "loader/offsets.hpp"
+
 #include "setup/component.hpp"
 #include "setup/data.hpp"
 #include "setup/delete.hpp"
@@ -45,12 +47,17 @@
 #include "setup/task.hpp"
 #include "setup/type.hpp"
 #include "setup/version.hpp"
+
 #include "stream/block.hpp"
+
+#include "util/fstream.hpp"
 #include "util/load.hpp"
 #include "util/log.hpp"
 #include "util/output.hpp"
 #include "util/time.hpp"
 
+namespace fs = boost::filesystem;
+
 void print_offsets(const loader::offsets & offsets) {
        
        std::cout << "loaded offsets:" << '\n';
@@ -599,3 +606,54 @@
        
        std::cout.setf(old, std::ios_base::boolalpha);
 }
+
+static void dump_headers(std::istream & is, const setup::version & version, 
const extract_options & o, int i) {
+       
+       std::string filename;
+       {
+               std::ostringstream oss;
+               oss << "headers" << i << ".bin";
+               filename = oss.str();
+       }
+       
+       const char * type = (i == 0 ? "primary" : "secondary");
+       if(!o.quiet) {
+               std::cout << "Dumping " << type << " setup headers to \""
+                         << color::white << filename << color::reset << "\"\n";
+       } else if(!o.silent) {
+               std::cout << filename << '\n';
+       }
+       
+       fs::path path = o.output_dir / filename;
+       util::ofstream ofs;
+       try {
+               ofs.open(path, std::ios_base::out | std::ios_base::trunc | 
std::ios_base::binary);
+               if(!ofs.is_open()) {
+                       throw std::exception();
+               }
+       } catch(...) {
+               throw std::runtime_error("Could not open output file \"" + 
path.string() + '"');
+       }
+       
+       try {
+               ofs << stream::block_reader::get(is, version)->rdbuf();
+       } catch(const std::exception & e) {
+               std::ostringstream oss;
+               oss << "Stream error while dumping " << type << " setup 
headers!\n";
+               oss << " ├─ detected setup version: " << version << '\n';
+               oss << " └─ error reason: " << e.what();
+               throw format_error(oss.str());
+       }
+       
+}
+
+void dump_headers(std::istream & is, const loader::offsets & offsets, const 
extract_options & o) {
+       
+       setup::version version;
+       is.seekg(offsets.header_offset);
+       version.load(is);
+       
+       dump_headers(is, version, o, 0);
+       dump_headers(is, version, o, 1);
+       
+}
diff -Nru innoextract-1.8/src/cli/debug.hpp innoextract-1.9/src/cli/debug.hpp
--- innoextract-1.8/src/cli/debug.hpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/debug.hpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -30,6 +30,8 @@
 
 #include "configure.hpp"
 
+#include "cli/extract.hpp"
+
 #ifdef DEBUG
 
 namespace loader { struct offsets; }
@@ -38,6 +40,8 @@
 void print_offsets(const loader::offsets & offsets);
 void print_info(const setup::info & info);
 
+void dump_headers(std::istream & is, const loader::offsets & offsets, const 
extract_options & o);
+
 #endif // DEBUG
 
 #endif // INNOEXTRACT_CLI_DEBUG_HPP
diff -Nru innoextract-1.8/src/cli/extract.cpp 
innoextract-1.9/src/cli/extract.cpp
--- innoextract-1.8/src/cli/extract.cpp 2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/extract.cpp 2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -876,6 +876,18 @@
        return processed;
 }
 
+void create_output_directory(const extract_options & o) {
+       
+       try {
+               if(!o.output_dir.empty() && !fs::exists(o.output_dir)) {
+                       fs::create_directory(o.output_dir);
+               }
+       } catch(...) {
+               throw std::runtime_error("Could not create output directory \"" 
+ o.output_dir.string() + '"');
+       }
+       
+}
+
 } // anonymous namespace
 
 void process_file(const fs::path & installer, const extract_options & o) {
@@ -904,6 +916,13 @@
        loader::offsets offsets;
        offsets.load(ifs);
        
+       #ifdef DEBUG
+       if(logger::debug) {
+               print_offsets(offsets);
+               std::cout << '\n';
+       }
+       #endif
+       
        if(o.data_version)  {
                setup::version version;
                ifs.seekg(offsets.header_offset);
@@ -916,12 +935,13 @@
                return;
        }
        
-#ifdef DEBUG
-       if(logger::debug) {
-               print_offsets(offsets);
-               std::cout << '\n';
+       #ifdef DEBUG
+       if(o.dump_headers)  {
+               create_output_directory(o);
+               dump_headers(ifs, offsets, o);
+               return;
        }
-#endif
+       #endif
        
        setup::info::entry_types entries = 0;
        if(o.list || o.test || o.extract || (o.gog_galaxy && o.list_languages)) 
{
@@ -956,6 +976,13 @@
                        process_file(headerfile, o);
                        return;
                }
+               if(offsets.found_magic) {
+                       if(offsets.header_offset == 0) {
+                               throw format_error("Could not determine 
location of setup headers!");
+                       } else {
+                               throw format_error("Could not determine setup 
data version!");
+                       }
+               }
                throw;
        } catch(const std::exception & e) {
                std::ostringstream oss;
@@ -1008,8 +1035,8 @@
        
        processed_entries processed = filter_entries(o, info);
        
-       if(o.extract && !o.output_dir.empty()) {
-               fs::create_directories(o.output_dir);
+       if(o.extract) {
+               create_output_directory(o);
        }
        
        if(o.list || o.extract) {
diff -Nru innoextract-1.8/src/cli/extract.hpp 
innoextract-1.9/src/cli/extract.hpp
--- innoextract-1.8/src/cli/extract.hpp 2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/extract.hpp 2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2019 Daniel Scharrer
+ * Copyright (C) 2014-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -57,6 +57,9 @@
        bool list_checksums; //!< Show checksum information for files
        
        bool data_version; //!< Print the data version
+       #ifdef DEBUG
+       bool dump_headers; //!< Dump setup headers
+       #endif
        bool list; //!< List files
        bool test; //!< Test files (but don't extract)
        bool extract; //!< Extract files
diff -Nru innoextract-1.8/src/cli/gog.cpp innoextract-1.9/src/cli/gog.cpp
--- innoextract-1.8/src/cli/gog.cpp     2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/gog.cpp     2020-08-09 20:48:04.000000000 +0200
@@ -253,12 +253,17 @@
 
 class temporary_directory : private boost::noncopyable {
        
+       fs::path parent;
        fs::path path;
        
 public:
        
        explicit temporary_directory(const fs::path & base) {
                try {
+                       if(!base.empty() && !fs::exists(base)) {
+                               fs::create_directory(base);
+                               parent = base;
+                       }
                        size_t tmpnum = 0;
                        std::ostringstream oss;
                        do {
@@ -266,7 +271,7 @@
                                oss << "innoextract-tmp-" << tmpnum++;
                                path = base / oss.str();
                        } while(fs::exists(path));
-                       fs::create_directories(path);
+                       fs::create_directory(path);
                } catch(...) {
                        path = fs::path();
                        throw std::runtime_error("Could not create temporary 
directory!");
@@ -277,6 +282,9 @@
                if(!path.empty()) {
                        try {
                                fs::remove_all(path);
+                               if(!parent.empty()) {
+                                       fs::remove(parent);
+                               }
                        } catch(...) {
                                log_error << "Could not remove temporary 
directory " << path << '!';
                        }
diff -Nru innoextract-1.8/src/cli/main.cpp innoextract-1.9/src/cli/main.cpp
--- innoextract-1.8/src/cli/main.cpp    2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/cli/main.cpp    2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -141,6 +141,9 @@
                ("show-password", "Show password check information")
                ("check-password", "Abort if the password is incorrect")
                ("data-version,V", "Only print the data version")
+               #ifdef DEBUG
+               ("dump-headers", "Dump decompressed setup headers")
+               #endif
        ;
        
        po::options_description modifiers("Modifiers");
@@ -175,7 +178,7 @@
                ("color,c", po::value<bool>()->implicit_value(true), 
"Enable/disable color output")
                ("progress,p", po::value<bool>()->implicit_value(true), 
"Enable/disable the progress bar")
                #ifdef DEBUG
-                       ("debug", "Output debug information")
+               ("debug", "Output debug information")
                #endif
        ;
        
@@ -374,14 +377,6 @@
                         * See https://svn.boost.org/trac/boost/ticket/8535
                         */
                        o.output_dir = i->second.as<std::string>();
-                       try {
-                               if(o.extract && !o.output_dir.empty() && 
!fs::exists(o.output_dir)) {
-                                       fs::create_directory(o.output_dir);
-                               }
-                       } catch(...) {
-                               log_error << "Could not create output directory 
" << o.output_dir;
-                               return ExitDataError;
-                       }
                }
        }
        
@@ -437,6 +432,16 @@
                }
        }
        
+       #ifdef DEBUG
+       o.dump_headers = (options.count("dump-headers") != 0);
+       if(o.dump_headers) {
+               if(explicit_action || o.data_version) {
+                       log_error << "Combining --dump-headers with other 
options is not allowed";
+                       return ExitUserError;
+               }
+       }
+       #endif
+       
        o.extract_unknown = (options.count("no-extract-unknown") == 0);
        
        const std::vector<std::string> & files = options["setup-files"]
diff -Nru innoextract-1.8/src/loader/offsets.cpp 
innoextract-1.9/src/loader/offsets.cpp
--- innoextract-1.8/src/loader/offsets.cpp      2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/loader/offsets.cpp      2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -62,7 +62,7 @@
 const int ResourceNameInstaller = 11111;
 
 const boost::uint32_t SetupLoaderHeaderOffset = 0x30;
-const boost::uint32_t SetupLoaderHeaderMagic = 0x6f6e6e49;
+const boost::uint32_t SetupLoaderHeaderMagic = 0x6f6e6e49; // "Inno"
 
 } // anonymous namespace
 
@@ -76,13 +76,21 @@
                return false;
        }
        
+       debug("found Inno magic at " << print_hex(SetupLoaderHeaderOffset));
+       
+       found_magic = true;
+       
        boost::uint32_t offset_table_offset = util::load<boost::uint32_t>(is);
        boost::uint32_t not_offset_table_offset = 
util::load<boost::uint32_t>(is);
        if(is.fail() || offset_table_offset != ~not_offset_table_offset) {
                is.clear();
+               debug("header offset checksum: " << 
print_hex(not_offset_table_offset) << " != ~"
+                                                << 
print_hex(offset_table_offset));
                return false;
        }
        
+       debug("found loader header at " << print_hex(offset_table_offset));
+       
        return load_offsets_at(is, offset_table_offset);
 }
 
@@ -94,6 +102,10 @@
                return false;
        }
        
+       debug("found loader header resource at " << print_hex(resource.offset));
+       
+       found_magic = true;
+       
        return load_offsets_at(is, resource.offset);
 }
 
@@ -101,12 +113,14 @@
        
        if(is.seekg(pos).fail()) {
                is.clear();
+               debug("could not seek to loader header");
                return false;
        }
        
        char magic[12];
        if(is.read(magic, std::streamsize(sizeof(magic))).fail()) {
                is.clear();
+               debug("could not read loader header magic");
                return false;
        }
        
@@ -115,6 +129,7 @@
                
BOOST_STATIC_ASSERT(sizeof(known_setup_loader_versions[i].magic) == 
sizeof(magic));
                if(!memcmp(magic, known_setup_loader_versions[i].magic, 
sizeof(magic))) {
                        version = known_setup_loader_versions[i].version;
+                       debug("found loader header magic version " << 
setup::version(version));
                        break;
                }
        }
@@ -131,6 +146,7 @@
                boost::uint32_t revision = checksum.load<boost::uint32_t>(is);
                if(is.fail()) {
                        is.clear();
+                       debug("could not read loader header revision");
                        return false;
                } else if(revision != 1) {
                        log_warning << "Unexpected setup loader revision: " << 
revision;
@@ -167,6 +183,7 @@
        
        if(is.fail()) {
                is.clear();
+               debug("could not read loader header");
                return false;
        }
        
@@ -174,6 +191,7 @@
                boost::uint32_t expected = util::load<boost::uint32_t>(is);
                if(is.fail()) {
                        is.clear();
+                       debug("could not read loader header checksum");
                        return false;
                }
                if(checksum.finalize() != expected) {
@@ -186,6 +204,8 @@
 
 void offsets::load(std::istream & is) {
        
+       found_magic = false;
+       
        /*
         * Try to load the offset table by following a pointer at a constant 
offset.
         * This method of storing the offset table is used in versions before 
5.1.5
diff -Nru innoextract-1.8/src/loader/offsets.hpp 
innoextract-1.9/src/loader/offsets.hpp
--- innoextract-1.8/src/loader/offsets.hpp      2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/loader/offsets.hpp      2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -51,6 +51,11 @@
 struct offsets {
        
        /*!
+        * True if we have some indication that this is an Inno Setup file
+        */
+       bool found_magic;
+       
+       /*!
         * Offset of compressed `setup.e32` (the actual installer code)
         *
         * A value of \c 0 means there is no setup.e32 embedded in this file
diff -Nru innoextract-1.8/src/release.cpp.in innoextract-1.9/src/release.cpp.in
--- innoextract-1.8/src/release.cpp.in  2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/release.cpp.in  2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -38,12 +38,12 @@
 
 const char innoextract_name[] = "${VERSION_0_NAME}";
 
-const char innoextract_version[] = "${VERSION_0_NUMBER}${GIT_SUFFIX_7}";
+const char innoextract_version[] = 
"${VERSION_0_STRING}${VERSION_SUFFIX}${GIT_SUFFIX_7}";
 
 const char innosetup_versions[] = "${VERSION_2}";
 
 const char innoextract_bugs[] = "${VERSION_4}";
 
-const char innoextract_copyright[] = "${LICENSE_0_STRING}";
+const char innoextract_copyright[] = "${LICENSE_0_LINE}";
 
 const char innoextract_license[] = "${LICENSE_TAIL}";
diff -Nru innoextract-1.8/src/setup/delete.cpp 
innoextract-1.9/src/setup/delete.cpp
--- innoextract-1.8/src/setup/delete.cpp        2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/delete.cpp        2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -43,7 +43,7 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(name, i.codepage);
+       is >> util::encoded_string(name, i.codepage, i.header.lead_bytes);
        
        load_condition_data(is, i);
        
diff -Nru innoextract-1.8/src/setup/directory.cpp 
innoextract-1.9/src/setup/directory.cpp
--- innoextract-1.8/src/setup/directory.cpp     2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/directory.cpp     2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -52,7 +52,7 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(name, i.codepage);
+       is >> util::encoded_string(name, i.codepage, i.header.lead_bytes);
        
        load_condition_data(is, i);
        
diff -Nru innoextract-1.8/src/setup/file.cpp innoextract-1.9/src/setup/file.cpp
--- innoextract-1.8/src/setup/file.cpp  2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/file.cpp  2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -81,11 +81,11 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(source, i.codepage);
-       is >> util::encoded_string(destination, i.codepage);
-       is >> util::encoded_string(install_font_name, i.codepage);
+       is >> util::encoded_string(source, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(destination, i.codepage, 
i.header.lead_bytes);
+       is >> util::encoded_string(install_font_name, i.codepage, 
i.header.lead_bytes);
        if(i.version >= INNO_VERSION(5, 2, 5)) {
-               is >> util::encoded_string(strong_assembly_name, i.codepage);
+               is >> util::encoded_string(strong_assembly_name, i.codepage, 
i.header.lead_bytes);
        } else {
                strong_assembly_name.clear();
        }
diff -Nru innoextract-1.8/src/setup/filename.cpp 
innoextract-1.9/src/setup/filename.cpp
--- innoextract-1.8/src/setup/filename.cpp      2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/filename.cpp      2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2019 Daniel Scharrer
+ * Copyright (C) 2012-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -37,7 +37,7 @@
 
 struct is_unsafe_path_char {
        bool operator()(char c) {
-               if(c < 32) {
+               if(static_cast<unsigned char>(c) < 32) {
                        return true;
                }
                switch(c) {
@@ -81,7 +81,8 @@
                }
                ptrdiff_t obegin = ptrdiff_t(result.size());
                result.append(begin, pos);
-               result.erase(std::remove_if(result.begin() + obegin, 
result.end(), is_unsafe_path_char()), result.end());
+               std::replace_copy_if(result.begin() + obegin, result.end(), 
result.begin() + obegin,
+                                    is_unsafe_path_char(), '$');
                begin = pos;
                
                if(pos == end) {
diff -Nru innoextract-1.8/src/setup/header.cpp 
innoextract-1.9/src/setup/header.cpp
--- innoextract-1.8/src/setup/header.cpp        2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/header.cpp        2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -493,10 +493,10 @@
                uninstall_display_size = 0;
        }
        
-       if(version == INNO_VERSION_EXT(5, 5, 0, 1)) {
+       if(version == INNO_VERSION_EXT(5, 4,  2, 1) || version == 
INNO_VERSION_EXT(5, 5, 0, 1)) {
                /*
                 * This is needed to extract an Inno Setup variant (BlackBox 
v2?) that uses
-                * the 5.5.0 (unicode) data version string while the format 
differs:
+                * the 5.4.2 or 5.5.0 (unicode) data version string while the 
format differs:
                 * The language entries are off by one byte and the 
EncryptionUsed flag
                 * gets set while there is no decrypt_dll.
                 * I'm not sure where exactly this byte goes, but it's after 
the compression
@@ -715,24 +715,24 @@
        util::to_utf8(app_support_url, codepage);
        util::to_utf8(app_updates_url, codepage);
        util::to_utf8(app_version, codepage);
-       util::to_utf8(default_dir_name, codepage);
+       util::to_utf8(default_dir_name, codepage, &lead_bytes);
        util::to_utf8(default_group_name, codepage);
-       util::to_utf8(base_filename, codepage);
-       util::to_utf8(uninstall_files_dir, codepage);
-       util::to_utf8(uninstall_name, codepage);
-       util::to_utf8(uninstall_icon, codepage);
-       util::to_utf8(app_mutex, codepage);
+       util::to_utf8(base_filename, codepage, &lead_bytes);
+       util::to_utf8(uninstall_files_dir, codepage, &lead_bytes);
+       util::to_utf8(uninstall_name, codepage, &lead_bytes);
+       util::to_utf8(uninstall_icon, codepage, &lead_bytes);
+       util::to_utf8(app_mutex, codepage, &lead_bytes);
        util::to_utf8(default_user_name, codepage);
        util::to_utf8(default_user_organisation, codepage);
        util::to_utf8(default_serial, codepage);
-       util::to_utf8(app_readme_file, codepage);
+       util::to_utf8(app_readme_file, codepage, &lead_bytes);
        util::to_utf8(app_contact, codepage);
        util::to_utf8(app_comments, codepage);
-       util::to_utf8(app_modify_path, codepage);
-       util::to_utf8(create_uninstall_registry_key, codepage);
+       util::to_utf8(app_modify_path, codepage, &lead_bytes);
+       util::to_utf8(create_uninstall_registry_key, codepage, &lead_bytes);
        util::to_utf8(uninstallable, codepage);
        util::to_utf8(close_applications_filter, codepage);
-       util::to_utf8(setup_mutex, codepage);
+       util::to_utf8(setup_mutex, codepage, &lead_bytes);
        util::to_utf8(changes_environment, codepage);
        util::to_utf8(changes_associations, codepage);
        
diff -Nru innoextract-1.8/src/setup/icon.cpp innoextract-1.9/src/setup/icon.cpp
--- innoextract-1.8/src/setup/icon.cpp  2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/icon.cpp  2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -43,11 +43,11 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(name, i.codepage);
-       is >> util::encoded_string(filename, i.codepage);
-       is >> util::encoded_string(parameters, i.codepage);
-       is >> util::encoded_string(working_dir, i.codepage);
-       is >> util::encoded_string(icon_file, i.codepage);
+       is >> util::encoded_string(name, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(filename, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(parameters, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(working_dir, i.codepage, 
i.header.lead_bytes);
+       is >> util::encoded_string(icon_file, i.codepage, i.header.lead_bytes);
        is >> util::encoded_string(comment, i.codepage);
        
        load_condition_data(is, i);
@@ -58,6 +58,14 @@
                app_user_model_id.clear();
        }
        
+       if(i.version >= INNO_VERSION(6, 1, 0)) {
+               const size_t guid_size = 16;
+               app_user_model_toast_activator_clsid.resize(guid_size);
+               is.read(&app_user_model_toast_activator_clsid[0], 
std::streamsize(guid_size));
+       } else {
+               app_user_model_toast_activator_clsid.clear();
+       }
+       
        load_version_data(is, i.version);
        
        icon_index = util::load<boost::int32_t>(is, i.version.bits());
@@ -98,6 +106,9 @@
        if(i.version >= INNO_VERSION(5, 5, 0)) {
                flagreader.add(PreventPinning);
        }
+       if(i.version >= INNO_VERSION(6, 1, 0)) {
+               flagreader.add(HasAppUserModelToastActivatorCLSID);
+       }
        
        options = flagreader;
 }
diff -Nru innoextract-1.8/src/setup/icon.hpp innoextract-1.9/src/setup/icon.hpp
--- innoextract-1.8/src/setup/icon.hpp  2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/icon.hpp  2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -48,6 +48,7 @@
                FolderShortcut,
                ExcludeFromShowInNewInstall,
                PreventPinning,
+               HasAppUserModelToastActivatorCLSID,
                // obsolete options:
                RunMinimized
        );
@@ -65,6 +66,7 @@
        std::string icon_file;
        std::string comment;
        std::string app_user_model_id;
+       std::string app_user_model_toast_activator_clsid;
        
        int icon_index;
        
diff -Nru innoextract-1.8/src/setup/info.cpp innoextract-1.9/src/setup/info.cpp
--- innoextract-1.8/src/setup/info.cpp  2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/info.cpp  2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -150,10 +150,13 @@
        
        stream::block_reader::pointer reader = stream::block_reader::get(is, 
version);
        
+       debug("loading main header");
        header.load(*reader, version);
        
+       debug("loading languages");
        load_entries(*reader, entries, header.language_count, languages, 
Languages);
        
+       debug("determining encoding");
        if(version.is_unicode()) {
                // Unicode installers are always UTF16-LE, do not allow users 
to override that.
                codepage = util::cp_utf16le;
@@ -180,27 +183,43 @@
        }
        
        if(version < INNO_VERSION(4, 0, 0)) {
+               debug("loading images and plugins");
                load_wizard_and_decompressor(*reader, version, header, *this, 
entries);
        }
        
+       debug("loading messages");
        load_entries(*reader, entries, header.message_count, messages, 
Messages);
+       debug("loading permissions");
        load_entries(*reader, entries, header.permission_count, permissions, 
Permissions);
+       debug("loading types");
        load_entries(*reader, entries, header.type_count, types, Types);
+       debug("loading components");
        load_entries(*reader, entries, header.component_count, components, 
Components);
+       debug("loading tasks");
        load_entries(*reader, entries, header.task_count, tasks, Tasks);
+       debug("loading directories");
        load_entries(*reader, entries, header.directory_count, directories, 
Directories);
+       debug("loading files");
        load_entries(*reader, entries, header.file_count, files, Files);
+       debug("loading icons");
        load_entries(*reader, entries, header.icon_count, icons, Icons);
+       debug("loading ini entries");
        load_entries(*reader, entries, header.ini_entry_count, ini_entries, 
IniEntries);
+       debug("loading registry entries");
        load_entries(*reader, entries, header.registry_entry_count, 
registry_entries, RegistryEntries);
+       debug("loading delete entries");
        load_entries(*reader, entries, header.delete_entry_count, 
delete_entries, DeleteEntries);
+       debug("loading uninstall delete entries");
        load_entries(*reader, entries, header.uninstall_delete_entry_count, 
uninstall_delete_entries,
                     UninstallDeleteEntries);
+       debug("loading run entries");
        load_entries(*reader, entries, header.run_entry_count, run_entries, 
RunEntries);
+       debug("loading uninstall run entries");
        load_entries(*reader, entries, header.uninstall_run_entry_count, 
uninstall_run_entries,
                     UninstallRunEntries);
        
        if(version >= INNO_VERSION(4, 0, 0)) {
+               debug("loading images and plugins");
                load_wizard_and_decompressor(*reader, version, header, *this, 
entries);
        }
        
@@ -208,6 +227,7 @@
        check_is_end(reader, "unknown data at end of primary header stream");
        reader = stream::block_reader::get(is, version);
        
+       debug("loading data entries");
        load_entries(*reader, entries, header.data_entry_count, data_entries, 
DataEntries);
        
        check_is_end(reader, "unknown data at end of secondary header stream");
diff -Nru innoextract-1.8/src/setup/ini.cpp innoextract-1.9/src/setup/ini.cpp
--- innoextract-1.8/src/setup/ini.cpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/ini.cpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -47,13 +47,13 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(inifile, i.codepage);
+       is >> util::encoded_string(inifile, i.codepage, i.header.lead_bytes);
        if(inifile.empty()) {
                inifile = "{windows}/WIN.INI";
        }
-       is >> util::encoded_string(section, i.codepage);
+       is >> util::encoded_string(section, i.codepage, i.header.lead_bytes);
        is >> util::encoded_string(key, i.codepage);
-       is >> util::encoded_string(value, i.codepage);
+       is >> util::encoded_string(value, i.codepage, i.header.lead_bytes);
        
        load_condition_data(is, i);
        
diff -Nru innoextract-1.8/src/setup/registry.cpp 
innoextract-1.9/src/setup/registry.cpp
--- innoextract-1.8/src/setup/registry.cpp      2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/registry.cpp      2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -65,7 +65,7 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(key, i.codepage);
+       is >> util::encoded_string(key, i.codepage, i.header.lead_bytes);
        if(i.version.bits() != 16) {
                is >> util::encoded_string(name, i.codepage);
        } else {
diff -Nru innoextract-1.8/src/setup/run.cpp innoextract-1.9/src/setup/run.cpp
--- innoextract-1.8/src/setup/run.cpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/run.cpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -45,9 +45,9 @@
                (void)util::load<boost::uint32_t>(is); // uncompressed size of 
the entry
        }
        
-       is >> util::encoded_string(name, i.codepage);
-       is >> util::encoded_string(parameters, i.codepage);
-       is >> util::encoded_string(working_dir, i.codepage);
+       is >> util::encoded_string(name, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(parameters, i.codepage, i.header.lead_bytes);
+       is >> util::encoded_string(working_dir, i.codepage, 
i.header.lead_bytes);
        if(i.version >= INNO_VERSION(1, 3, 9)) {
                is >> util::encoded_string(run_once_id, i.codepage);
        } else {
@@ -103,6 +103,9 @@
        if(i.version >= INNO_VERSION(5, 2, 0)) {
                flagreader.add(RunAsOriginalUser);
        }
+       if(i.version >= INNO_VERSION(6, 1, 0)) {
+               flagreader.add(DontLogParameters);
+       }
        
        options = flagreader;
 }
diff -Nru innoextract-1.8/src/setup/run.hpp innoextract-1.9/src/setup/run.hpp
--- innoextract-1.8/src/setup/run.hpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/setup/run.hpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -49,7 +49,8 @@
                HideWizard,
                Bits32,
                Bits64,
-               RunAsOriginalUser
+               RunAsOriginalUser,
+               DontLogParameters
        );
        
        enum wait_condition {
diff -Nru innoextract-1.8/src/setup/version.cpp 
innoextract-1.9/src/setup/version.cpp
--- innoextract-1.8/src/setup/version.cpp       2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/setup/version.cpp       2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -160,11 +160,13 @@
        { "Inno Setup Setup Data (5.3.10)",                     
INNO_VERSION_EXT(5, 3, 10, 0), 0 },
        { "Inno Setup Setup Data (5.3.10) (u)",                 
INNO_VERSION_EXT(5, 3, 10, 0), version::Unicode },
        { "Inno Setup Setup Data (5.4.2)",                      
INNO_VERSION_EXT(5, 4,  2, 0), 0 },
-       { "Inno Setup Setup Data (5.4.2) (u)",                  
INNO_VERSION_EXT(5, 4,  2, 0), version::Unicode },
+       { "Inno Setup Setup Data (5.4.2) (u)",  /* ambiguous */ 
INNO_VERSION_EXT(5, 4,  2, 0), version::Unicode },
+       { "" /* BlackBox v1? */,                                
INNO_VERSION_EXT(5, 4,  2, 1), 0 },
+       { "" /* BlackBox v1? */,                                
INNO_VERSION_EXT(5, 4,  2, 1), version::Unicode },
        { "Inno Setup Setup Data (5.5.0)",                      
INNO_VERSION_EXT(5, 5,  0, 0), 0 },
        { "Inno Setup Setup Data (5.5.0) (u)",  /* ambiguous */ 
INNO_VERSION_EXT(5, 5,  0, 0), version::Unicode },
-       { "" /* BlackBox v2? */,                                
INNO_VERSION_EXT(5, 5,  0, 1), 0 },
-       { "" /* BlackBox v2? */,                                
INNO_VERSION_EXT(5, 5,  0, 1), version::Unicode },
+       { "" /* BlackBox v2 / Inno Setup Ultra */,              
INNO_VERSION_EXT(5, 5,  0, 1), 0 },
+       { "" /* BlackBox v2 / Inno Setup Ultra */,              
INNO_VERSION_EXT(5, 5,  0, 1), version::Unicode },
        { "Inno Setup Setup Data (5.5.6)",                      
INNO_VERSION_EXT(5, 5,  6, 0), 0 },
        { "Inno Setup Setup Data (5.5.6) (u)",                  
INNO_VERSION_EXT(5, 5,  6, 0), version::Unicode },
        { "Inno Setup Setup Data (5.5.7)",      /* ambiguous */ 
INNO_VERSION_EXT(5, 5,  7, 0), 0 },
@@ -178,6 +180,7 @@
        { "Inno Setup Setup Data (5.6.2)",     /* prerelease */ 
INNO_VERSION_EXT(5, 6,  2, 0), 0 },
        { "Inno Setup Setup Data (5.6.2) (u)", /* prerelease */ 
INNO_VERSION_EXT(5, 6,  2, 0), version::Unicode },
        { "Inno Setup Setup Data (6.0.0) (u)",                  
INNO_VERSION_EXT(6, 0,  0, 0), version::Unicode },
+       { "Inno Setup Setup Data (6.1.0) (u)",                  
INNO_VERSION_EXT(6, 1,  0, 0), version::Unicode },
 };
 
 } // anonymous namespace
@@ -277,7 +280,7 @@
        char * end = std::find(version_string, version_string + 
boost::size(version_string), '\0');
        std::string version_str(version_string, end);
        debug("unknown version: \"" << version_str << '"');
-       if(version_str.find("Inno Setup") == std::string::npos) {
+       if(!boost::contains(version_str, "Inno Setup")) {
                throw version_error();
        }
        
@@ -372,6 +375,11 @@
                return true;
        }
        
+       if(value == INNO_VERSION(5, 4, 2)) {
+               // might be either 5.4.2 or 5.4.2.1
+               return true;
+       }
+       
        if(value == INNO_VERSION(5, 5, 0)) {
                // might be either 5.5.0 or 5.5.0.1
                return true;
diff -Nru innoextract-1.8/src/util/boostfs_compat.hpp 
innoextract-1.9/src/util/boostfs_compat.hpp
--- innoextract-1.8/src/util/boostfs_compat.hpp 2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/util/boostfs_compat.hpp 2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2018 Daniel Scharrer
+ * Copyright (C) 2012-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -31,30 +31,6 @@
 #include <boost/filesystem/path.hpp>
 #include <boost/filesystem/operations.hpp>
 
-#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION < 3
-
-namespace boost { namespace filesystem {
-
-inline bool create_directories(const path & p) {
-       
-       if(p.empty()) {
-               return true;
-       }
-       
-       path parent = p.parent_path();
-       if(!exists(parent)) {
-               if(!create_directories(parent)) {
-                       return false;
-               }
-       }
-       
-       return create_directory(p);
-}
-
-} } // namespace boost::filesystem
-
-#endif
-
 namespace util {
 
 inline const std::string & as_string(const std::string & path) {
diff -Nru innoextract-1.8/src/util/encoding.cpp 
innoextract-1.9/src/util/encoding.cpp
--- innoextract-1.8/src/util/encoding.cpp       2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/util/encoding.cpp       2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -468,14 +468,41 @@
        
 }
 
-void wtf8_to_utf16le(const std::string & from, std::string & to) {
+const char * wtf8_find_end(const char * begin, const char * end) {
+       
+       const char * i = end;
+       while(i != begin && is_utf8_continuation_byte(boost::uint8_t(*(i - 
1)))) {
+               i--;
+       }
+       
+       if(i != begin) {
+               unicode_char chr = boost::uint8_t(*(i - 1));
+               size_t expected = 0;
+               if(chr & (1 << 7)) {
+                       expected++;
+                       if(chr & (1 << (5 + 6))) {
+                               expected++;
+                               if(chr & (1 << (4 + 6 + 6))) {
+                                       expected++;
+                               }
+                       }
+               }
+               if(expected > size_t(end - i)) {
+                       return i - 1;
+               }
+       }
+       
+       return end;
+}
+
+void wtf8_to_utf16le(const char * begin, const char * end, std::string & to) {
        
        to.clear();
-       to.reserve(from.size() * 2); // optimistically, most strings only have 
ASCII characters
+       to.reserve(size_t(end - begin) * 2); // optimistically, most strings 
only have ASCII characters
        
-       for(std::string::const_iterator i = from.begin(); i != from.end(); ) {
+       for(const char * i = begin; i != end; ) {
                
-               unicode_char chr = utf8_read(i, from.end());
+               unicode_char chr = utf8_read(i, end);
                
                if(chr >= 0x10000) {
                        chr -= 0x10000;
@@ -491,6 +518,10 @@
        
 }
 
+void wtf8_to_utf16le(const std::string & from, std::string & to) {
+       return wtf8_to_utf16le(from.c_str(), from.c_str() + from.size(), to);
+}
+
 namespace {
 
 unicode_char windows1252_replacements[] = {
@@ -752,7 +783,8 @@
 
 #endif // INNOEXTRACT_HAVE_WIN32_CONV
 
-void to_utf8(const std::string & from, std::string & to, codepage_id codepage) 
{
+void to_utf8(const std::string & from, std::string & to, codepage_id codepage,
+             const std::bitset<256> * lead_bytes) {
        
        switch(codepage) {
                case cp_utf16le:     utf16le_to_wtf8(from, to); return;
@@ -761,6 +793,30 @@
                default: break;
        }
        
+       if(lead_bytes) {
+               std::string buffer;
+               for(size_t start = 0; start < from.length();) {
+                       size_t end = start;
+                       while(end < from.length()) {
+                               if(lead_bytes->test(static_cast<unsigned 
char>(from[end]))) {
+                                       end = std::min(from.length(), end + 2);
+                               } else if(from[end] != 0x5C) {
+                                       end++;
+                               } else {
+                                       break;
+                               }
+                       }
+                       buffer = from.substr(start, end - start);
+                       util::to_utf8(buffer, codepage, NULL);
+                       to.append(buffer);
+                       if(end < from.length()) {
+                               to.push_back('\\');
+                       }
+                       start = end + 1;
+               }
+               return;
+       }
+       
        #if INNOEXTRACT_HAVE_ICONV
        if(to_utf8_iconv(from, to, codepage)) {
                return;
@@ -779,7 +835,7 @@
 
 } // anonymous namespace
 
-void to_utf8(std::string & data, codepage_id codepage) {
+void to_utf8(std::string & data, codepage_id codepage, const std::bitset<256> 
* lead_bytes) {
        
        if(data.empty() || is_utf8(data, codepage)) {
                // Already UTF-8
@@ -787,7 +843,7 @@
        }
        
        std::string buffer;
-       to_utf8(data, buffer, codepage);
+       to_utf8(data, buffer, codepage, lead_bytes);
        std::swap(data, buffer);
 }
 
diff -Nru innoextract-1.8/src/util/encoding.hpp 
innoextract-1.9/src/util/encoding.hpp
--- innoextract-1.8/src/util/encoding.hpp       2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/util/encoding.hpp       2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -26,6 +26,7 @@
 #ifndef INNOEXTRACT_UTIL_ENCODING_HPP
 #define INNOEXTRACT_UTIL_ENCODING_HPP
 
+#include <bitset>
 #include <string>
 
 #include <boost/cstdint.hpp>
@@ -151,18 +152,30 @@
 void utf16le_to_wtf8(const std::string & from, std::string & to);
 
 /*!
+ * Find the end of the last complete WTF-8 character in a string.
+ */
+const char * wtf8_find_end(const char * begin, const char * end);
+
+/*!
+ * Convert WTF-8 to UTF-16 while preserving unpaired surrogates.
+ */
+void wtf8_to_utf16le(const char * begin, const char * end, std::string & to);
+
+/*!
  * Convert WTF-8 to UTF-16 while preserving unpaired surrogates.
  */
 void wtf8_to_utf16le(const std::string & from, std::string & to);
 
 /*!
  * Convert a string in place to UTF-8 from a specified encoding.
- * \param data     The input string to convert.
- * \param codepage The Windows codepage number for the input string encoding.
+ * \param data       The input string to convert.
+ * \param codepage   The Windows codepage number for the input string encoding.
+ * \param lead_bytes Preserve 0x5C path separators.
  *
  * \note This function is not thread-safe.
  */
-void to_utf8(std::string & data, codepage_id codepage = cp_windows1252);
+void to_utf8(std::string & data, codepage_id codepage = cp_windows1252,
+             const std::bitset<256> * lead_bytes = NULL);
 
 /*!
  * Convert a string from UTF-8 to a specified encoding.
diff -Nru innoextract-1.8/src/util/load.cpp innoextract-1.9/src/util/load.cpp
--- innoextract-1.8/src/util/load.cpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/util/load.cpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -54,9 +54,10 @@
        discard(is, length);
 }
 
-void encoded_string::load(std::istream & is, std::string & target, codepage_id 
codepage) {
+void encoded_string::load(std::istream & is, std::string & target, codepage_id 
codepage,
+                          const std::bitset<256> * lead_bytes) {
        binary_string::load(is, target);
-       to_utf8(target, codepage);
+       to_utf8(target, codepage, lead_bytes);
 }
 
 unsigned to_unsigned(const char * chars, size_t count) {
diff -Nru innoextract-1.8/src/util/load.hpp innoextract-1.9/src/util/load.hpp
--- innoextract-1.8/src/util/load.hpp   2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/src/util/load.hpp   2020-08-09 20:48:04.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2019 Daniel Scharrer
+ * Copyright (C) 2011-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -26,6 +26,7 @@
 #ifndef INNOEXTRACT_UTIL_LOAD_HPP
 #define INNOEXTRACT_UTIL_LOAD_HPP
 
+#include <bitset>
 #include <cstring>
 #include <istream>
 #include <string>
@@ -89,34 +90,46 @@
        
        std::string & data;
        codepage_id codepage;
+       const std::bitset<256> * lead_byte_set;
        
        /*!
-        * \param target  The std::string object to receive the loaded UTF-8 
string.
-        * \param cp      The Windows codepage for the encoding of the stored 
string.
+        * \param target     The std::string object to receive the loaded UTF-8 
string.
+        * \param cp         The Windows codepage for the encoding of the 
stored string.
         */
-       encoded_string(std::string & target, codepage_id cp) : data(target), 
codepage(cp) { }
+       encoded_string(std::string & target, codepage_id cp)
+               : data(target), codepage(cp), lead_byte_set(NULL) { }
+       
+       /*!
+        * \param target     The std::string object to receive the loaded UTF-8 
string.
+        * \param cp         The Windows codepage for the encoding of the 
stored string.
+        * \param lead_bytes Preserve 0x5C path separators.
+        */
+       encoded_string(std::string & target, codepage_id cp, const 
std::bitset<256> & lead_bytes)
+               : data(target), codepage(cp), lead_byte_set(&lead_bytes) { }
        
        /*!
         * Load and convert a length-prefixed string
         *
         * \note This function is not thread-safe.
         */
-       static void load(std::istream & is, std::string & target, codepage_id 
codepage);
+       static void load(std::istream & is, std::string & target, codepage_id 
codepage,
+                        const std::bitset<256> * lead_bytes = NULL);
        
        /*!
         * Load and convert a length-prefixed string
         *
         * \note This function is not thread-safe.
         */
-       static std::string load(std::istream & is, codepage_id codepage) {
+       static std::string load(std::istream & is, codepage_id codepage,
+                               const std::bitset<256> * lead_bytes = NULL) {
                std::string target;
-               load(is, target, codepage);
+               load(is, target, codepage, lead_bytes);
                return target;
        }
        
 };
 inline std::istream & operator>>(std::istream & is, const encoded_string & 
str) {
-       encoded_string::load(is, str.data, str.codepage);
+       encoded_string::load(is, str.data, str.codepage, str.lead_byte_set);
        return is;
 }
 
diff -Nru innoextract-1.8/src/util/windows.cpp 
innoextract-1.9/src/util/windows.cpp
--- innoextract-1.8/src/util/windows.cpp        2020-01-15 16:29:27.000000000 
+0100
+++ innoextract-1.9/src/util/windows.cpp        2020-08-09 20:48:04.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2019 Daniel Scharrer
+ * Copyright (C) 2013-2020 Daniel Scharrer
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the author(s) be held liable for any damages
@@ -75,9 +75,8 @@
        const HANDLE handle;
        
        //! Buffer for charset conversions
-       std::vector<wchar_t> buffer;
-       const utf8_codecvt * codecvt;
-       utf8_codecvt::state_type codecvt_state;
+       std::string in_buffer;
+       std::string out_buffer;
        
        //! Initial console display attributes
        WORD initial_attributes;
@@ -236,6 +235,10 @@
        }
        
        void handle_command(CommandType type, const char * codes, const char * 
end) {
+               if(!in_buffer.empty()) {
+                       output_text(in_buffer.c_str(), in_buffer.c_str() + 
in_buffer.size());
+                       in_buffer.clear();
+               }
                switch(type) {
                        case EL:  erase_in_line(codes, end); break;
                        case SGR: select_graphic_rendition(codes, end); break;
@@ -249,7 +252,7 @@
                }
        }
        
-       void handle_deferred_clear(wchar_t * & begin, wchar_t * end) {
+       void handle_deferred_clear(LPCWSTR & begin, LPCWSTR end) {
                
                CONSOLE_SCREEN_BUFFER_INFO info;
                if(!GetConsoleScreenBufferInfo(handle, &info)) {
@@ -265,8 +268,8 @@
                                break;
                        }
                        
-                       wchar_t * cr = std::find(begin, end, L'\r');
-                       wchar_t * ln = std::find(begin, cr, L'\n');
+                       LPCWSTR cr = std::find(begin, end, L'\r');
+                       LPCWSTR ln = std::find(begin, cr, L'\n');
                        
                        // Insert an empty line before the "cleared" line
                        if(clear_line == info.dwCursorPosition.Y) {
@@ -338,48 +341,48 @@
                
        }
        
+       void output_text(const char * begin, const char * end) {
+               
+               wtf8_to_utf16le(begin, end, out_buffer);
+               
+               LPCWSTR obegin = reinterpret_cast<LPCWSTR>(out_buffer.c_str());
+               LPCWSTR oend = obegin + out_buffer.size() / 2;
+               
+               if(deferred_clear) {
+                       handle_deferred_clear(obegin, oend);
+               }
+               
+               DWORD count;
+               WriteConsoleW(handle, obegin, DWORD(oend - obegin), &count, 
NULL);
+               
+       }
+       
        void handle_text(const char * s, size_t n) {
                
+               if(!in_buffer.empty()) {
+                       in_buffer.append(s, n);
+                       s = in_buffer.c_str();
+                       n = in_buffer.size();
+               }
+               
                const char * end = s + n;
                
                if(s == end) {
                        return;
                }
                
-               for(;;) {
-                       
-                       wchar_t * obegin = &buffer.front();
-                       wchar_t * oend = obegin + buffer.size();
-                       wchar_t * onext = obegin;
-                       
-                       std::codecvt_base::result res;
-                       res = codecvt->in(codecvt_state, s, end, s, obegin, 
oend, onext);
-                       
-                       if(deferred_clear) {
-                               handle_deferred_clear(obegin, onext);
-                       }
-                       
-                       DWORD count;
-                       WriteConsoleW(handle, obegin, DWORD(onext - obegin), 
&count, NULL);
-                       
-                       if(res != std::codecvt_base::partial) {
-                               break;
-                       }
-                       
-                       if(onext == oend) {
-                               buffer.resize(buffer.size() * 2);
-                       }
-                       
-               }
+               const char * e = wtf8_find_end(s, end);
+               
+               output_text(s, e);
+               
+               in_buffer.assign(e, end);
                
        }
        
 public:
        
-       windows_console_sink(HANDLE console_handle, const utf8_codecvt * 
converter)
+       explicit windows_console_sink(HANDLE console_handle)
                : handle(console_handle)
-               , buffer(256)
-               , codecvt(converter)
                , initial_attributes(get_attributes())
                , default_attributes(get_default_attributes())
                , attributes(initial_attributes)
@@ -389,6 +392,9 @@
        { }
        
        ~windows_console_sink() {
+               if(!in_buffer.empty()) {
+                       output_text(in_buffer.c_str(), in_buffer.c_str() + 
in_buffer.size());
+               }
                if(deferred_clear) {
                        CONSOLE_SCREEN_BUFFER_INFO info;
                        if(GetConsoleScreenBufferInfo(handle, &info)) {
@@ -400,9 +406,6 @@
        
 };
 
-// UTF8 -> UTF-16 converter
-static utf8_codecvt codecvt;
-
 typedef boost::iostreams::stream_buffer<windows_console_sink> console_buffer;
 struct console_buffer_info {
        HANDLE handle;
@@ -440,7 +443,7 @@
 static void init_console(std::ostream & os, console_buffer_info & info, DWORD 
n) {
        info.handle = GetStdHandle(n);
        if(is_console(info.handle)) {
-               info.buf = new console_buffer(info.handle, &codecvt);
+               info.buf = new console_buffer(info.handle);
                info.orig_buf = os.rdbuf(info.buf);
        } else {
                info.handle = NULL;
@@ -521,7 +524,7 @@
        }
        
        // Tell boost::filesystem to interpret our path strings as UTF-8
-       boost::filesystem::path::imbue(std::locale(std::locale(), 
&util::codecvt));
+       boost::filesystem::path::imbue(std::locale(std::locale(), new 
utf8_codecvt()));
        
        // Enable UTF-8 output and ANSI escape sequences
        util::console_wrapper wrapped;
diff -Nru innoextract-1.8/VERSION innoextract-1.9/VERSION
--- innoextract-1.8/VERSION     2020-01-15 16:29:27.000000000 +0100
+++ innoextract-1.9/VERSION     2020-08-09 20:48:04.000000000 +0200
@@ -1,7 +1,7 @@
-innoextract 1.8
+innoextract 1.9
 
 Known working Inno Setup versions:
-Inno Setup 1.2.10 to 6.0.2
+Inno Setup 1.2.10 to 6.0.5
 
 Bug tracker:
-http://innoextract.constexpr.org/issues
+https://innoextract.constexpr.org/issues

Reply via email to