{"record":{"id":"0aca14a97c79b6b8","repo":"airbnb/lottie-android","slug":"nesting-too-deep-at","errorCode":null,"errorMessage":"Nesting too deep at {}","messagePattern":"Nesting too deep at (.+?)","errorType":"exception","errorClass":"JsonDataException","httpStatus":null,"severity":"error","filePath":"lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonReader.java","lineNumber":237,"sourceCode":"\n  /**\n   * Returns a new instance that reads UTF-8 encoded JSON from {@code source}.\n   */\n  public static JsonReader of(BufferedSource source) {\n    return new JsonUtf8Reader(source);\n  }\n\n  // Package-private to control subclasses.\n  JsonReader() {\n    scopes = new int[32];\n    pathNames = new String[32];\n    pathIndices = new int[32];\n  }\n\n  final void pushScope(int newTop) {\n    if (stackSize == scopes.length) {\n      if (stackSize == 256) {\n        throw new JsonDataException(\"Nesting too deep at \" + getPath());\n      }\n      scopes = Arrays.copyOf(scopes, scopes.length * 2);\n      pathNames = Arrays.copyOf(pathNames, pathNames.length * 2);\n      pathIndices = Arrays.copyOf(pathIndices, pathIndices.length * 2);\n    }\n    scopes[stackSize++] = newTop;\n  }\n\n  /**\n   * Throws a new IO exception with the given message and a context snippet\n   * with this reader's content.\n   */\n  final JsonEncodingException syntaxError(String message) throws JsonEncodingException {\n    throw new JsonEncodingException(message + \" at path \" + getPath());\n  }\n\n\n  /**","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/airbnb/lottie-android/blob/05ea92e90381eb8a8ae06855ea2b74f322bebbec/lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonReader.java#L219-L255","documentation":"JsonReader.pushScope() manages the parser's scope stack. The stack starts at 32 entries and doubles on demand, but when it reaches 256 levels deep it throws JsonDataException('Nesting too deep'). This is a hard cap to prevent stack-overflow-style attacks or pathological input. Lottie animations should never approach this depth under normal conditions.","triggerScenarios":"Loading a JSON stream (Lottie animation or otherwise) with more than 256 levels of nested arrays/objects. This can be caused by a maliciously crafted file (JSON nesting bomb), a severely corrupted file, or a programming error producing deeply recursive JSON.","commonSituations":"Security: untrusted JSON input designed to exhaust memory; corrupted Lottie file with deeply nested (possibly circular-referenced) structures; accidental double-wrapping of JSON payloads by a broken server or CDN.","solutions":["Verify the Lottie JSON is well-formed and not excessively nested using a standard JSON parser or validator.","If accepting animations from untrusted sources, pre-validate nesting depth before passing to LottieAnimationView/LottieComposition.","Re-download or re-export the animation to eliminate corruption."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check nesting depth before passing to Lottie\npublic static boolean isNestingSafe(JsonElement json, int maxDepth) {\n    if (maxDepth <= 0) return false;\n    if (json.isJsonObject()) {\n        for (Map.Entry<String, JsonElement> e : json.getAsJsonObject().entrySet()) {\n            if (!isNestingSafe(e.getValue(), maxDepth - 1)) return false;\n        }\n    } else if (json.isJsonArray()) {\n        for (JsonElement e : json.getAsJsonArray()) {\n            if (!isNestingSafe(e, maxDepth - 1)) return false;\n        }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    LottieCompositionFactory.fromAsset(context, name);\n} catch (JsonDataException e) {\n    // nesting too deep — reject untrusted input\n}","preventionTips":["Never load untrusted Lottie JSON without pre-validation.","If accepting animations from users/network, pre-parse with Gson/Jackson to check nesting depth.","Treat excessively nested JSON as a potential attack indicator."],"tags":["lottie","json-parsing","nesting-depth","security","json-data-exception"],"backgroundTag":null,"analyzedSha":"05ea92e90381eb8a8ae06855ea2b74f322bebbec","analyzedAt":"2026-08-14T00:51:35.636Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}