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

Open Beginner friendly
#1,009 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
1/5
Estimated time
Under an hour
Newbie friendliness
85/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
c
Domain
backend

Research direction

Start in cJSON_Utils.c at decode_array_index_from_pointer() and trace its use from get_item_from_pointer(). Verify the listed JSON Pointer and JSON Patch array cases, then confirm that an empty reference token is rejected while valid indices and the '-' token retain their documented behavior.

Written by the indexing model from the issue text.

Description

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.

Dominant language
C
Stars
13k
Forks
3.5k
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from DaveGamble/cJSON

All issues in DaveGamble/cJSON

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.