iBotPeaches/Apktool · warning · InvalidPathException
Path is null or empty
Error message
Path is null or empty
What it means
BrutIO.sanitizePath rejects a path argument that is null or empty before doing any traversal checks. It is the first validation in apktool's zip-slip defense: paths coming from archive entries must be non-empty relative paths. InvalidPathException is thrown carrying the offending path and this reason.
Source
Thrown at brut.j.util/src/main/java/brut/util/BrutIO.java:103
}
}
}
return modified;
}
public static CRC32 calculateCrc(InputStream in) throws IOException {
CRC32 crc = new CRC32();
int bytesRead;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer)) != -1) {
crc.update(buffer, 0, bytesRead);
}
return crc;
}
public static String sanitizePath(File baseDir, String path) throws InvalidPathException, IOException {
if (path == null || path.isEmpty()) {
throw new InvalidPathException(path, "Path is null or empty");
}
Path origPath = Paths.get(path);
if (origPath.isAbsolute()) {
throw new InvalidPathException(path, "Absolute paths are not allowed");
}
Path basePath = Paths.get(baseDir.getCanonicalPath());
Path resolvedPath = basePath.resolve(origPath).normalize();
if (!resolvedPath.startsWith(basePath)) {
throw new InvalidPathException(path, "Path traverses outside the base directory");
}
return basePath.relativize(resolvedPath).toString();
}
}
View on GitHub (pinned to 79b63384d7)
Solutions
- Filter entries before sanitizing: skip null/empty names (often pure directory markers)
- Fix the producer side if you control archive creation so entries always have names
- Guard call sites that may legitimately have no path (optional attributes) instead of passing null
- Keep the other sanitizePath rules in mind too: absolute paths and traversal outside baseDir are rejected next
Example fix
// before
for (ZipEntry e : zipEntries) {
Path p = Path.of(BrutIO.sanitizePath(baseDir, e.getName())); // empty dir-entry name throws
}
// after
for (ZipEntry e : zipEntries) {
String name = e.getName();
if (name == null || name.isEmpty()) {
continue; // directory marker or malformed entry; nothing to extract
}
Path p = Path.of(BrutIO.sanitizePath(baseDir, name));
} Defensive patterns
Strategy: validation
Validate before calling
String name = entry.getName();
if (name == null || name.isEmpty()) {
continue; // skip empty/dir-marker entries before sanitizing
}
Path safe = Path.of(BrutIO.sanitizePath(baseDir, name)); Type guard
boolean isSanitizablePath(String path) {
return path != null && !path.isEmpty();
} Try / catch
try {
Path p = Path.of(BrutIO.sanitizePath(baseDir, name));
} catch (InvalidPathException e) {
if ("Path is null or empty".equals(e.getReason())) {
// skip the entry (usually a directory marker) rather than aborting extraction
} else {
// other rejections: absolute path or traversal — log and quarantine the archive
}
} Prevention
- Filter null/empty entry names before extraction loops
- Treat sanitizePath rejections as untrusted-input signals, not crashes
- Also guard the next rules: reject absolute paths and traversal outside baseDir explicitly
When it happens
Trigger: Calling sanitizePath(baseDir, null) or sanitizePath(baseDir, ""), typically because an archive contained an entry whose name was empty, or because calling code passed an unvalidated/absent name field.
Common situations: Repacking archives that contain directory-only entries represented by empty names; programmatically iterating entries and passing a missing attribute; malformed zips produced by third-party packers.
Related errors
- Absolute paths are not allowed
- Path traverses outside the base directory
- Malicious value for apkFileName: " + mApkFileName
- Mark not supported
- Mark not set
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/6abd26d473b320b0.
Report an issue: GitHub.