From 47b6e3af2bac6c992b23f1a6525e400f853a9916 Mon Sep 17 00:00:00 2001 From: Davy Landman Date: Tue, 17 Mar 2026 17:43:26 +0100 Subject: [PATCH] Fixed a bug where the root of a jar+file or zip uri was always existing, even if the underlying file did not exist --- .../rascalmpl/uri/jar/JarFileResolver.java | 23 +++++++++++++------ .../uri/jar/JarInputStreamResolver.java | 4 ++-- .../rascalmpl/uri/zip/ZipFileResolver.java | 21 +++++++++++------ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/org/rascalmpl/uri/jar/JarFileResolver.java b/src/org/rascalmpl/uri/jar/JarFileResolver.java index 938da017235..9ac73bdf233 100644 --- a/src/org/rascalmpl/uri/jar/JarFileResolver.java +++ b/src/org/rascalmpl/uri/jar/JarFileResolver.java @@ -39,10 +39,19 @@ public class JarFileResolver { .expireAfterAccess(10, TimeUnit.MINUTES) // 10 minutes after last access, drop it .softValues().build(); - protected CompressedFSTree getFileHierchyCache(ISourceLocation jar) { + + private File jarFile(ISourceLocation jar) { + return new File(jar.getPath()); + } + + protected CompressedFSTree getFileHierchyCache(ISourceLocation jar) throws IOException { try { - final File jarFile = new File(jar.getPath()); - return fsCache.get(URIUtil.changeQuery(jar, "mod=" + jarFile.lastModified()), j -> new JarFileTree(jarFile)); + var jarFile = jarFile(jar); + var lastModified = jarFile.lastModified(); + if (lastModified == 0) { + throw new FileNotFoundException("The file " + jar + "does not exist or is a directory"); + } + return fsCache.get(URIUtil.changeQuery(jar, "mod=" + lastModified), j -> new JarFileTree(jarFile)); } catch (URISyntaxException e) { throw new RuntimeException(e); @@ -60,21 +69,21 @@ public InputStream getInputStream(ISourceLocation jar, String path) throws IOExc return jarFile.getInputStream(jarEntry); } - public boolean exists(ISourceLocation jar, String path) { + public boolean exists(ISourceLocation jar, String path) throws IOException { if (path == null || path.isEmpty() || path.equals("/")) { - return true; + return jarFile(jar).isFile(); } return getFileHierchyCache(jar).exists(path); } - public boolean isDirectory(ISourceLocation jar, String path) { + public boolean isDirectory(ISourceLocation jar, String path) throws IOException { if (!path.endsWith("/")) { path = path + "/"; } return getFileHierchyCache(jar).isDirectory(path); } - public boolean isFile(ISourceLocation jar, String path) { + public boolean isFile(ISourceLocation jar, String path) throws IOException { return getFileHierchyCache(jar).isFile(path); } diff --git a/src/org/rascalmpl/uri/jar/JarInputStreamResolver.java b/src/org/rascalmpl/uri/jar/JarInputStreamResolver.java index e7aaa6f63f9..5f2ce440bb3 100644 --- a/src/org/rascalmpl/uri/jar/JarInputStreamResolver.java +++ b/src/org/rascalmpl/uri/jar/JarInputStreamResolver.java @@ -32,7 +32,7 @@ public JarInputStreamResolver(URIResolverRegistry registry) { } @Override - protected CompressedFSTree getFileHierchyCache(ISourceLocation jarLocation) { + protected CompressedFSTree getFileHierchyCache(ISourceLocation jarLocation) throws IOException { try { final ISourceLocation lookupKey = URIUtil.changeQuery(jarLocation, "mod=" + CTX.lastModified(jarLocation)); return fsCache.get(lookupKey, j -> { @@ -44,7 +44,7 @@ protected CompressedFSTree getFileHierchyCache(ISourceLocation jarLocation) { } }); } - catch (URISyntaxException | IOException e) { + catch (URISyntaxException e) { throw new RuntimeException(e); } } diff --git a/src/org/rascalmpl/uri/zip/ZipFileResolver.java b/src/org/rascalmpl/uri/zip/ZipFileResolver.java index 6416aec0dc6..140afd67606 100644 --- a/src/org/rascalmpl/uri/zip/ZipFileResolver.java +++ b/src/org/rascalmpl/uri/zip/ZipFileResolver.java @@ -38,10 +38,17 @@ public class ZipFileResolver { .expireAfterAccess(10, TimeUnit.MINUTES) // 10 minutes after last access, drop it .softValues().build(); - protected CompressedFSTree getFileHierchyCache(ISourceLocation zip) { + private File zipFile(ISourceLocation zip) { + return new File(zip.getPath()); + } + protected CompressedFSTree getFileHierchyCache(ISourceLocation zip) throws IOException { try { - final File zipFile = new File(zip.getPath()); - return fsCache.get(URIUtil.changeQuery(zip, "mod=" + zipFile.lastModified()), j -> new ZipFileTree(zipFile)); + var zipFile = zipFile(zip); + var lastModified = zipFile.lastModified(); + if (lastModified == 0) { + throw new FileNotFoundException("File " + zip + " not found"); + } + return fsCache.get(URIUtil.changeQuery(zip, "mod=" + lastModified), j -> new ZipFileTree(zipFile)); } catch (URISyntaxException e) { throw new RuntimeException(e); @@ -59,21 +66,21 @@ public InputStream getInputStream(ISourceLocation zip, String path) throws IOExc return zipFile.getInputStream(zipEntry); } - public boolean exists(ISourceLocation zip, String path) { + public boolean exists(ISourceLocation zip, String path) throws IOException { if (path == null || path.isEmpty() || path.equals("/")) { - return true; + return zipFile(zip).isFile(); } return getFileHierchyCache(zip).exists(path); } - public boolean isDirectory(ISourceLocation zip, String path) { + public boolean isDirectory(ISourceLocation zip, String path) throws IOException{ if (!path.endsWith("/")) { path = path + "/"; } return getFileHierchyCache(zip).isDirectory(path); } - public boolean isFile(ISourceLocation zip, String path) { + public boolean isFile(ISourceLocation zip, String path) throws IOException { return getFileHierchyCache(zip).isFile(path); }