Rather than write a program to do that, I instead wrote a script that generates zip files from scratch, writing the offsets correctly as it goes.
You don’t have to write a program to do that, you can use the ordinary InfoZIP zip tool (the standard on most Unix machines) with the -A or --adjust-sfx option. From the manual page:
Adjust self-extracting executable archive. A self-extracting executable archive is created by prepending the SFX stub to an existing archive. The -A option tells zip to adjust the entry offsets stored in the archive to take into account this “preamble” data.
Of course, the ZIP file format is quirky and historical and still relevant, so even if you don’t have to learn about it, it’s useful to do so!
Since the post doesn’t spell this out I will mention that LÖVE has built-in support for this too, you can simply append the zip to the end of the love executable itself. This is sometimes called fused mode.
Interesting, so we are violating the spec, but the unzipper libraries are just able to figure it out anyway.
I have known for a while that you could prepend arbitrary data to a ZIP and have it still work, but this is my first time hearing that it results in a technically-corrupt archive! (As opposed to following the spec to the letter, but exploiting a loophole in it.)
I wonder what the specific miracle is that allows decompression software to figure this out and read the contents anyway. There must be something in the end-of-file directory that identifies the correct size of the archive (her example with unzip identifies that there are exactly 102 extra bytes), and then the software adds a correction factor to each offset before seeking to it? Either that, or it scans forward from the incorrect offset until it finds something that looks like a file header.
You don’t have to write a program to do that, you can use the ordinary InfoZIP
ziptool (the standard on most Unix machines) with the-Aor--adjust-sfxoption. From the manual page:Of course, the ZIP file format is quirky and historical and still relevant, so even if you don’t have to learn about it, it’s useful to do so!
Since the post doesn’t spell this out I will mention that LÖVE has built-in support for this too, you can simply append the zip to the end of the love executable itself. This is sometimes called fused mode.
The “boot” process can be seen here.
I have known for a while that you could prepend arbitrary data to a ZIP and have it still work, but this is my first time hearing that it results in a technically-corrupt archive! (As opposed to following the spec to the letter, but exploiting a loophole in it.)
I wonder what the specific miracle is that allows decompression software to figure this out and read the contents anyway. There must be something in the end-of-file directory that identifies the correct size of the archive (her example with
unzipidentifies that there are exactly 102 extra bytes), and then the software adds a correction factor to each offset before seeking to it? Either that, or it scans forward from the incorrect offset until it finds something that looks like a file header.