adm-zip
adm-zip copied to clipboard
Zip build on windows are not POSIX compliant
I had an issue with my CLI when used on Windows the ZIP was not readable on certain picky env like JAVA.
So I created a test in GitHub action for that and found the issue
You can see the result here: https://github.com/Cap-go/CLI/actions/runs/9634029990/job/26569222957 I created a zip with the lib in windows and tried with java and swift to open it, and it fails in Java.
My current fix is to use jszip for windows env, but it's not maintained, I would be glad if we managed to fix it here and I keep only using adm-zip.
the java test i run
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class VerifyZip {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java VerifyZip <zip-file>");
System.exit(1);
}
String zipFilePath = args[0];
File zipFile = new File(zipFilePath);
File targetDirectory = new File("extracted");
if (!zipFile.exists()) {
System.out.println("File not found: " + zipFilePath);
System.exit(1);
}
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(zipFile));
ZipInputStream zis = new ZipInputStream(bis)
) {
int count;
int bufferSize = 8192;
byte[] buffer = new byte[bufferSize];
long lengthTotal = zipFile.length();
long lengthRead = bufferSize;
int percent = 0;
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().contains("\\")) {
System.out.println("Windows path is not supported: " + entry.getName());
System.exit(1);
}
File file = new File(targetDirectory, entry.getName());
String canonicalPath = file.getCanonicalPath();
String canonicalDir = targetDirectory.getCanonicalPath();
File dir = entry.isDirectory() ? file : file.getParentFile();
if (!canonicalPath.startsWith(canonicalDir)) {
System.out.println("SecurityException, Failed to ensure directory is the start path: " +
canonicalDir + " of " + canonicalPath);
System.exit(1);
}
if (!dir.isDirectory() && !dir.mkdirs()) {
System.out.println("Failed to ensure directory: " + dir.getAbsolutePath());
System.exit(1);
}
if (entry.isDirectory()) {
continue;
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
while ((count = zis.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
}
int newPercent = (int) ((lengthRead / (float) lengthTotal) * 100);
if (lengthTotal > 1 && newPercent != percent) {
percent = newPercent;
}
lengthRead += entry.getCompressedSize();
}
System.out.println("ZIP file is valid: " + zipFilePath);
} catch (IOException e) {
System.out.println("Failed to process ZIP file: " + zipFilePath);
e.printStackTrace();
System.exit(1);
}
}
}
The github action who could be adapted
name: Check POSIX Paths in Zip File
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
create-valid-zip-linux:
if: ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup bun
uses: oven-sh/[email protected]
with:
bun-version: latest
- name: Install dependencies
id: install_code
run: bun install --frozen-lockfile
- name: Build code
id: build_code
run: bun run build
- name: Create a valid zip test
id: create_zip
run: node ./dist/index.js bundle zip --path test/test_upload -n build-linux.zip
- name: Check build directory contents
run: |
echo "Listing contents of the build directory..."
ls -R ./dist
- name: Check ZIP file contents
run: |
echo "Listing contents of the ZIP file..."
unzip -l build-linux.zip
- name: Upload build-linux.zip artifact
uses: actions/upload-artifact@v4
with:
name: build-zip-linux
path: build-linux.zip
check-posix-paths-windows:
runs-on: ${{ matrix.os }}
if: ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }}
strategy:
matrix:
os: [windows-2019, windows-2022]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup bun
uses: oven-sh/[email protected]
with:
bun-version: latest
- name: Install dependencies
id: install_code
run: bun install --frozen-lockfile
- name: Build code
id: build_code
run: bun run build
- name: Create a zip test
id: create_zip
run: node ./dist/index.js bundle zip --path test/test_upload -n build-${{ matrix.os }}.zip
- name: Upload build.zip artifact
uses: actions/upload-artifact@v4
with:
name: build-zip-${{ matrix.os }}
path: build-${{ matrix.os }}.zip
check-posix-paths-unix:
runs-on: ubuntu-latest
needs: [create-valid-zip-linux, check-posix-paths-windows]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download build-linux.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-linux
- name: List the files
run: ls -lh
- name: Check file size of Linux build
run: ls -lh build-linux.zip
- name: Verify ZIP file integrity for Linux build with zipinfo
run: |
echo "Verifying ZIP file integrity for Linux build with zipinfo..."
zipinfo ./build-linux.zip || (echo "ZIP file is corrupted: build-linux.zip" && exit 1)
- name: Verify POSIX paths for Linux build
run: |
unzip build-linux.zip -d extracted-linux
if find extracted-linux -type f | grep -qE '\\\\'; then
echo "Non-POSIX paths detected in build-linux.zip."
exit 1
else
echo "All paths are POSIX compliant in build-linux.zip."
fi
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- name: Compile VerifyZip.java
run: javac ./test/VerifyZip.java
- name: Verify ZIP file integrity for Linux build with Java
run: java -cp ./test VerifyZip build-linux.zip
- name: Download build-windows-2019.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-windows-2019
- name: Download build-windows-2022.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-windows-2022
- name: List the files
run: ls -lh
- name: Check file sizes of Windows builds
run: |
echo "Checking file sizes..."
ls -lh build-windows-2019.zip
ls -lh build-windows-2022.zip
- name: Verify ZIP file integrity for Windows 2019 build with zipinfo
run: |
echo "Verifying ZIP file integrity for Windows 2019 build with zipinfo..."
zipinfo ./build-windows-2019.zip || (echo "ZIP file is corrupted: build-windows-2019.zip" && exit 1)
- name: Verify ZIP file integrity for Windows 2022 build with zipinfo
run: |
echo "Verifying ZIP file integrity for Windows 2022 build with zipinfo..."
zipinfo ./build-windows-2022.zip || (echo "ZIP file is corrupted: build-windows-2022.zip" && exit 1)
- name: Verify POSIX paths for Windows 2019 build
run: |
unzip build-windows-2019.zip -d extracted-2019
if find extracted-2019 -type f | grep -qE '\\\\'; then
echo "Non-POSIX paths detected in build-windows-2019.zip."
exit 1
else
echo "All paths are POSIX compliant in build-windows-2019.zip."
fi
- name: Verify POSIX paths for Windows 2022 build
run: |
unzip build-windows-2022.zip -d extracted-2022
if find extracted-2022 -type f | grep -qE '\\\\'; then
echo "Non-POSIX paths detected in build-windows-2022.zip."
exit 1
else
echo "All paths are POSIX compliant in build-windows-2022.zip."
fi
- name: Verify ZIP file integrity for Windows 2019 build with Java
run: java -cp ./test VerifyZip build-windows-2019.zip
- name: Verify ZIP file integrity for Windows 2022 build with Java
run: java -cp ./test VerifyZip build-windows-2022.zip
check-posix-paths-macos:
runs-on: macos-latest
needs: [create-valid-zip-linux, check-posix-paths-windows]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download build-linux.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-linux
- name: Download build-windows-2019.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-windows-2019
- name: Download build-windows-2022.zip artifact
uses: actions/download-artifact@v4
with:
name: build-zip-windows-2022
- name: List the files
run: ls -lh
- name: Check file size of Linux build
run: ls -lh build-linux.zip
- name: Setup Swift
uses: swift-actions/setup-swift@v2
- name: Get swift version
run: swift --version # Swift 5.10
- name: Compile test executable
run: swift build -c release
working-directory: ./test/test_zip_swift/
- name: Run the swift test
run: ./test/test_zip_swift/.build/release/MyCLI --zip-files build-linux.zip build-windows-2019.zip build-windows-2022.zip
```
Could be linked to https://github.com/cthackers/adm-zip/issues/497
Maybe it could be nice if we could force the behavior like in JSZIP:
Hmm, can you take code directly from github repo.
I believe #497 was fixed in repo, but this fix is not released in npm
May I ask when will it be released? @5saviahv
May I ask when will it be released? @5saviahv
Sadly, I have no good aswer for that. Currently only @cthackers can make releases in npm.