Skip to content

Commit

Permalink
Implement Open/Close Zip File
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeLtDave authored and Michael5601 committed May 14, 2024
1 parent 0196f11 commit 2707f57
Show file tree
Hide file tree
Showing 36 changed files with 2,051 additions and 581 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.core.filesystem; singleton:=true
Bundle-Version: 1.10.400.qualifier
Bundle-Version: 1.11.0.qualifier
Bundle-Localization: plugin
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.18.0,4.0.0)",
org.eclipse.equinox.registry;bundle-version="[3.2.0,4.0.0)",
Expand Down
7 changes: 7 additions & 0 deletions resources/bundles/org.eclipse.core.filesystem/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,11 @@
<run class="org.eclipse.core.internal.filesystem.NullFileSystem"/>
</filesystem>
</extension>
<extension
id="org.eclipse.core.filesystem.zip"
point="org.eclipse.core.filesystem.filesystems">
<filesystem scheme="zip">
<run class="org.eclipse.core.internal.filesystem.zip.ZipFileSystem"/>
</filesystem>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.eclipse.core.filesystem;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.internal.filesystem.zip.ZipFileStore;
import org.eclipse.core.runtime.CoreException;

/**
* Utility class to determine if a file is an archive based on file header information.
* This class checks for known file signatures to identify if a given file is a ZIP archive
* or a format based on ZIP, such as EPUB, JAR, ODF, and OOXML.
*
* @since 1.11
*/
public class ZipFileUtil {

private static final Set<Integer> ARCHIVE_FILE_SIGNATURES = new HashSet<>();

static {
// Initializes known archive file signatures from Wikipedia's list of file signatures
// (https://en.wikipedia.org/wiki/List_of_file_signatures)
ARCHIVE_FILE_SIGNATURES.add(0x504B0304); // Standard ZIP file
ARCHIVE_FILE_SIGNATURES.add(0x504B0506); // Empty archive
ARCHIVE_FILE_SIGNATURES.add(0x504B0708); // Spanned archive
}

/**
* Determines if the given {@link IFileStore} represents an open ZIP file.
* This can be used to check if operations on a ZIP file should be allowed or handled differently.
*
* @param store The file store to check.
* @return true if the store is an instance of {@link ZipFileStore}, false otherwise.
*/
public static boolean isInsideOpenZipFile(IFileStore store) {
return store instanceof ZipFileStore;
}

public static boolean isInsideOpenZipFile(URI locationURI) {
IFileStore store;
try {
store = EFS.getStore(locationURI);
} catch (CoreException e) {
return false;
}
return isInsideOpenZipFile(store);
}

/**
* Checks if the provided {@link InputStream} represents a ZIP archive
* by reading its first four bytes and comparing them against known ZIP file signatures.
* This method throws {@link IOException} if the file signature does not match any known ZIP archive signatures.
*
* @param fis The {@link InputStream} of the file to check.
* @throws IOException If the file signature does not match known ZIP archive signatures
* or an I/O error occurs during reading from the stream.
*/
public static void checkFileForZipHeader(InputStream fis) throws IOException {
byte[] bytes = new byte[4];
if (fis.read(bytes) == bytes.length) {
ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
int header = buffer.getInt();

if (!ARCHIVE_FILE_SIGNATURES.contains(header)) {
throw new IOException("Invalid archive file signature."); //$NON-NLS-1$
}
}
}
}
Loading

0 comments on commit 2707f57

Please sign in to comment.