{"id":"4a75d0107695a3df","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/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/NumberLimits.java#L9-L37","documentation":"Thrown by NumberLimits.parseBigDecimal as NumberFormatException when the absolute value of the parsed number's scale is >= 10,000. BigDecimal scale represents the number of digits to the right of the decimal point (negative means trailing zeros to the left). Extreme scales imply enormous internal int[] arrays and slow arithmetic, so Gson rejects them as a DoS/performance guard.","triggerScenarios":"Parsing a JSON number whose decimal-point offset is huge, e.g. '1e100000' (positive scale magnitude >= 10,000) or a literal with thousands of leading/trailing zeros after the decimal point. Reached when LazilyParsedNumber needs a BigDecimal (e.g. longValue()/intValue() overflow path) or when Gson parses into BigDecimal/BigInteger-backed fields.","commonSituations":"Scientific-notation payloads with exponents beyond +/-10,000; mis-typed identifiers/UUIDs/hashes modeled as numbers; adversarial input crafted to blow up BigDecimal memory.","solutions":["Model the field as a String and validate/sanitize the exponent before numeric conversion.","Cap or normalize the exponent: if the magnitude is implausible for your domain, reject the input.","Prefer Double/Long targets when full arbitrary precision is not required, avoiding the BigDecimal path entirely."],"exampleFix":"// before: huge exponent\ngson.fromJson(\"1e100000\", BigDecimal.class); // NumberFormatException\n\n// after: read as string, validate exponent, then parse\nString s = gson.fromJson(json, String.class);\nif (s.matches(\".*[eE][+-]?\\d{5,}\")) throw new IllegalArgumentException(\"scale too large\");\nBigDecimal v = new BigDecimal(s);","handlingStrategy":"validation","validationCode":"static boolean scaleIsAcceptable(String s) {\n  // reject exponents with magnitude >= 10000, or absurd decimal lengths\n  java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"[eE]([+-]?\\\\d+)\").matcher(s);\n  if (m.find()) {\n    long exp = Long.parseLong(m.group(1));\n    if (Math.abs(exp) >= 10_000) return false;\n  }\n  return s.length() <= 10_000;\n}","typeGuard":"static boolean isReasonableBigDecimal(String s) {\n  return scaleIsAcceptable(s);\n}","tryCatchPattern":"try {\n  NumberLimits.parseBigDecimal(s);\n} catch (NumberFormatException e) {\n  if (e.getMessage().contains(\"unsupported scale\")) {\n    // fall back to Double or reject\n    return Double.parseDouble(s);\n  } else throw e;\n}","preventionTips":["Model fields with extreme precision needs as Strings and bound the exponent.","Prefer Double/Long when arbitrary precision is unnecessary.","Sanitize JSON before parsing to reject pathological exponents."],"tags":["gson","number","dos","numberformatexception","limits","bigdecimal"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}