Skip to content

Commit 500508f

Browse files
Merge pull request #75 from contentstack/RT-360
fix: escape html entities in attr values
2 parents d4f28d1 + e46ee03 commit 500508f

File tree

6 files changed

+33
-37
lines changed

6 files changed

+33
-37
lines changed

package-lock.json

Lines changed: 2 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
},
5050
"dependencies": {
5151
"array-flat-polyfill": "^1.0.1",
52-
"dompurify": "^3.2.3",
5352
"lodash": "^4.17.21",
5453
"lodash.clonedeep": "^4.5.0",
5554
"lodash.flatten": "^4.4.0",

src/toRedactor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import kebbab from 'lodash.kebabcase'
22
import isEmpty from 'lodash.isempty'
3-
import DOMPurify from 'dompurify'
43
import {IJsonToHtmlElementTags, IJsonToHtmlOptions, IJsonToHtmlTextTags} from './types'
54
import isPlainObject from 'lodash.isplainobject'
5+
import {replaceHtmlEntities } from './utils'
66

77
const ELEMENT_TYPES: IJsonToHtmlElementTags = {
88
'blockquote': (attrs: string, child: string) => {
@@ -507,7 +507,7 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string
507507
}
508508
delete attrsJson['redactor-attributes']
509509
Object.entries(attrsJson).forEach((key) => {
510-
return key[1] ? (key[1] !== '' ? (attrs += `${key[0]}="${key[1]}" `) : '') : ''
510+
return key[1] ? (key[1] !== '' ? (attrs += `${key[0]}="${replaceHtmlEntities(key[1])}" `) : '') : ''
511511
})
512512
attrs = (attrs.trim() ? ' ' : '') + attrs.trim()
513513
}
@@ -564,7 +564,7 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string
564564
if(['td','th'].includes(jsonValue['type'])){
565565
if(jsonValue?.['attrs']?.['void']) return ''
566566
}
567-
567+
568568
attrs = (attrs.trim() ? ' ' : '') + attrs.trim()
569569

570570
return ELEMENT_TYPES[orgType || jsonValue['type']](attrs, children,jsonValue, figureStyles)

src/utils/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function replaceHtmlEntities(str: string): string {
2+
return String(str)
3+
.replace(/&/g, '&')
4+
.replace(/</g, '&lt;')
5+
.replace(/>/g, '&gt;')
6+
.replace(/"/g, '&quot;');
7+
}

test/expectedJson.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,8 @@ export default {
20052005
`<iframe src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A%22%3E%3C/iframe%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3Ciframe%20\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A%22%3E%3C/iframe%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3Ciframe%20\"></iframe>`,
20062006
`<iframe width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\"></iframe>`,
20072007
'<iframe src=\"www.youtube.com/watch?v=Gw7EqoOYC9A\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"www.youtube.com/embed/VD6xJq8NguY\"></iframe>',
2008-
`<iframe src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\"></iframe>`
2008+
`<iframe src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\"></iframe>`,
2009+
`<iframe src="null" width="560" height="320" title=" This is for &lt;/p&gt;testing &lt;/p&gt; purpose 'only' " data-type="social-embeds" ></iframe>`
20092010
],
20102011
"json":
20112012
[
@@ -2168,7 +2169,19 @@ export default {
21682169
}
21692170
],
21702171
"_version": 1
2171-
}
2172+
},
2173+
{
2174+
uid: "45a850acbeb949db86afe415625ad1ce",
2175+
type: "social-embeds",
2176+
attrs: {
2177+
src: "null",
2178+
width: 560,
2179+
height: 320,
2180+
title: " This is for </p>testing </p> purpose 'only' "
2181+
},
2182+
children: [{ text: "" }],
2183+
},
2184+
21722185
]
21732186

21742187
}

test/toRedactor.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ describe("Testing json to html conversion", () => {
273273
const html = toRedactor(json);
274274
expect(html).toBe(expectedValue["RT-360"].html[3]);
275275
})
276+
277+
it("should escape html entities in attribute values",()=>{
278+
const json = expectedValue["RT-360"].json[4]
279+
const html = toRedactor(json);
280+
expect(html).toBe(expectedValue["RT-360"].html[4]);
281+
})
276282
})
277283

278284
test('should convert numeric width to string', () => {

0 commit comments

Comments
 (0)