{"record":{"id":"095ffc7cd9b77913","repo":"HMCL-dev/HMCL","slug":"bad-query-string","errorCode":null,"errorMessage":"bad query string","messagePattern":"bad query string","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"minecraft/libraries/HMCLMultiMCBootstrap/src/main/java/org/jackhuang/hmcl/HMCLMultiMCBootstrap.java","lineNumber":98,"sourceCode":"                method.invoke(null, (Object) args);\n                return;\n            }\n        }\n\n        throw new IllegalArgumentException(\"Cannot find method 'main(String[])' in \" + mainClass);\n    }\n\n    private static Map<String, String> parseQuery(String queryParameterString) {\n        if (queryParameterString == null) return Collections.emptyMap();\n\n        Map<String, String> result = new HashMap<>();\n\n        try (Scanner scanner = new Scanner(queryParameterString)) {\n            scanner.useDelimiter(\"&\");\n            while (scanner.hasNext()) {\n                String[] nameValue = scanner.next().split(\"=\");\n                if (nameValue.length == 0 || nameValue.length > 2) {\n                    throw new IllegalArgumentException(\"bad query string\");\n                }\n\n                String name = decodeURL(nameValue[0]);\n                String value = nameValue.length == 2 ? decodeURL(nameValue[1]) : null;\n                result.put(name, value);\n            }\n        }\n        return result;\n    }\n\n    private static String decodeURL(String value) {\n        try {\n            return URLDecoder.decode(value, \"UTF-8\");\n        } catch (UnsupportedEncodingException e) {\n            throw new AssertionError(e);\n        }\n    }\n}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/minecraft/libraries/HMCLMultiMCBootstrap/src/main/java/org/jackhuang/hmcl/HMCLMultiMCBootstrap.java#L80-L116","documentation":"HMCLMultiMCBootstrap.parseQuery splits the query string on '&' and expects each token to contain at most one '='. When a token splits into zero or more than two parts (empty token or multiple '=' signs), it throws IllegalArgumentException(\"bad query string\"). This guards the bootstrap from malformed launch arguments.","triggerScenarios":"Calling parseQuery with a string containing an empty '&amp;' segment (e.g. 'a=1&&b=2' or a trailing '&'), or a segment with two or more '=' characters such as 'base64data=abc==', since split(\"=\") then yields 3+ parts.","commonSituations":"Malformed command-line or launcher-supplied query parameters; base64 values embedded in query strings without URL encoding; hand-edited shortcut/target lines with stray '&' or '='; trailing delimiters left by template expansion.","solutions":["Remove empty segments (consecutive or trailing '&') from the query string before it reaches HMCL.","URL-encode any '=' characters inside values (%3D) so each segment has at most one '='.","If you control the caller, sanitize/split the query string yourself and pass only well-formed name=value pairs."],"exampleFix":"// before\nparseQuery(\"server=example.com&token=abc==\")\n// after\nparseQuery(\"server=example.com&token=abc%3D%3D\")","handlingStrategy":"validation","validationCode":"boolean isSafeQuery(String q) {\n    if (q == null || q.isEmpty()) return true; // or false per contract\n    for (String part : q.split(\"&\", -1)) {\n        if (part.isEmpty()) return false;\n        if (part.indexOf('=') != part.lastIndexOf('=')) return false;\n    }\n    return true;\n}\n// call: if (!isSafeQuery(query)) throw new IllegalArgumentException(\"malformed query: \" + query);","typeGuard":null,"tryCatchPattern":"try {\n    Map<String,String> params = parseQuery(query);\n} catch (IllegalArgumentException e) {\n    LOG.warn(\"Skipping malformed query string: \" + query, e);\n    params = Collections.emptyMap();\n}","preventionTips":["URL-encode '=' (%3D) inside values so each segment has one '='.","Join parameters with a helper that avoids empty or duplicate '&' segments.","Trim trailing delimiters before parsing.","Unit-test parseQuery with edge inputs ('', 'a&&b', 'a=b=c')."],"tags":["query-string","url-parsing","java","bootstrap"],"backgroundTag":"invalid-argument-format","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}