{"record":{"id":"fcbfaf6315da2124","repo":"lingochamp/FileDownloader","slug":"found-invalid-internal-destination-filename-s","errorCode":null,"errorMessage":"found invalid internal destination filename %s","messagePattern":"found invalid internal destination filename (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java","lineNumber":689,"sourceCode":"            throw new FileDownloadSecurityException(FileDownloadUtils.formatString(\n                    \"The filename [%s] from the response is not allowable, because it contains \"\n                            + \"'../', which can raise the directory traversal vulnerability\",\n                    filename));\n        }\n\n        return filename;\n    }\n\n    public static FileDownloadOutputStream createOutputStream(final String path)\n            throws IOException {\n\n        if (TextUtils.isEmpty(path)) {\n            throw new RuntimeException(\"found invalid internal destination path, empty\");\n        }\n\n        //noinspection ConstantConditions\n        if (!FileDownloadUtils.isFilenameValid(path)) {\n            throw new RuntimeException(\n                    FileDownloadUtils.formatString(\"found invalid internal destination filename\"\n                            + \" %s\", path));\n        }\n\n        File file = new File(path);\n\n        if (file.exists() && file.isDirectory()) {\n            throw new RuntimeException(\n                    FileDownloadUtils.formatString(\"found invalid internal destination path[%s],\"\n                            + \" & path is directory[%B]\", path, file.isDirectory()));\n        }\n        if (!file.exists()) {\n            if (!file.createNewFile()) {\n                throw new IOException(\n                        FileDownloadUtils.formatString(\"create new file error  %s\",\n                                file.getAbsolutePath()));\n            }\n        }","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/lingochamp/FileDownloader/blob/6237a8cac174bcc916e4342b14ab1ab72a5768d4/library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java#L671-L707","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Sanitize the filename before building the path: keep only the segment after the last '/' and strip illegal characters.","Let the library derive the filename via FileDownloadUtils.generateFileName(url) (MD5 of URL) instead of trusting server names.","Pre-validate with FileDownloadUtils.isFilenameValid(path) at the call site and reject/normalize invalid names.","Set an explicit safe path with task.setPath(...) so server data never shapes the local filename."],"exampleFix":"// before\nString path = dir + File.separator + headerFilename; // may contain '/'\nFileDownloadUtils.createOutputStream(path);\n\n// after\nString safe = headerFilename.replaceAll(\"[/\\\\\\\\]\", \"_\");\nString path = dir + File.separator + safe;\nif (!FileDownloadUtils.isFilenameValid(path)) {\n    path = dir + File.separator + FileDownloadUtils.generateFileName(url);\n}\nFileDownloadUtils.createOutputStream(path);","handlingStrategy":"validation","validationCode":"String path = dir + File.separator + candidateName;\nif (!FileDownloadUtils.isFilenameValid(path)) {\n    path = dir + File.separator + FileDownloadUtils.generateFileName(url);\n}","typeGuard":"boolean isFilenameValid(String p) { return p != null && FileDownloadUtils.isFilenameValid(p); }","tryCatchPattern":"try {\n    stream = FileDownloadUtils.createOutputStream(path);\n} catch (RuntimeException e) {\n    String fallback = dir + File.separator + FileDownloadUtils.generateFileName(url);\n    stream = FileDownloadUtils.createOutputStream(fallback);\n}","preventionTips":["Sanitize server/header-derived filenames: strip path separators and control characters.","Prefer library-generated hash filenames (generateFileName) over raw server names.","Run isFilenameValid on any path built from external input before writing."],"tags":["android","file-io","invalid-filename","filedownloader"],"backgroundTag":"invalid-argument-value","analyzedSha":"6237a8cac174bcc916e4342b14ab1ab72a5768d4","analyzedAt":"2026-09-08T23:50:48.168Z","contentChangedAt":"2026-09-08T23:50:48.168Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}