{"record":{"id":"ff39e31f3d117b97","repo":"chinabugotech/hutool","slug":"bad-input","errorCode":null,"errorMessage":"BAD_INPUT","messagePattern":"BAD_INPUT","errorType":"exception","errorClass":"UtilException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/codec/PunyCode.java","lineNumber":204,"sourceCode":"\t\tint d = input.lastIndexOf(DELIMITER);\n\t\tif (d > 0) {\n\t\t\tfor (int j = 0; j < d; j++) {\n\t\t\t\tfinal char c = input.charAt(j);\n\t\t\t\tif (isBasic(c)) {\n\t\t\t\t\toutput.append(c);\n\t\t\t\t}\n\t\t\t}\n\t\t\td++;\n\t\t} else {\n\t\t\td = 0;\n\t\t}\n\t\tfinal int length = input.length();\n\t\twhile (d < length) {\n\t\t\tint oldi = i;\n\t\t\tint w = 1;\n\t\t\tfor (int k = BASE; ; k += BASE) {\n\t\t\t\tif (d == length) {\n\t\t\t\t\tthrow new UtilException(\"BAD_INPUT\");\n\t\t\t\t}\n\t\t\t\tint c = input.charAt(d++);\n\t\t\t\tint digit = codepoint2digit(c);\n\t\t\t\tif (digit > (Integer.MAX_VALUE - i) / w) {\n\t\t\t\t\tthrow new UtilException(\"OVERFLOW\");\n\t\t\t\t}\n\t\t\t\ti = i + digit * w;\n\t\t\t\tint t;\n\t\t\t\tif (k <= bias) {\n\t\t\t\t\tt = TMIN;\n\t\t\t\t} else if (k >= bias + TMAX) {\n\t\t\t\t\tt = TMAX;\n\t\t\t\t} else {\n\t\t\t\t\tt = k - bias;\n\t\t\t\t}\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/codec/PunyCode.java#L186-L222","documentation":"Thrown by PunyCode.decode() when the input string ends prematurely mid-variable-length-integer, i.e., when the inner decoding loop reaches the end of the input (d == length) before completing the current digit sequence. This indicates a malformed or truncated Punycode string that cannot be fully parsed.","triggerScenarios":"Calling PunyCode.decode(input) with a string that is truncated or malformed — the decoder expects a complete sequence of base-36 digit characters but encounters the end of the string mid-sequence. This happens with corrupted, manually truncated, or incorrectly generated Punycode strings.","commonSituations":"Truncated domain names from user input or URL parsing. Corrupted data in transit or storage. Manually constructed or partially overwritten Punycode strings. Inconsistent prefix handling (passing 'xn--' prefix to decode() which strips it, leaving a malformed remainder).","solutions":["Validate the Punycode string is well-formed before decoding — check it only contains [a-z0-9-] characters.","Catch UtilException around decode() and report the input as malformed.","Use decodeDomain() for full domain processing which handles the xn-- prefix correctly per label."],"exampleFix":"// before\nString decoded = PunyCode.decode(\"xn--fiq\"); // truncated — throws BAD_INPUT\n\n// after\ntry {\n    String decoded = PunyCode.decode(input);\n} catch (UtilException e) {\n    if (\"BAD_INPUT\".equals(e.getMessage())) {\n        return input; // fall back to raw string\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Validate Punycode charset before decoding\nboolean valid = input != null && input.matches(\"^[a-z0-9-]*$\");","typeGuard":null,"tryCatchPattern":"try {\n    String decoded = PunyCode.decode(input);\n} catch (UtilException e) {\n    if (\"BAD_INPUT\".equals(e.getMessage())) {\n        return input; // fall back to raw string if not valid Punycode\n    }\n    throw e;\n}","preventionTips":["Validate Punycode input character set before decoding.","Use decodeDomain() for full domain processing.","Handle BAD_INPUT gracefully by falling back to the raw string."],"tags":["punycode","decode","malformed-input","idn","codec"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}