yyjson-recursion-limit.patch


Overview

This patch enhances the **yyjson** C JSON parsing library by introducing a configurable recursion depth limit during JSON parsing. The primary purpose is to prevent unbounded recursion when parsing deeply nested JSON arrays or objects, which can lead to stack overflow or excessive resource consumption.

The patch defines a new macro `YYJSON_READER_CONTAINER_RECURSION_LIMIT` (defaulting to 1024) that limits the maximum allowed recursion depth for nested JSON containers (arrays and objects) during parsing. When the parser exceeds this depth, it triggers a specific parsing error (`YYJSON_READ_ERROR_RECURSION_DEPTH`), allowing the caller to detect and handle excessively deep JSON structures gracefully.


Detailed Explanation

Changes in yyjson.c


Key Entities and Functions

Macro

Error Code

Functions/Methods (in yyjson.c)

Parameters (common to both)

Return Value

Usage Example (internal)

// At start of parsing an array
container_depth++;
if (container_depth >= YYJSON_READER_CONTAINER_RECURSION_LIMIT) {
    goto fail_recursion;
}
// Parse array elements...

// At end of parsing an array
container_depth--;

Implementation Details and Algorithms


Interaction with Other Parts of the System


Usage Example

#include "yyjson.h"

// Optionally override recursion limit before including yyjson.c
#define YYJSON_READER_CONTAINER_RECURSION_LIMIT 500

int main() {
    const char *json = "[[[...]]]";  // Deeply nested JSON
    yyjson_read_err err;
    yyjson_doc *doc = yyjson_read(json, strlen(json), 0, &err);
    if (!doc) {
        if (err.code == YYJSON_READ_ERROR_RECURSION_DEPTH) {
            printf("JSON parsing failed: recursion depth exceeded\n");
        } else {
            printf("JSON parsing failed: %s\n", err.msg);
        }
        return 1;
    }
    // Use doc...
    yyjson_doc_free(doc);
    return 0;
}

Mermaid Diagram: Flow of Recursion Depth Checking in JSON Parsing

flowchart TD
    Start[Start Parsing Container]
    IncDepth[Increment container_depth]
    CheckLimit{container_depth >= YYJSON_READER_CONTAINER_RECURSION_LIMIT?}
    FailRecursion[Return RECURSION_DEPTH Error]
    ParseElements[Parse Array/Object Elements]
    DecDepth[Decrement container_depth]
    ReturnSuccess[Return Parsed Container]

    Start --> IncDepth --> CheckLimit
    CheckLimit -- Yes --> FailRecursion
    CheckLimit -- No --> ParseElements --> DecDepth --> ReturnSuccess

This flowchart shows how recursion depth is incremented when entering a container, checked against the limit, and decremented after parsing, with error handling if the limit is exceeded.


Summary

This patch is a critical safeguard improvement for yyjson, enhancing the parser's resilience and configurability without impacting normal parsing performance for typical JSON documents.