Add support for Inno Setup 6.4.2 through 6.7.1#210
Open
dscho wants to merge 11 commits into
Open
Conversation
Inno Setup 6.5.0 bumped SetupLdrOffsetTableVersion from 1 to 2 and widened the on-disk TSetupLdrOffsetTable struct: TotalSize, OffsetEXE, Offset0 and Offset1 each grew from 32-bit LongWord to Int64, and a new ReservedPadding UInt32 was inserted before TableCRC. The record also lost its `packed` qualifier, but with 32-bit Delphi default alignment (Int64 is 4-byte aligned in 32-bit Delphi) the on-disk layout remains contiguous, growing from 48 to 64 bytes total. See Projects/Src/Shared.Struct.pas at tag is-6_5_0 in https://github.com/jrsoftware/issrc. Without this, every installer produced by Inno Setup 6.5.0 or newer fails to load with: Warning: Unexpected setup loader revision: 2 Warning: Setup loader checksum mismatch! Could not determine setup data version! Detect revision 2 specifically and parse the new layout. The fields that innoextract actually consumes (exe_offset, header_offset, data_offset) are still stored as 32-bit in the offsets struct, so truncate the read 64-bit values to 32-bit and emit a warning if any of them exceed 4 GiB. Real installers that large are rare in the wild but possible, and widening the struct is left for a follow-up. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.4.2 added the new [Setup] section directive CloseApplicationsFilterExcludes (see https://jrsoftware.org/files/is6.4-whatsnew.htm). It is serialised as a binary string immediately after architectures_installed_in_64bit_mode_expr in TSetupHeader (Projects/Src/Shared.Struct.pas in https://github.com/jrsoftware/issrc at tag is-6_4_2). Read it as a new header field for installers from 6.4.2 onward; clear it for older installers. 6.4.2 also bumped the SetupID magic to 'Inno Setup Setup Data (6.4.2)'; 6.4.3 to 'Inno Setup Setup Data (6.4.3)'. Both versions are otherwise on-disk-compatible with the post-6.4.2 layout, so add them to the known versions table without further parsing changes. This change is sourced from the prior-art PR dscharrer#202 by itai-delphos (dscharrer#202), which I am picking up and extending to cover Inno Setup 6.5.x, 6.6.x and 6.7.x in the follow-up commits in this series. Helped-by: itai-delphos@github Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.5.0 made two on-disk changes to TSetupHeader:
- A new SevenZipLibraryName: String, serialised right after
CloseApplicationsFilterExcludes (Projects/Src/Shared.Struct.pas
at tag is-6_5_0 in https://github.com/jrsoftware/issrc).
- A new NumISSigKeyEntries: Integer entry-count field, slotted
between NumDirEntries and NumFileEntries. ISSig (Inno Setup
Signature) key entries are part of the new ECDSA P-256 ISSigTool
technology preview added in 6.4.3 and turned into a serialised
table in 6.5.0. innoextract does not yet process the entries
themselves; for now consume the count so that NumFileEntries and
every entry count after it remains aligned.
6.5.0 also bumped the SetupLdrOffsetTableVersion from 1 to 2 and
widened the offset table; that part is handled in the previous
"loader: support setup loader offset table revision 2" commit.
Add SetupID magic strings:
- 6.5.0 covers 6.5.0 and 6.5.1, which share `Inno Setup Setup Data
(6.5.0)`.
- 6.5.2 covers 6.5.2, 6.5.3 and 6.5.4, which share
`Inno Setup Setup Data (6.5.2)`. The header changes (new wizard
image background colours and dynamic-dark-mode variants) are added
in a separate follow-up commit since they are not in the same
on-disk position as the older WizardImageBackColor field, so they
require a different branch in `header::load`.
This change continues the prior-art line started by PR dscharrer#202
(dscharrer#202) by itai-delphos.
Helped-by: itai-delphos@github
Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.6.0 made several rearrangements in TSetupHeader's wizard section (Projects/Src/Shared.Struct.pas at tag is-6_6_0 in https://github.com/jrsoftware/issrc): - Removed WizardStyle. The classic/modern toggle was always going to end up as ModernStyle for any installer reaching modern Inno Setup versions, so 6.6.0 dropped the field on disk entirely. - Added WizardDarkStyle: TSetupWizardDarkStyle (light / dark / dynamic), serialised AFTER the WizardSizePercentX/Y pair instead of where WizardStyle used to sit. - Added WizardImageBackColorDynamicDark and WizardSmallImageBackColorDynamicDark, the dark-mode counterparts of the colours added back in 6.5.2. 6.6.1 then added one more field at the same position: - WizardImageOpacity: Byte. Defaults to 0xff (fully opaque) for older installers. In innoextract these changes are not purely additive: the wizard read block has to take a 6.6.0+ branch that omits the WizardStyle byte, and the new colour and opacity fields land between the old WizardImageAlphaFormat and the rest of the wizard scalars. Add a stored_dark_style enum mapping (analogous to stored_setup_style), declare it as a NAMED_ENUM and provide its NAMES so that stored_enum<>::get()'s warning path can reference its name at compile time, and add new header fields image_back_color_dynamic_dark, small_image_back_color_dynamic_dark and wizard_image_opacity. TSetupHeaderOption itself was reshuffled at the same time. The shWizardResizable bit was removed (the new modern wizard is always resizable, so the flag became redundant) and four new wizard-styling bits were appended at the same position: shWizardModern, shWizardBorderStyled, shWizardKeepAspectRatio and shWizardLightButtonsUnstyled. Mirror this in header::flags by adding the four new enum values, gating the existing WizardResizable add to ``< 6.6.0`` and adding the four new flags for ``>= 6.6.0`` so that the on-disk bit positions stay aligned. Provide NAMES strings for the new flags. shWizardLightButtonsUnstyled is later dropped again in 6.7.0; that gate is added in the 6.7.0 patch so that this commit remains self-contained for installers compiled with 6.6.0 or 6.6.1. Add the SetupID magic strings 'Inno Setup Setup Data (6.6.0)' and 'Inno Setup Setup Data (6.6.1)'. (Each 6.6.x point release carries a distinct magic, unlike 6.5.0/.1 and 6.5.2/.3/.4.) Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.7.0 widens several on-disk size and offset fields from
32 to 64 bits (TSetupLdrOffsetTable.OffsetEXE/Offset0/Offset1, the
block-header stored_size, and the new "idskb32" disk-slice header), to
allow setup binaries larger than 4 GiB. The current "loader: support
setup loader offset table revision 2" code path already reads the
widened TSetupLdrOffsetTable fields as Int64, but truncates them back
to 32 bits with a warning when storing into `loader::offsets` because
the struct still holds them in `boost::uint32_t`.
Widen the affected types now, ahead of consuming the new on-disk
formats, so that the follow-up commit can drop the truncations and
read the wider on-disk fields natively without churn in the call
sites. The fields touched are:
- `loader::offsets::{exe_offset, exe_compressed_size,
exe_uncompressed_size, message_offset, header_offset,
data_offset}` and the matching argument of `load_offsets_at`.
- `stream::chunk::{sort_offset, offset}` (chunk byte offsets within
a slice; `size` was already 64-bit).
- `stream::slice_reader::{data_offset, slice_size}`, the matching
argument of the embedded-data constructor, and the offset
parameter of `seek(slice, offset)`. The local `read_pos`/
`remaining` in `slice_reader::read` follow `slice_size`.
- `cli/extract.cpp`'s local `sort_offset` mirror of
`chunk::sort_offset`.
The on-disk reads themselves are unchanged: every site still pulls in
the same number of bytes as before, just into wider locals or members,
and the existing `boost::uint32_t(...)` truncation in the loader-v2
path remains in place so behaviour is bit-identical for installers up
to 4 GiB. Where `streampos` / `seekg(off_t)` interactions now produce
unsigned-to-signed warnings on the wider integers, wrap with
`std::streamoff(...)` to keep the conversion explicit and silent.
A follow-up commit drops the loader-v2 truncation and the
"exceeds 4 GiB" warning so installers above the legacy limit are
parsed natively; another follow-up reads the new 64-bit
block-header `stored_size` for Inno Setup 6.7.0 and later.
Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Now that loader::offsets, stream::chunk, stream::slice_reader and the block-reader local size hold their values in uint64_t, drop the truncating uint32_t casts that the previous "loader: support setup loader offset table revision 2" commit had to use as a placeholder. The loader-revision-2 path stores the full 64-bit OffsetEXE / Offset0 / Offset1 directly, and the warning about offsets exceeding 4 GiB is gone because there is no longer any truncation happening; only a much narrower sanity check for negative values remains, since the on-disk fields are signed Int64 in Inno Setup's struct. stream/block.cpp grows a 6.7.0+ branch in block_reader::get that loads stored_size as uint64_t to match the on-disk widening introduced in Inno Setup 6.7.0 (TSetupLdrCompressedBlockHeader's StoredSize was bumped from LongWord to Int64 in Projects/Src/Stream.BlockReader.pas at tag is-6_7_0 in https://github.com/jrsoftware/issrc). With the local stored_size already widened by the previous refactor, the rest of block_reader needs no change: the boost::iostreams::restrict slice still receives the value unchanged via std::streamoff, and the per-4 KiB-subblock checksum-overhead arithmetic now operates on uint64_t directly so the explicit uint32_t cast falls away. Without this commit we observed `block header CRC32 mismatch` on 6.7.0 installers because the older code read just 4 bytes of a freshly-widened 8-byte StoredSize and then mistook the next 4 bytes (actually the upper half of StoredSize) for the compressed flag and the trailing CRC, causing the actual_checksum.finalize() check to fail. The mismatch is what motivated the type-widening refactor in the previous commit. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.7.0 padded both TSetupHeaderOption and TSetupFileEntryOption to 57 elements (foUnusedPadding/shUnusedPadding = 56) so that the serialised `packed set` always occupies 8 bytes regardless of how many flags are actually defined. The motivation in issrc is to keep 32-bit and 64-bit Delphi builds bit-compatible: a `set` with more than 32 flags has a minimum size of 8 bytes in 64-bit Delphi, so 32-bit builds need to match by reserving the same width. innoextract reads bitsets through stored_flag_reader<>, which sizes itself to the number of flags the caller adds. To support the new padding without exposing the internal byte counter or duplicating the reader API, add a small public helper that drains additional padding bytes from the stream until at least `target` bytes have been consumed in total. A bytes_consumed() getter is added too so callers can introspect the count if needed. The follow-up commits that bring innoextract up to Inno Setup 6.7.0 use this from header::load_flags and file_entry::load. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.5.0 made several invasive changes to the on-disk serialisation that go well beyond the SetupID magic and the new SevenZipLibraryName header field that the previous patch picked up. To actually parse a 6.5.0 installer, four further changes are needed. First, a new TSetupEncryptionHeader record now sits on the outer stream, between the version magic and the first compressed block (Projects/Src/Shared.Struct.pas at tag is-6_5_0 in https://github.com/jrsoftware/issrc). It carries a 4-byte expected CRC32, a 1-byte EncryptionUse flag, a 16-byte KDFSalt, the KDF iteration count, the 24-byte BaseNonce triple (RandomXorStartOffset / RandomXorFirstSlice / RemainingRandom) and a 4-byte PasswordTest, with the CRC32 covering the 49 bytes after itself. Read it on the outer stream so the block reader starts at the right offset; if the EncryptionUse byte is non-zero, log a warning that decrypting 6.5.0+ encrypted installers is not yet supported. Validate the CRC32 against expected_crc and warn on mismatch. Second, the matching encryption fields move out of TSetupHeader. The 4-byte SHA-256 digest prefix and the 44-byte salt-plus-nonce blob that 6.4.0 added directly to the header are no longer present in 6.5.0; the shEncryptionUsed flag is also dropped from TSetupHeaderOption. Gate the existing 6.4.x reads to ``< 6.5.0`` and clear the header.password / password_salt members for 6.5.0+ so that downstream code sees the same "no embedded password" state. Third, the new TSetupISSigKeyEntry array sits between the directory and file entry streams. Read NumISSigKeyEntries (already wired up by the 6.5.0 magic patch as a placeholder, now actually stored in the new header.issig_key_count). After the directory entries, load exactly that many records via the standard load_entries helper, mirroring how component_entry, task_entry, etc. are handled. Each record holds three binary strings (PublicX, PublicY, RuntimeID) naming an Ed25519 public key the installer trusts; the new issig_key_entry struct exposes them so callers that opt in via the ISSigKeys entry-type flag can inspect them. Fourth, when a 6.5.0+ installer sets [Setup] SevenZipLibraryName (supporting Extract7ZipArchive that was added in 6.4.0), an additional binary string appears on the wizard / decompressor stream after the decompressor DLL and before the decryptor DLL slot. Skip past it so later reads of decrypt_dll align correctly. In TSetupFileEntry, 6.5.0 appended five new expression strings (Excludes, DownloadISSigSource, DownloadUserName, DownloadPassword, ExtractArchivePassword) and a per-file Verification packed record made of an ISSigAllowedKeys ansi string, a 32-byte SHA-256 digest, and a TSetupFileVerificationType byte enum (none / hash / IS sig); these sit between BeforeInstall and MinVersion. Two new flag bits foDownload and foExtractArchive were added to TSetupFileEntryOption for the new [Files] flags `download` and `extractarchive`. Add the matching members and stored_enum mapping, gated to `>= 6.5.0`. The SHA-256 digest is stored in the existing file_entry::checksum field (unused before 6.5.0 in upstream innoextract); the trailing unconditional reset of that field is gated to `< 6.5.0` so the verification hash survives. In TSetupFileLocationEntry, Inno Setup 6.4.3 (issrc commits 6aec0a55 "Distinguish file options (fo) and file location options (flo)." and 00d335b7 "Cleanup: TSetupFileLocationEntry contained a few things which Setup doesn't need and are only for the compiler.", both first tagged in is-6_4_3) had already dropped four flags (foVersionInfoNotValid, foIsUninstExe, foApplyTouchDateTime, foSolidBreak) from the Flags bitset and removed the standalone Sign field entirely; the [Files] `signonce` and `signcheck` directives still record a per-file location signing intent at compile time but the result is no longer serialised. Gate the four obsolete flag adds to `< 6.4.3` and short-circuit the Sign read for `>= 6.4.3` to NoSetting. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…tup 6.5.2 Inno Setup 6.5.2 widened TSetupFileLocationEntry.StartOffset from LongWord (4 bytes) to Int64 (8 bytes) in Projects/Src/Shared.Struct.pas (tag is-6_5_2 in https://github.com/jrsoftware/issrc), so that the data offset within a slice can exceed 4 GiB. The matching change for chunk.first_slice and chunk.last_slice had already happened in 4.0.0 / 5.x; only StartOffset was still 32-bit. Read the new layout as uint64 for `>= 6.5.2`, keep the old 32-bit read for everything below. The earlier offsets-table widening patch already widened chunk_location::offset itself to 64 bits, so the only thing that needed to change here is the read width. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.6.0 reorganised TSetupLanguageEntry beyond what is already covered by the matching SetupID magic patch. To actually parse 6.6.0 language entries, the on-disk layout in Projects/Src/Shared.Struct.pas (tag is-6_6_0 in https://github.com/jrsoftware/issrc) needs three changes. The TitleFontName and CopyrightFontName binary strings were dropped entirely (the new dialog-font-base-scale machinery makes per-language title/copyright fonts unnecessary). The matching TitleFontSize and CopyrightFontSize integers were replaced by DialogFontBaseScaleHeight and DialogFontBaseScaleWidth, sitting between DialogFontSize and WelcomeFontSize. And LanguageID narrowed from Cardinal (4 bytes) to Word (2 bytes) on disk, since the upper half was always zero anyway. Add corresponding members for the new scale fields, gate the obsolete reads to ``< 6.6.0``, and read LanguageID at the right width. In TSetupCustomMessageEntry/TSetupPermissionEntry the read order is unchanged; only the wizard-and-decompressor stream gains material: 6.6.0 added a second copy of each wizard image group right after the existing main and small image groups, holding the dynamic-dark images that match the new WantWizardImagesDynamicDark plumbing in Setup.MainFunc.pas (tag is-6_6_0). Both groups are always serialised even when dark-mode imagery is not configured; the runtime is what picks which set to display. innoextract does not expose dark-theme images yet, but the bytes have to be consumed so the decompressor / decryptor blocks that follow stay aligned. Read both groups into local vectors and discard them, gated to ``>= 6.6.0``. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Inno Setup 6.7.0 made another sweep of changes to the on-disk serialisation. The 6.7.x point releases share a single SetupID magic, "Inno Setup Setup Data (6.7.0)" (Projects/Src/Setup.MainFunc.pas at tag is-6_7_0 in https://github.com/jrsoftware/issrc), so 6.7.0 and 6.7.1 are detected together and parsed identically. In TSetupHeader, the five shUsePrevious* flags (UsePreviousAppDir, UsePreviousGroup, UsePreviousSetupType, UsePreviousTasks, UsePreviousUserInfo) were promoted out of the TSetupHeaderOption bitset into expression-string fields of the same names, so that they can take per-install conditional values rather than just on/off. Read the five new strings between SevenZipLibraryName and LicenseText, and gate the corresponding flag adds in load_flags to ``< 6.7.0`` so the bitset matches the new length on the wire. Three more wizard-colour fields were added next to the 6.5.2/6.6.0 ones: WizardBackColor between WizardSmallImageBackColor and the *DynamicDark colour pair, WizardBackColorDynamicDark in the same position relative to the dynamic-dark companions, and WizardBackImageOpacity (Byte) right after WizardImageOpacity. TSetupWizardLightControlStyling (wcsAll, wcsAllButButtons, wcsOnlyRequired) is also stored as a byte enum at that point. Add header members for all four, default the older versions to 0xff / LightControlStyleAll respectively, and provide the matching stored_enum and NAMES blocks. TSetupHeaderOption itself dropped shWizardLightButtonsUnstyled (the 6.6.x experiment for light theme) and added shRedirectionGuard and shWizardBevelsHidden at the end. Tighten the existing WizardLightButtonsUnstyled add to ``< 6.7.0`` and add the two new flags for ``>= 6.7.0`` with their NAMES strings, mirroring the 6.6.0 pattern. The whole bitset was also padded to 57 elements via shUnusedPadding=56 so the serialised set is always 8 bytes regardless of which subset of flags is actually defined. The motivation in issrc is bit-compatibility between 32-bit and 64-bit Delphi builds (a `set` with more than 32 elements has a minimum size of 8 bytes in 64-bit Delphi). With every active 6.7.0 header flag now modelled, the flagreader fills 6 bytes; use the new storedenum helper to drain the remaining 2 padding bytes up to 8 bytes total. The same pattern applies to TSetupFileEntryOption with its foUnusedPadding=56 sentinel; add the matching discard_padding_to(8) call after file_entry's flagreader.finalize(). In TSetupComponentEntry and TSetupTaskEntry, Level narrowed from Integer (4 bytes) to Byte (1 byte). Both fields were already restricted to 0..99 in the compiler, so the storage shrink is purely a wire-format change. Finally Setup.MainFunc.pas adds a third wizard image group on the wizard / decompressor stream for the new WizardBackImageFile directive, in addition to the existing main and small image groups. The same group is duplicated for the dynamic-dark theme that 6.6.0 introduced, matching the existing main/small dark pair. Read the new non-dark group into a new info::wizard_images_back vector (so extraction can later expose it), and read the dark back-image group into a discarded local. Both are gated to ``>= 6.7.0`` and sit on exactly the same fork between the two pre-existing groups and the decompressor DLL block as the 6.6.0 dynamic-dark groups. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
dscho
added a commit
to dscho/MINGW-packages
that referenced
this pull request
May 15, 2026
Recent Git for Windows installers are built with Inno Setup 6.7.x, and the currently-packaged innoextract bails out on the SetupID magic for any Inno Setup version newer than 6.4.1. That is a concrete regression for users who rely on innoextract to inspect or unpack Git for Windows installers, and presumably other installers built with current Inno Setup releases. To address that, dscharrer/innoextract#210 adds on-disk format support for Inno Setup 6.4.2, 6.4.3, 6.5.0 through 6.5.4, 6.6.0, 6.6.1, 6.7.0, and 6.7.1, in 11 commits on top of the upstream dscharrer/innoextract master tip. That PR is currently a draft upstream. Rather than pointing _commit at a personal fork carrying those commits, keep this package close to upstream: _commit stays pinned to the upstream tip, the 11 commits are exported via git format-patch and applied in prepare() with a patch -Np1 loop, and only pkgrel is bumped. Once dscharrer/innoextract#210 is merged, the patches can be dropped and _commit re-pinned to a commit that already contains them. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
lazka
pushed a commit
to msys2/MINGW-packages
that referenced
this pull request
May 18, 2026
Recent Git for Windows installers are built with Inno Setup 6.7.x, and the currently-packaged innoextract bails out on the SetupID magic for any Inno Setup version newer than 6.4.1. That is a concrete regression for users who rely on innoextract to inspect or unpack Git for Windows installers, and presumably other installers built with current Inno Setup releases. To address that, dscharrer/innoextract#210 adds on-disk format support for Inno Setup 6.4.2, 6.4.3, 6.5.0 through 6.5.4, 6.6.0, 6.6.1, 6.7.0, and 6.7.1, in 11 commits on top of the upstream dscharrer/innoextract master tip. That PR is currently a draft upstream. Rather than pointing _commit at a personal fork carrying those commits, keep this package close to upstream: _commit stays pinned to the upstream tip, the 11 commits are exported via git format-patch and applied in prepare() with a patch -Np1 loop, and only pkgrel is bumped. Once dscharrer/innoextract#210 is merged, the patches can be dropped and _commit re-pinned to a commit that already contains them. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This series teaches
innoextractto parse installers built with Inno Setup 6.4.2 through 6.7.1. Upstream currently bails out on the newSetupIDmagic strings, and even past that point the on-disk layout has changed substantially across the 6.4.x, 6.5.x, 6.6.x and 6.7.x lines (new header fields, the encryption metadata moved out ofTSetupHeaderinto a separate outer-streamTSetupEncryptionHeader, anISSigkey array between directories and files, 64-bit offsets and sizes, dark-mode wizard image groups, padding bytes in the option bitsets, and so on). The motivation is concrete: recent Git for Windows installers are built with Inno Setup 6.7.x, andinnoextract --info/--listare useful enough on those that I wanted them to keep working.Opening as a draft because I''d like your eyes on the structural choices before polishing.
The 11 commits are split so each one builds and runs independently (verified via
git rebase --exec ''ninja innoextract''from the upstream merge-base). Each commit message cites the relevantProjects/Src/Shared.Struct.passnippets at the correspondingis-X_Y_Ztag of https://github.com/jrsoftware/issrc as evidence, so the per-version deltas can be cross-checked against issrc directly rather than against my prose.Roughly, the shape is: commit 1 adds the setup loader v2 offset table (Inno Setup 6.5.0+) in a minimal form that truncates back to uint32 so the seek chain need not change yet; commits 2, 3, 4 cover the simple per-version magic strings plus straightforward header field additions and the
TSetupHeaderOptionreshuffle through 6.6.1; commit 5 is a pure type widening ofoffsets,chunk_locationandslice_reader::seekto 64 bits with no behaviour change; commit 6 then makes the loader-v2 path and the 6.7.0 block header consume native Int64, so >4 GiB installers are parsed without silent truncation; commit 7 addsbytes_consumed()anddiscard_padding_to(target)helpers onstored_flag_reader<>; commits 8, 9, 10 cover the 6.5.0 / 6.5.2 / 6.6.0 entry stream reworks (encryption header split-out, theTSetupISSigKeyEntryarray, the optional 7-Zip DLL outer stream, theTSetupFileEntryandTSetupFileLocationEntryreshuffles, the 64-bitStartOffset, theTSetupLanguageEntryrework, dynamic-dark wizard images); commit 11 covers the 6.7.0 / 6.7.1 changes (the fiveshUsePrevious*flags promoted out of the option bitset into expression-string header fields, three new wizard colour fields,TSetupWizardLightControlStyling, theshUnusedPadding=56/foUnusedPadding=56padding handled viadiscard_padding_to(8),Levelnarrowing on components and tasks, and the newWizardBackImageFileimage group).A few design points worth flagging explicitly, since they are deliberate and a reviewer might otherwise pick at them:
For 6.5.0+ installers,
TSetupHeadernow clearspassword.typeandpassword_saltrather than leavingpassword.type = PBKDF2_SHA256_XChaCha20. With the encryption metadata moved out to the outer-streamTSetupEncryptionHeader, leaving the in-header password type set would make--inforeport "Setup is passworded!" for every 6.5.0+ installer regardless of whetherEncryptionUseis actuallyeuNone. Clearing it preserves the upstream "Setup is not passworded!" output for the unencrypted case.The 6.7.0 bitset padding is handled via
flagreader.discard_padding_to(8)rather than hard-coded byte reads, so it survives future flag-count changes within innoextract itself without re-derivation of the padding constant.ISSig keys are loaded into a proper
issig_key_entrystruct via the standardload_entries(...)mechanism (newsrc/setup/issigkey.{cpp,hpp}, newISSigKeysentry_typesflag, newinfo::issig_keysvector). Callers that opt in viaISSigKeysget the keys; callers that don''t get the same skip-only behaviour the inline path would have had.The per-file ISSig SHA-256 digest is stored in the existing (and, on the relevant code path, previously unread)
file_entry::checksumfield rather than a newly inventedverification_checksum. The trailing unconditionalchecksum.type = crypto::Nonereset is gated to< 6.5.0so the hash survives.Verification I ran locally:
innoextract --infoagainst a 6.7.0 Git for Windows installer reportsInspecting "Git" - setup data version 6.7.0 (unicode),Setup is not passworded!,Done., and exits 0;innoextract --liston the same installer enumerates 9409 entries, all paths within the installer; andgit rebase --exec ''ninja innoextract''from the upstream merge-base succeeds for all 11 intermediate trees.Out of scope for this series, deliberately:
The
CMakeLists.txtBoost 1.89.0 build fix and the CI-matrix updates from #205 are not included here. Happy to fold them in (or send a separate PR) if you''d prefer.Decryption of 6.5.0+ encrypted installers is not implemented. The
TSetupEncryptionHeaderis parsed and validated, butEncryptionUse != euNoneproduces a warning and the file body is not decoded.Dark-mode wizard images (6.6.0+) and the dark variant of the 6.7.0 back-image group are read for stream alignment but not surfaced beyond the new
info::wizard_images_backvector for the non-dark 6.7.0 group.For transparency: #205 by @pelya is a parallel in-flight attempt at the same scope, also still in draft. This series was developed independently; I used #205 only as a confirmation reference for which Inno Setup version first touched which field, not as a source to copy from. There are several deliberate divergences from #205 worth being aware of when you compare them, namely the
password.typeclearing for 6.5.0+, the native 64-bit consumption in the loader-v2 and block paths rather than truncation back to 32-bit, thediscard_padding_to(8)helper instead of hard-coded padding reads, the< 6.4.3gate (rather than< 6.5.0) for theTSetupFileLocationEntrycleanup based on issrc commits6aec0a55and00d335b7first appearing atis-6_4_3, the dedicatedissig_key_entrydata structure rather than skip-only handling, and the reuse of the existingfile_entry::checksumfield for the per-file ISSig digest. I''m happy to coordinate with @pelya if you''d rather take one branch as the basis and have the other rebased on top.