Skip to content

Empty array reference token is incorrectly accepted as index 0 in JSON Pointer evaluation #1009

@Yanhaoxi

Description

@Yanhaoxi

Empty array reference token is accepted as index 0 in JSON Pointer evaluation

Summary

decode_array_index_from_pointer() appears to accept an empty reference token as a valid array index and decodes it as 0.

This seems inconsistent with RFC 6901 JSON Pointer array evaluation. When the currently referenced value is an array, the reference token should be either:

  • a valid unsigned base-10 array index without leading zeroes, or
  • exactly "-" for the special position after the last array element.

An empty string is not a valid array index, but cJSON currently treats it as index 0.

Relevant code

In cJSON_Utils.c:

static cJSON_bool decode_array_index_from_pointer(const unsigned char * const pointer, size_t * const index)
{
    size_t parsed_index = 0;
    size_t position = 0;

    if ((pointer[0] == '0') && ((pointer[1] != '\0') && (pointer[1] != '/')))
    {
        /* leading zeroes are not permitted */
        return 0;
    }

    for (position = 0; (pointer[position] >= '0') && (pointer[position] <= '9'); position++)
    {
        parsed_index = (10 * parsed_index) + (size_t)(pointer[position] - '0');
    }

    if ((pointer[position] != '\0') && (pointer[position] != '/'))
    {
        return 0;
    }

    *index = parsed_index;
    return 1;
}

Observable impact

Because get_item_from_pointer() calls decode_array_index_from_pointer() when the current value is an array, invalid pointers can resolve to the first array element.

Examples:

  • cJSONUtils_GetPointer(array, "/") returns array[0], but it should fail.
  • JSON Patch remove with path "/" on an array removes the first element, although the path is invalid for an array.
  • JSON Patch replace with path "/" on an array replaces the first element.
  • JSON Patch copy or move with from: "/" on an array reads or detaches the first element.
  • Nested paths such as "/0/" can incorrectly resolve an empty token inside a nested array as index 0.

For JSON Patch, RFC 6902 requires operation paths and from locations to be JSON Pointer values. If the target location is invalid or does not exist, the operation should fail instead of silently acting on index 0.

References:

Expected behavior

decode_array_index_from_pointer() should reject an empty token when resolving an array index.

For example:

if (pointer[0] == '\0' || pointer[0] == '/')
{
    return 0;
}

Actual behavior

The empty token is accepted and interpreted as index 0, so invalid JSON Pointers targeting arrays can resolve to, modify, remove, copy, or move the first array element.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions