diff --git a/package-lock.json b/package-lock.json index 1ee91c5..7deee9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "@contentstack/json-rte-serializer", - "version": "2.0.12", + "version": "2.0.13", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@contentstack/json-rte-serializer", - "version": "2.0.12", + "version": "2.0.13", "license": "MIT", "dependencies": { "array-flat-polyfill": "^1.0.1", - "dompurify": "^3.2.3", "lodash": "^4.17.21", "lodash.clonedeep": "^4.5.0", "lodash.flatten": "^4.4.0", @@ -1609,12 +1608,6 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "optional": true - }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -2250,14 +2243,6 @@ "node": ">=8" } }, - "node_modules/dompurify": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz", - "integrity": "sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, "node_modules/electron-to-chromium": { "version": "1.4.622", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.622.tgz", @@ -6280,12 +6265,6 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, - "@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "optional": true - }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -6756,14 +6735,6 @@ } } }, - "dompurify": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz", - "integrity": "sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==", - "requires": { - "@types/trusted-types": "^2.0.7" - } - }, "electron-to-chromium": { "version": "1.4.622", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.622.tgz", diff --git a/package.json b/package.json index 53cd1a6..626ec39 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ }, "dependencies": { "array-flat-polyfill": "^1.0.1", - "dompurify": "^3.2.3", "lodash": "^4.17.21", "lodash.clonedeep": "^4.5.0", "lodash.flatten": "^4.4.0", diff --git a/src/toRedactor.tsx b/src/toRedactor.tsx index b7b1c8e..2dc1406 100644 --- a/src/toRedactor.tsx +++ b/src/toRedactor.tsx @@ -1,8 +1,8 @@ import kebbab from 'lodash.kebabcase' import isEmpty from 'lodash.isempty' -import DOMPurify from 'dompurify' import {IJsonToHtmlElementTags, IJsonToHtmlOptions, IJsonToHtmlTextTags} from './types' import isPlainObject from 'lodash.isplainobject' +import {replaceHtmlEntities } from './utils' const ELEMENT_TYPES: IJsonToHtmlElementTags = { 'blockquote': (attrs: string, child: string) => { @@ -507,7 +507,7 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string } delete attrsJson['redactor-attributes'] Object.entries(attrsJson).forEach((key) => { - return key[1] ? (key[1] !== '' ? (attrs += `${key[0]}="${key[1]}" `) : '') : '' + return key[1] ? (key[1] !== '' ? (attrs += `${key[0]}="${replaceHtmlEntities(key[1])}" `) : '') : '' }) attrs = (attrs.trim() ? ' ' : '') + attrs.trim() } @@ -564,7 +564,7 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string if(['td','th'].includes(jsonValue['type'])){ if(jsonValue?.['attrs']?.['void']) return '' } - + attrs = (attrs.trim() ? ' ' : '') + attrs.trim() return ELEMENT_TYPES[orgType || jsonValue['type']](attrs, children,jsonValue, figureStyles) diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..b4b9c08 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,7 @@ +export function replaceHtmlEntities(str: string): string { + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} diff --git a/test/expectedJson.ts b/test/expectedJson.ts index fa21d5a..1433de4 100644 --- a/test/expectedJson.ts +++ b/test/expectedJson.ts @@ -2005,7 +2005,8 @@ export default { ``, ``, '', - `` + ``, + `` ], "json": [ @@ -2168,7 +2169,19 @@ export default { } ], "_version": 1 - } + }, + { + uid: "45a850acbeb949db86afe415625ad1ce", + type: "social-embeds", + attrs: { + src: "null", + width: 560, + height: 320, + title: " This is for

testing

purpose 'only' " + }, + children: [{ text: "" }], + }, + ] } diff --git a/test/toRedactor.test.ts b/test/toRedactor.test.ts index 87e5471..6517f88 100644 --- a/test/toRedactor.test.ts +++ b/test/toRedactor.test.ts @@ -273,6 +273,12 @@ describe("Testing json to html conversion", () => { const html = toRedactor(json); expect(html).toBe(expectedValue["RT-360"].html[3]); }) + + it("should escape html entities in attribute values",()=>{ + const json = expectedValue["RT-360"].json[4] + const html = toRedactor(json); + expect(html).toBe(expectedValue["RT-360"].html[4]); + }) }) test('should convert numeric width to string', () => {