{"record":{"id":"6e4b1d2891da3e7e","repo":"scwang90/SmartRefreshLayout","slug":"error-in-parsing-pathdata","errorCode":null,"errorMessage":"Error in parsing ${pathData}","messagePattern":"Error in parsing (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"refresh-drawable-path/src/main/java/com/scwang/smart/drawable/path/PathParser.java","lineNumber":186,"sourceCode":"                    val[k + 5] *= ratioWidth;\n                    val[k + 6] *= ratioHeight;\n                    break;\n            }\n        }\n    }\n\n    /**\n     * @param pathData The string representing a path, the same as \"d\" string in svg file.\n     * @return the generated Path object.\n     */\n    public static Path createPathFromPathData(String pathData) {\n        Path path = new Path();\n        PathDataNode[] nodes = createNodesFromPathData(pathData);\n        if (nodes != null) {\n            try {\n                PathDataNode.nodesToPath(nodes, path);\n            } catch (RuntimeException e) {\n                throw new RuntimeException(\"Error in parsing \" + pathData, e);\n            }\n            return path;\n        }\n        return null;\n    }\n\n    /**\n     * @param pathData The string representing a path, the same as \"d\" string in svg file.\n     * @return an array of the PathDataNode.\n     */\n    public static PathDataNode[] createNodesFromPathData(String pathData) {\n        if (pathData == null) {\n            return null;\n        }\n        int start = 0;\n        int end = 1;\n\n        List<PathDataNode> list = new ArrayList<>();","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/scwang90/SmartRefreshLayout/blob/224db48f8af897a930b810a6b6fc55af8cef0d57/refresh-drawable-path/src/main/java/com/scwang/smart/drawable/path/PathParser.java#L168-L204","documentation":"Thrown when PathDataNode.nodesToPath() fails while converting parsed SVG path-data nodes into an android.graphics.Path. The path string was tokenized into nodes, but applying them to the Path object raised a RuntimeException (e.g. malformed command sequence, too few parameters for a command, or an unsupported construct). The original pathData string is embedded in the message to help identify the offending input.","triggerScenarios":"Calling PathParser.createPathFromPathData(pathData) with an SVG 'd' string that parses into nodes but fails during Path construction: commands with missing/extra parameters (e.g. 'L' with one coordinate), relative commands that underflow, nested or repeated command letters in wrong order, or locale-generated strings using ',' decimal separators.","commonSituations":"Hand-writing or dynamically building an SVG path string for a refresh header/footer drawable; copying an SVG 'd' attribute that contains arcs (A) or implicit-repeat syntax not handled identically by this parser; formatting floats with String.format in a locale like de/fr producing '3,5' instead of '3.5'; truncating a path string from a designer's SVG export.","solutions":["Validate the 'd' string against the full SVG path grammar before passing it (a lint/regex pass or rendering it in a tool like Inkscape/browser first).","Check the embedded pathData in the exception message for missing parameters — most often a command letter with fewer numbers than it requires.","Ensure numbers are formatted with Locale.US ('.' decimal separator) when the string is generated programmatically.","Wrap createPathFromPathData in a try-catch and fall back to a default drawable/header so one bad path does not crash the app.","If the path uses advanced SVG features, simplify it (convert arcs/transforms in a vector editor and re-export as plain M/L/C/Z commands)."],"exampleFix":"// before\nPath path = PathParser.createPathFromPathData(\"M10,10 L40\"); // L needs 2 coords -> crash\n\n// after\nPath path;\ntry {\n    path = PathParser.createPathFromPathData(\"M10,10 L40,40\");\n} catch (RuntimeException e) {\n    path = new Path(); // or load a bundled fallback vector drawable\n}","handlingStrategy":"try-catch","validationCode":"// Quick sanity check: known commands, balanced params, before calling the parser\nboolean looksLikeValidPath(String d) {\n    if (d == null || d.trim().isEmpty()) return false;\n    if (!d.matches(\"[MmLlHhVvCcSsQqTtAaZz0-9,\\\\s.+-]+\")) return false;\n    return d.trim().matches(\"^[Mm].*\"); // must start with a moveto\n}\nif (looksLikeValidPath(pathData)) {\n    path = PathParser.createPathFromPathData(pathData);\n}","typeGuard":null,"tryCatchPattern":"Path path;\ntry {\n    path = PathParser.createPathFromPathData(pathData);\n} catch (RuntimeException e) {\n    Log.w(TAG, \"Bad path data: \" + pathData, e);\n    path = new Path(); // or a bundled fallback vector\n}","preventionTips":["Treat path-data strings as untrusted input: validate or wrap every programmatic construction.","Format generated floats with Locale.US to keep '.' as the decimal separator.","Keep a unit test that parses every hardcoded path string used in the app.","Prefer importing paths as Android vector drawables rather than parsing raw 'd' strings at runtime."],"tags":["svg","path-parsing","drawable","android","input-validation"],"backgroundTag":null,"analyzedSha":"224db48f8af897a930b810a6b6fc55af8cef0d57","analyzedAt":"2026-08-14T10:09:28.455Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}