Skip to content

diffJson misbehaves when object has __proto__ #696

Description

@aforemendude

When diffJson is called with objects with the special __proto__ key, the diff result is unexpected.

This issue is happening to the latest v9.0.0.

Reproduction: https://github.com/aforemendude/bugs-reproduction/tree/main/jsdiff-proto-edge-case

import { diffJson } from 'diff'

function diffAndLog(label, oldJson, newJson) {
  const oldObject = JSON.parse(oldJson)
  const newObject = JSON.parse(newJson)
  const changes = diffJson(oldObject, newObject)

  console.log(`${label}:`, JSON.stringify(changes, null, 2))
}

diffAndLog('normal', '{"normal":"old"}', '{"normal":"new"}')
console.log('--------------------')
diffAndLog('__proto__', '{"__proto__":"old"}', '{"__proto__":"new"}')

Output:

normal: [
  {
    "count": 1,
    "added": false,
    "removed": false,
    "value": "{\n"
  },
  {
    "count": 1,
    "added": false,
    "removed": true,
    "value": "  \"normal\": \"old\"\n"
  },
  {
    "count": 1,
    "added": true,
    "removed": false,
    "value": "  \"normal\": \"new\"\n"
  },
  {
    "count": 1,
    "added": false,
    "removed": false,
    "value": "}"
  }
]
--------------------
__proto__: [
  {
    "count": 1,
    "added": false,
    "removed": false,
    "value": "{}"
  }
]

Potential solution (unverified):

canonicalizedObj = {};

Change {} to Object.create(null).

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