data:;base64,aGVsbG8=
image.png
, background.png
style.css
,
properties.css
script.js
project/
folderProject structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
Project structure
project/index.html
project/script.js
project/style.css
project/properties.css
project/image.png
project/background.png
DEFLATE
format since version 2.0 (1993)
AES
encryption since version 5.2 (2003).ODT
, .DOCX
,
...).JAR
).APK
and Archives iOS .IPA
)
.CRX
and .XPI
)CompressionStream
APIExample of ZIP file creation
import { ZipWriter, Uint8ArrayWriter } from "@zip-js/zip-js"
const zipDataWriter = new Uint8ArrayWriter()
const zipWriter = new ZipWriter(zipDataWriter)
for await (const { name } of readDirectory(inputFolder)) {
const readableStream = await readFileStream(name)
await zipWriter.add(name, readableStream)
}
await zipWriter.close()
const zipData = zipDataWriter.getData() // Uint8Array
console.log("zip file data:", zipData)
Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
Creation of the ZIP file
index.html
index.js
lib/utils-zip.js
Example of reading a ZIP file
import { ZipReader, BlobReader, BlobWriter } from "@zip-js/zip-js"
const zipReader = new ZipReader(new BlobReader(blob))
const entries = await zipReader.getEntries()
for (const entry of entries) {
const blob = await entry.getData(new BlobWriter())
console.log("file:", entry.filename, "blob:", blob)
}
await zipReader.close()
Reading the ZIP file
index.html
index.js
Reading the ZIP file
index.html
index.js
Reading the ZIP file
<!--
-->
and end of HTML contentSelf-extracting HTML file template
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Please wait...</title>
<script><!-- Content of assets/zip.min.js --></script>
</head>
<body>
<p>Please wait...</p>
<script><!-- Content of assets/main.js --></script>
</body>
</html>
Self-extracting HTML file template
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Please wait...</title> <script><!-- Content of assets/zip.min.js --></script> </head> <body> <p>Please wait...</p> <!--
ZIP data
--> <script><!-- Content of assets/main.js --></script> </body> </html>
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
1/4 - Extracting and displaying ZIP file entries
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
2/4 - Displaying the index.html
page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
3/4 - Displaying the full page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Inactive JavaScript code ⚠️
4/4 - Scripts support
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Reading the page from the file system ⚠️
await fetch("")
Node#textContent
(in UTF-16
)windows-1252
) versus
multiple bytes (e.g. UTF-8
)
U+FFFD
replacement characters for
characters whose code is 0
or invalid (depending on encoding) \n
of the characters:
\r
\r\n
ASCII 7-bit
tableHexadecimal display of ZIP data read as text
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
UTF-8
:
windows-1252
:
Comparison of the impact of different 1-byte encodings
U+FFFD
(first
column)Comparison of the impact of different 1-byte encodings
Changes in the HTML template
UTF-8
encoding with windows-1252
\r
\r\n
<script>
tag
Self-extracting HTML file template (before)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Please wait...</title>
<script><!-- Content of assets/zip.min.js --></script>
</head>
<body>
<p>Please wait...</p><!--
ZIP data
-->
<script><!-- Content of assets/main.js --></script>
</body>
</html>
Self-extracting HTML file template (after)
<!DOCTYPE html>
<html>
<head>
<meta charset="windows-1252">
<title>Please wait...</title>
<script><!-- Content of assets/zip.min.js --></script>
</head>
<body>
<p>Please wait...</p><!--
ZIP data
-->
<script><!-- Content of assets/main.js --></script>
</body>
</html>
Self-extracting HTML file template (after)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> <title>Please wait...</title> <script><!-- Content of assets/zip.min.js --></script> </head> <body> <p>Please wait...</p><!-- ZIP data --> <script type="application/json">
Consolidation data
</script> <script><!-- Content of assets/main.js --></script> </body> </html>
Support for consolidation data in the HTML template
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Support for consolidation data in the HTML template
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Adding consolidation data to the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Bypassing the call to await fetch("")
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Bypassing the call to await fetch("")
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
Page resources are decoded in windows-1252
⚠️
Correction of MIME type issues in external resources
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
assets/main.js
DEFLATE
)IHDR
, IDAT
,
IEND
, tEXt
...
CRC32
) computed from all the chunk
data89 50 4E 47 0D 0A 1A 0A
IHDR
chunk for the header (13 bytes)
00 00 00 0D 49 48 44 52 ...
IDAT
chunk(s) for the data
IEND
chunk for the trailer (12 bytes)
00 00 00 00 49 45 4E 44 AE 42 60 82
tEXt
chunk to store text or binary data
xx xx xx xx 74 45 58 74 ...
Minimal PNG file structure
Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
---|---|---|---|---|
PNG signature | 89 50 4E 47 0D 0A 1A 0A |
✓ | 8 |
|
Header chunk | IHDR |
00 00 00 0D 49 48 44 52 ... |
✓ | 13 |
... | ||||
Data chunk | IDAT |
xx xx xx xx 49 44 41 54 ... |
12 + n |
|
... | ||||
Trailer chunk | IEND |
00 00 00 00 49 45 4E 44 AE 42 60 82 |
✓ | 12 |
<!--
-->
and end of HTML content
PNG file structure (before)
Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
---|---|---|---|---|
PNG signature | 89 50 4E 47 0D 0A 1A 0A |
✓ | 8 |
|
Header chunk | IHDR |
00 00 00 0D 49 48 44 52 ... |
✓ | 13 |
... | ||||
Data chunk | IDAT |
xx xx xx xx 49 44 41 54 ... |
12 + n |
|
... | ||||
Trailer chunk | IEND |
00 00 00 00 49 45 4E 44 AE 42 60 82 |
✓ | 12 |
PNG file structure (after)
Data type | Data in hexadecimal | Mandatory | Length (bytes) | |
---|---|---|---|---|
PNG signature | 89 50 4E 47 0D 0A 1A 0A |
✓ | 8 |
|
Header chunk | IHDR |
00 00 00 0D 49 48 44 52 ... |
✓ | 13 |
Text chunk | tEXt |
xx xx xx xx 74 45 58 74 ... |
12 + n |
|
... | ||||
Data chunk | IDAT |
xx xx xx xx 49 44 41 54 ... |
12 + n |
|
... | ||||
Text chunk | tEXt |
xx xx xx xx 74 45 58 74 ... |
12 + n |
|
Trailer chunk | IEND |
00 00 00 00 49 45 4E 44 AE 42 60 82 |
✓ | 12 |
Self-extracting HTML file template (before)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--
ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>
Self-extracting HTML file template (after)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--
IDAT chunk(s)
--><!-- ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>
Self-extracting HTML file template (after)
PNG signature + IHDR chunk (21 bytes)
<!DOCTYPE html> <html> <head> <meta charset="windows-1252"> ... </head> <body> <p>Please wait...</p><!--
IDAT chunk(s)
--><!-- ZIP data --><script type="application/json"> Consolidation data </script> <script><!-- Content of assets/main.js --></script> </body> </html>
IEND chunk (12 bytes)
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Encapsulation of the HTML/ZIP file into a PNG file
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
Text nodes induced by the PNG format are visible ⚠️
Removal of text nodes induced by PNG format
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
The page is rendered in quirks mode ⚠️
Correction of HTML page rendering mode and script loading
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
The main image is stored twice in the file 🤔
Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
Reuse of the image in the HTML page
index.html
index.js
lib/html-template.js
lib/utils.js
lib/utils-zip.js
lib/utils-png.js
assets/main.js
project/index.html
-->
in ZIP or PNG binary dataString#replaceAll()
to replace paths in text files
instead of relying on parsing<meta>
tag containing the Content
Security Policy (CSP)
Questions? 🤔, Feedback? 📝