Skip to content

Excessive Recursion in modelFromJSON Causes Stack Overflow ( Parser Depth Handling Bug ) #8632

@amadhan882

Description

@amadhan882

Excessive Recursion in modelFromJSON Causes Stack Overflow ( Parser Depth Handling Bug )


System information

  • Have I written custom code: Yes (minimal PoC)
  • OS Platform: Windows 11
  • Mobile device: N/A
  • TensorFlow.js installed from: npm
  • TensorFlow.js version: @tensorflow/tfjs@4.22.0
  • Browser version: N/A (Node.js execution)
  • TensorFlow.js Converter Version: Not applicable
  • Node.js runtime: v22.18.0

Describe the current behavior

When calling:

tf.models.modelFromJSON(...)

with a model configuration containing extremely deep nested "config" objects, the parser crashes with:

RangeError: Maximum call stack size exceeded

The model loader recursively walks through the configuration without:

  • enforcing a maximum nesting depth
  • validating input structure
  • switching to an iterative-safe traversal

This results in a JavaScript stack overflow during JSON model parsing.

This is a robustness bug affecting model loading of malformed or accidentally nested config structures.


Describe the expected behavior

The parser should gracefully reject unreasonably deep configurations.

Expected safeguards:

  • Detect excessive nesting (e.g., > 1000 levels)
  • Abort with a clear error message such as:
    “Model configuration depth exceeds supported limit.”
  • Avoid triggering recursive stack overflow.

This improves resilience when handling corrupted, user-generated, or automated model configs.


Standalone code to reproduce the issue

Save as reproduce_tfjs_parser_depth_bug.js:

const tf = require('@tensorflow/tfjs');

async function checkParserStability() {
    console.log("[*] Testing Parser Depth Limits...");

    const depth = 5000;   // large enough to exceed JS call stack
    let nestedConfig = { layers: [] };
    let current = nestedConfig;

    // Generate deeply nested `"config"` chain
    for (let i = 0; i < depth; i++) {
        current.config = { layers: [] };
        current = current.config;
    }

    const modelStructure = {
        "modelTopology": {
            "class_name": "Sequential",
            "config": nestedConfig
        }
    };

    try {
        await tf.models.modelFromJSON(modelStructure);
    } catch (err) {
        console.log("Status:", err.message);
    }
}

checkParserStability();

How to run

node reproduce_tfjs_parser_depth_bug.js

Observed output

[*] Testing Parser Depth Limits...
Status: Maximum call stack size exceeded

Depth values >2000–3000 consistently trigger the same failure.


Explanation

The underlying issue is unbounded recursive descent in the model loader's configuration parsing.

Because JavaScript engines (V8 on Node.js) impose strict call-stack limits, this leads to:

  • Call stack exhaustion
  • Immediate crash inside modelFromJSON
  • No graceful recovery path

While not a security issue, this is a correctness and stability bug for any workflow that processes:

  • Auto-generated configs
  • Third-party model JSON
  • Machine-generated nested structures
  • Corrupted or malformed models

Adding a depth-checking guard or iterative parsing would prevent this runtime crash.


Other info / logs

  • Not browser-specific (reproduces in Node.js)
  • No native memory access; pure JS error

Conclusion

The modelFromJSON parser lacks a recursion depth limit, making the library vulnerable to uncontrolled recursion (CWE-674).
This allows malformed or deeply nested configurations to exhaust the JavaScript call stack, causing an immediate process crash.

To ensure reliability and prevent runtime termination, the parser should:

  • Implement a maximum nesting depth guard, or
  • Use an iterative traversal strategy instead of deep recursion.

Adding these safeguards would prevent call-stack crashes and improve TensorFlow.js robustness when handling complex or malformed inputs.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions