Skip to content

Fix diffJson silently dropping an own __proto__ key (#696) - #697

Merged
ExplodingCabbage merged 2 commits into
kpdecker:masterfrom
youdie006:fix/diffjson-proto-key
Aug 11, 2026
Merged

Fix diffJson silently dropping an own __proto__ key (#696)#697
ExplodingCabbage merged 2 commits into
kpdecker:masterfrom
youdie006:fix/diffjson-proto-key

Conversation

@youdie006

Copy link
Copy Markdown
Contributor

Fixes#696.

Problem

diffJson reports two objects that differ only in an own __proto__ property as identical:

diffJson(JSON.parse('{"__proto__":"old"}'),JSON.parse('{"__proto__":"new"}'))// => [ { count: 1, value: "{}", added: false, removed: false } ] // no diff!

Root cause

canonicalize (src/diff/json.ts) builds its output object with {}. That object inherits Object.prototype, so canonicalizedObj["__proto__"] = value invokes the __proto__setter instead of creating an own data property. The key is silently discarded, both sides canonicalize to {}, and diffJson sees no difference. Objects parsed from JSON (e.g. JSON.parse) can legitimately carry an own enumerable __proto__ property, so this is silent data loss.

Fix

Build the canonicalized object with Object.create(null), so a "__proto__" key is stored as an ordinary property. This is the approach suggested (unverified) by the reporter in #696; this PR verifies it and adds test coverage. canonicalize output is only ever JSON.stringify-d or key-walked, both of which work on null-prototype objects, and the existing #canonicalize tests (which read Object.keys(...)) still pass.

Test

Added a regression test in test/diff/json.js diffing two JSON-parsed objects with an own __proto__ property. Red-green verified: before the fix the assertion fails (single unchanged "{}" hunk); after, it produces the expected removed/added __proto__ lines. The full mocha suite passes (one unrelated pre-existing timeout on the enormous-hunk perf test in test/patch/create.js, which passes with a higher --timeout); eslint is clean.


Disclosure: prepared with AI assistance (Claude); I reviewed it and verified the red-green test and the full test suite.

canonicalize built its output with `{}`, so assigning a canonicalized
value to an own "__proto__" key invoked the Object.prototype __proto__
setter instead of creating a data property. The key was dropped, and
diffJson reported two objects that differ only in their __proto__
property as identical (a single unchanged "{}" hunk).
Build the canonicalized object with Object.create(null) so a "__proto__"
key is stored as an ordinary property. Add a regression test covering
diffJson over objects parsed from JSON with an own __proto__ property.
Fixeskpdecker#696

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:392ff6b95c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threadsrc/diff/json.ts

@ExplodingCabbageExplodingCabbage left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Looks correct, comments are clear, and I have no problem with the AI co-authorship so long as it's disclosed and the substance of the PR is sound.

Doesn't seem to me like there are any other places in the codebase where similar changes are needed (based on a quick grep for {}).

I'll merge.

@ExplodingCabbage
ExplodingCabbage merged commit c207c49 into kpdecker:masterAug 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

diffJson misbehaves when object has __proto__

2 participants

@youdie006@ExplodingCabbage