import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { mergeAttributes } from "@tiptap/core"; test("development and release manifests retain the patched rich-text dependency floor", () => { for (const filename of ["package.json", "package.release.json"]) { const manifest = JSON.parse(readFileSync(new URL(`../${filename}`, import.meta.url), "utf8")); for (const name of ["core", "extension-image", "pm", "react", "starter-kit"]) { assert.equal(manifest.dependencies[`@tiptap/${name}`], "^3.30.4", `${filename}: @tiptap/${name}`); } } }); test("rich-text attribute merging cannot inherit executable attributes from a JSON prototype key", () => { const untrusted = JSON.parse('{"__proto__":{"onerror":"fixture-canary","src":"fixture-invalid"},"title":"Safe title"}'); const attributes = mergeAttributes({ class: "preview" }, untrusted); assert.equal(Object.getPrototypeOf(attributes), Object.prototype); assert.equal(attributes.onerror, undefined); assert.equal(attributes.src, undefined); assert.equal(attributes.title, "Safe title"); const enumerable = []; for (const key in attributes) enumerable.push(key); assert.ok(!enumerable.includes("onerror")); assert.ok(!enumerable.includes("src")); assert.equal(Object.prototype.onerror, undefined); });