Skip to content

Commit c567682

Browse files
committed
Improve normalization logic
Renamed normalizeEntryName to stripLeadingAndTrailingSlashes for better clarity. Enhanced the normalization logic to handle multiple consecutive leading or trailing slashes. Now, any degenerate entries with multiple slashes are properly stripped to ensure consistent and safe entry paths. Removed redundant checks for leading or trailing slashes after normalization. -> Based on Norman Rzepka's suggestion. Since the normalization process now handles all cases, there's no need for further slash-stripping. Updated zip entry processing logic to: Continue using the isDirectory() flag and directoryToChildrenDirectoriesIndex for directory entries. Unified root directory handling, creating indices, no recursion.
1 parent f4e6e90 commit c567682

1 file changed

Lines changed: 14 additions & 22 deletions

File tree

src/main/java/dev/zarr/zarrjava/store/ReadOnlyZipStore.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,27 +107,18 @@ private synchronized void buildZipIndex() {
107107
Enumeration<? extends ZipEntry> en = zf.entries();
108108
while (en.hasMoreElements()) {
109109
ZipEntry e = en.nextElement();
110-
String entryStrippedPath = normalizeEntryName(e.getName());
111-
if (entryStrippedPath.isEmpty()) continue; // guard against odd entries
112-
113-
if (e.isDirectory() || entryStrippedPath.endsWith("/")) {
114-
// Ensure directory entryStrippedPaths end with '/' ... this just complicates
115-
if (entryStrippedPath.endsWith("/")) {
116-
entryStrippedPath = entryStrippedPath.substring(0, entryStrippedPath.length() - 1);
117-
logger.log(Level.WARNING,
118-
"Directory entry '{0}' did end with '/' not removed by normalizeEntryName()",
119-
e.getName());
120-
} else if (entryStrippedPath.startsWith("/")) {
121-
entryStrippedPath = entryStrippedPath.substring(1);
122-
logger.log(Level.WARNING,
123-
"Directory entry '{0}' did start with '/' not removed by normalizeEntryName()",
124-
e.getName());
125-
}
110+
// In some zip files entries may have leading or trailing slashes, we want to ignore those for consistent indexing
111+
// Trailing shashes are common for directory entries, but since we have dedicated directoryToChildrenDirectoriesIndex we strip those and rely on the isDirectory() flag to determine if an entry is a directory or file
112+
String entryStrippedPath = stripLeadingAndTrailingSlashes(e.getName());
113+
114+
if (e.isDirectory()) {
126115
directoryToChildrenDirectoriesIndex.computeIfAbsent(entryStrippedPath,
127116
k -> ConcurrentHashMap.newKeySet());
128117
directoryToChildrenFilesIndex.computeIfAbsent(entryStrippedPath,
129118
k -> ConcurrentHashMap.newKeySet());
130-
insertDirectoryEntry(entryStrippedPath);
119+
if (!entryStrippedPath.isEmpty()) { // Don't insert the root directory itself as an entry
120+
insertDirectoryEntry(entryStrippedPath);
121+
}
131122
} else {
132123
// Put file size (may be -1 for STORED anomalies, but ZipFile usually knows it)
133124
long size = e.getSize();
@@ -371,11 +362,12 @@ public Stream<String> listChildren(String[] prefixKeys) {
371362
}
372363

373364

374-
// Normalize entry names to ensure consistent handling of leading/trailing slashes
375-
// Name of root directory will then be ""
376-
private String normalizeEntryName(String name) {
377-
if (name.startsWith("/")) name = name.substring(1);
378-
if (name.endsWith("/")) name = name.substring(0, name.length() - 1);
365+
// Strip leading and trailing slashes, including multiple occurrences
366+
// For degenerate strings with multiple slashes, they will all be stripped
367+
// The name of the root directory will be an empty string ""
368+
private String stripLeadingAndTrailingSlashes(String name) {
369+
while (name.startsWith("/")) name = name.substring(1);
370+
while (name.endsWith("/")) name = name.substring(0, name.length() - 1);
379371
return name;
380372
}
381373

0 commit comments

Comments
 (0)