Skip to content

JSON Patch 'add' operation with path ending in '-' doesn't append to array (end position) #422

@Cha2d

Description

@Cha2d

Expected Behavior

According to RFC 6902 Section 4.1, when the path ends with '-', the operation should append the value to the end of the array.

Actual Behavior

The current implementation attempts to parse '-' as a numeric index using Number.parseInt(), which returns NaN. This causes unexpected behavior instead of properly appending to the array.

Steps to Reproduce

import { applyJsonPatchRFC6902 } from './src/formatters/jsonpatch-apply.js';

const target = { items: [1, 2, 3] };
const patch = [{ op: 'add', path: '/items/-', value: 4 }];

applyJsonPatchRFC6902(target, patch);
console.log(target.items); // Expected: [1, 2, 3, 4], but doesn't work correctly

Root Cause

In the add function (lines 175-185), the code doesn't check for the special '-' character before attempting to parse it as an integer:

const index = Number.parseInt(last, 10);
if (index < 0 || index > parent.length) {
    // This condition doesn't catch NaN from parsing '-'

Proposed Solution

Add special handling for the '-' character before attempting numeric parsing:

if (Array.isArray(parent)) {
    if (last === '-') {
        // Append to the end of the array per RFC 6902
        parent.push(clone(value));
        return;
    }
    const index = Number.parseInt(last, 10);
    if (Number.isNaN(index) || index < 0 || index > parent.length) {
        // Also added NaN check for better error handling
        throw new Error(/* ... */);
    }
    // ... rest of implementation
}

Environment

  • Location: packages/jsondiffpatch/src/formatters/jsonpatch-apply.ts
  • Function: add() (around line 168)

Additional Notes

This is a compliance issue with RFC 6902 and affects the correctness of JSON Patch operations when working with arrays. The fix is straightforward and maintains backward compatibility while adding proper support for the '-' end-of-array indicator.

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