{"record":{"id":"b4fd5dffdd7067ac","repo":"Blankj/AndroidUtilCode","slug":"segment-of-segment-is-illegal","errorCode":null,"errorMessage":"segment of <{segment}> is illegal","messagePattern":"segment of <(.+?)> is illegal","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/utilcode/src/main/java/com/blankj/utilcode/util/PathUtils.java","lineNumber":65,"sourceCode":"        return newPath;\n    }\n\n    private static String getLegalSegment(String segment) {\n        int st = -1, end = -1;\n        char[] charArray = segment.toCharArray();\n        for (int i = 0; i < charArray.length; i++) {\n            char c = charArray[i];\n            if (c != SEP) {\n                if (st == -1) {\n                    st = i;\n                }\n                end = i;\n            }\n        }\n        if (st >= 0 && end >= st) {\n            return segment.substring(st, end + 1);\n        }\n        throw new IllegalArgumentException(\"segment of <\" + segment + \"> is illegal\");\n    }\n\n    /**\n     * Return the path of /system.\n     *\n     * @return the path of /system\n     */\n    public static String getRootPath() {\n        return getAbsolutePath(Environment.getRootDirectory());\n    }\n\n    /**\n     * Return the path of /data.\n     *\n     * @return the path of /data\n     */\n    public static String getDataPath() {\n        return getAbsolutePath(Environment.getDataDirectory());","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/PathUtils.java#L47-L83","documentation":"PathUtils.getLegalSegment() is called internally by PathUtils.join() to extract the non-separator portion of a child path segment. It throws IllegalArgumentException if the segment consists entirely of separator characters (File.separatorChar), meaning no valid path characters were found. On Linux/Android the separator is '/'; on Windows it would be '\\'.","triggerScenarios":"Calling PathUtils.join(parent, child) where child is a string composed solely of separator characters — e.g., join(\"/data\", \"///\") or join(\"/data\", \"/\"). Also triggered by join(\"/data\", \"\") if TextUtils.isEmpty doesn't catch it (it does catch empty, but whitespace-only non-empty strings like \" \" still pass through and contain a non-separator char, so this specifically targets all-separator strings).","commonSituations":"Building paths from user input or config values that contain trailing/leading/duplicate separators; string concatenation that produces separator-only segments; null-safe defaults that resolve to separator characters.","solutions":["Sanitize the child path before calling join: trim leading/trailing separators and validate it contains at least one non-separator character.","Use a null/empty check plus separator stripping: child = child.replaceAll(\"^/+|/+$\", \"\").","If child may be separator-only, short-circuit: if (child.replaceAll(String.valueOf(File.separatorChar), \"\").isEmpty()) return parent.","Consider using java.nio.file.Paths or java.io.File constructors instead of manual string joins for robust path building."],"exampleFix":"// before\nString path = PathUtils.join(\"/data/app\", \"///\"); // throws\n\n// after\nString child = \"///\";\nif (child != null && !child.replace(\"/\", \"\").isEmpty()) {\n    String path = PathUtils.join(\"/data/app\", child);\n} else {\n    // handle invalid child\n}","handlingStrategy":"validation","validationCode":"// Sanitize child path before calling join\nString child = getUserInput();\nif (child != null && !child.trim().isEmpty()) {\n    // Remove leading/trailing separators\n    child = child.replaceAll(\"^[\" + File.separator + \"]+|[\" + File.separator + \"]+$\", \"\");\n    if (!child.isEmpty()) {\n        String path = PathUtils.join(parent, child);\n    }\n}","typeGuard":"static boolean isValidPathSegment(String segment) {\n    if (segment == null || segment.isEmpty()) return false;\n    char sep = File.separatorChar;\n    for (char c : segment.toCharArray()) {\n        if (c != sep) return true;\n    }\n    return false;\n}","tryCatchPattern":"try {\n    String path = PathUtils.join(parent, child);\n} catch (IllegalArgumentException e) {\n    // Child segment was all-separator chars or invalid\n    // Fall back to parent only or sanitize and retry\n    String sanitized = child.replaceAll(\"/\", \"\");\n    if (!sanitized.isEmpty()) {\n        path = PathUtils.join(parent, sanitized);\n    } else {\n        path = parent;\n    }\n}","preventionTips":["Sanitize path inputs: strip leading/trailing separators and verify non-empty content.","Validate user-supplied path segments before passing to PathUtils.join().","Use java.nio.file.Path or java.io.File for path construction when possible — they handle edge cases internally.","Add unit tests covering separator-only and empty-string path segments."],"tags":["java","android","path","validation","illegal-argument"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}