lingochamp/FileDownloader · error · RuntimeException

found invalid internal destination filename

Error message

found invalid internal destination filename %s

What it means

After checking the path is non-empty, createOutputStream validates the filename characters via isFilenameValid(path). A path containing illegal filename characters (e.g. path separators inside the filename portion, control chars) cannot be safely written, so the library throws a RuntimeException naming the offending path.

Solutions

  1. Sanitize the filename before building the path: keep only the segment after the last '/' and strip illegal characters.
  2. Let the library derive the filename via FileDownloadUtils.generateFileName(url) (MD5 of URL) instead of trusting server names.
  3. Pre-validate with FileDownloadUtils.isFilenameValid(path) at the call site and reject/normalize invalid names.
  4. Set an explicit safe path with task.setPath(...) so server data never shapes the local filename.

Example fix

// before
String path = dir + File.separator + headerFilename; // may contain '/'
FileDownloadUtils.createOutputStream(path);

// after
String safe = headerFilename.replaceAll("[/\\\\]", "_");
String path = dir + File.separator + safe;
if (!FileDownloadUtils.isFilenameValid(path)) {
    path = dir + File.separator + FileDownloadUtils.generateFileName(url);
}
FileDownloadUtils.createOutputStream(path);
Defensive patterns

Strategy: validation

Validate before calling

String path = dir + File.separator + candidateName;
if (!FileDownloadUtils.isFilenameValid(path)) {
    path = dir + File.separator + FileDownloadUtils.generateFileName(url);
}

Type guard

boolean isFilenameValid(String p) { return p != null && FileDownloadUtils.isFilenameValid(p); }

Try / catch

try {
    stream = FileDownloadUtils.createOutputStream(path);
} catch (RuntimeException e) {
    String fallback = dir + File.separator + FileDownloadUtils.generateFileName(url);
    stream = FileDownloadUtils.createOutputStream(fallback);
}

Prevention

When it happens

Trigger: Calling createOutputStream with a path whose filename component contains characters rejected by isFilenameValid — commonly a server-derived filename containing '/' or other illegal characters that slipped through.

Common situations: Using raw Content-Disposition filenames (with slashes or special characters) as the local filename; concatenating user input into the save path; Windows-incompatible characters in the target name.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08). Data as JSON: /api/errors/fcbfaf6315da2124. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java:689

            throw new FileDownloadSecurityException(FileDownloadUtils.formatString(
                    "The filename [%s] from the response is not allowable, because it contains "
                            + "'../', which can raise the directory traversal vulnerability",
                    filename));
        }

        return filename;
    }

    public static FileDownloadOutputStream createOutputStream(final String path)
            throws IOException {

        if (TextUtils.isEmpty(path)) {
            throw new RuntimeException("found invalid internal destination path, empty");
        }

        //noinspection ConstantConditions
        if (!FileDownloadUtils.isFilenameValid(path)) {
            throw new RuntimeException(
                    FileDownloadUtils.formatString("found invalid internal destination filename"
                            + " %s", path));
        }

        File file = new File(path);

        if (file.exists() && file.isDirectory()) {
            throw new RuntimeException(
                    FileDownloadUtils.formatString("found invalid internal destination path[%s],"
                            + " & path is directory[%B]", path, file.isDirectory()));
        }
        if (!file.exists()) {
            if (!file.createNewFile()) {
                throw new IOException(
                        FileDownloadUtils.formatString("create new file error  %s",
                                file.getAbsolutePath()));
            }
        }

View on GitHub (pinned to 6237a8cac1)