{"record":{"id":"e2118e6f14245733","repo":"google/gson","slug":"number-has-unsupported-scale-s","errorCode":null,"errorMessage":"Number has unsupported scale: ${s}","messagePattern":"Number has unsupported scale: (.+?)","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/NumberLimits.java","lineNumber":27,"sourceCode":" */\npublic final class NumberLimits {\n  private NumberLimits() {}\n\n  private static final int MAX_NUMBER_STRING_LENGTH = 10_000;\n\n  private static void checkNumberStringLength(String s) {\n    if (s.length() > MAX_NUMBER_STRING_LENGTH) {\n      throw new NumberFormatException(\"Number string too large: \" + s.substring(0, 30) + \"...\");\n    }\n  }\n\n  public static BigDecimal parseBigDecimal(String s) throws NumberFormatException {\n    checkNumberStringLength(s);\n    BigDecimal decimal = new BigDecimal(s);\n\n    // Cast to long to avoid issues with abs when value is Integer.MIN_VALUE\n    if (Math.abs((long) decimal.scale()) >= 10_000) {\n      throw new NumberFormatException(\"Number has unsupported scale: \" + s);\n    }\n    return decimal;\n  }\n\n  public static BigInteger parseBigInteger(String s) throws NumberFormatException {\n    checkNumberStringLength(s);\n    return new BigInteger(s);\n  }\n}\n","sourceCodeStart":9,"sourceCodeEnd":37,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/NumberLimits.java#L9-L37","documentation":"NumberLimits rejects any BigDecimal whose scale's absolute value is >= 10,000 (NumberLimits.java:26). Extremely large scales cause pathological memory/CPU usage in BigDecimal arithmetic; Gson treats them as malformed.","triggerScenarios":"Parsing a JSON number whose scale magnitude is >= 10,000, e.g. extremely high-precision decimals like 1e-50000 or 0.000... (10k+ zeros) ...1, via NumberLimits.parseBigDecimal / LazilyParsedNumber.asBigDecimal / big-decimal coercion.","commonSituations":"Untrusted numeric input engineered to exhaust memory; scientific/engineering payloads with absurd precision; malformed fixed-point fields; adversarial JSON fuzzing.","solutions":["Constrain accepted numeric precision at the schema/validation boundary (e.g. max significant digits).","If you need wide ranges, accept the value as a quoted String and parse with a bounded custom parser rather than BigDecimal.","Cap JSON request size and field length so pathological numbers cannot reach NumberLimits."],"exampleFix":"// before\nBigDecimal v = NumberLimits.parseBigDecimal(input);\n// after\nBigDecimal test = new BigDecimal(input);\nif (Math.abs(test.scale()) >= 10_000) throw new IllegalArgumentException(\"scale too large\");\n// (or simply let NumberLimits throw and handle the NumberFormatException at the boundary)","handlingStrategy":"validation","validationCode":"BigDecimal probe = new BigDecimal(s);\nif (Math.abs(probe.scale()) >= 10_000) throw new NumberFormatException(\"scale too large\");\nBigDecimal v = NumberLimits.parseBigDecimal(s);","typeGuard":"static boolean scaleOK(String s) { try { return Math.abs(new BigDecimal(s).scale()) < 10_000; } catch (Exception e) { return false; } }","tryCatchPattern":"try { NumberLimits.parseBigDecimal(s); } catch (NumberFormatException e) { /* unsupported scale or malformed */ }","preventionTips":["Validate numeric precision/significant digits in your schema.","For very-wide-range numbers, accept a quoted String and parse with a bounded custom parser.","Treat scale-related NumberFormatException as adversarial input at the boundary."],"tags":["gson","parsing","dos","number","security"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}