Blocks encoding in entityToHTML
I was wondering why a ENTITY_MAP is used to convert text in entities, here https://github.com/HubSpot/draft-convert/blob/master/src/encodeBlock.js#L4 ?
Because this is what is happening when using a entityToHTML function to transform links into real <a>:
Editor:
Result after convertToHTML:
Only because it's in a entity (a link).
Why?
Do I have to use a decoder on originalText to display the original text?
ENTITY_MAP that you linked to is referring to HTML entities, not Draft entities. They're there to escape any HTML entities that make it into the plain text of the editor content. The escaping is done before any entityToHTML processing happens, so it doesn't affect any HTML defined by your entityToHTML function, just the text wrapped by the Draft entity.
Not escaping these HTML entities is a pretty glaring vulnerability, since then if i were to write <script>alert('test');<script> in in the editor in the same way you wrote <this> would make it through into the output HTML.
Here is my code:
convertToHTML({
entityToHTML: (entity, originalText) => {
console.log('originalText', originalText) // display "Here's my address"
if (entity.type === 'link') {
return {
start: `<a href="${entity.data.url}">`,
end: '</a>',
}
}
return originalText
}
})(contentState)
Where the console.log is I have Here's my address, so originalText is escaped.
My entityToHTML is passed here https://github.com/HubSpot/draft-convert/blob/master/src/convertToHTML.js#L30, which is used here https://github.com/HubSpot/draft-convert/blob/master/src/convertToHTML.js#L86.
blockEntities receives an encoded block:
encodeBlock(
block
),
which is transforming HTML entities with ENTITY_MAP.
My concern is that in entityToHTML, originalText is escaped. I want to display Here's my address in my link, not Here's my address. Everytime entityToHTML is called, it's originalText is escaped.
If you put Here's my address in an HTML page it will render as Here's my address, though - it's an HTML encoded version of the character. Like I said originalText (and all text in the editor contents) must be escaped or it's a massive security vulnerability, since the natural use for the HTML output is to use it in a page directly.
I understand the escape necessity, but here is without link:
<div>Here's</div>
Here is with a link:
<div><a href="http://google.com">Here&#x27;s</a></div>
Apparently in the entityToHTML the encoding of the string is called a second time which transformed ' to ' a first time, then ' to &#x27; a second time, resulting in displaying ' instead of '.
Ahh I see. Interesting, thanks for bearing with me @jebarjonet. Are you using the same code that you posted above when converting to HTML? The first thing that came to mind as the culprit was using ReactElements to render out the HTML like this:
entityToHTML: (entity, originalText) => {
if (entity.type === 'link') {
return <a href={entity.data.url}>{originalText}</a>; // originalText is double-escaped
}
return originalText;
}
Since React automatically escapes text nodes. However the example you posted above uses a string to convert, which I cannot reproduce the issue with. Additionally returning an empty ReactElement avoids the problem:
entityToHTML: (entity, originalText) => {
if (entity.type === 'link') {
return <a href={entity.data.url} />; // originalText is escaped once
}
return originalText;
}
The first example I can fix, but there should be some already available workarounds in the meanwhile.
You are right. It works well with
return <a href={entity.data.url} />
and
return {
start: `<a href="${entity.data.url}">`,
end: '</a>',
}
Thank you!
I just does not work well with
return <a href={entity.data.url}>{originalText}</a>
Great! I'll try to find some time to put together a solution for that case.
@benbriggs could you please tell us when the fix for the issue will be published?
I have the same problem with link text like Click > here. Though the workaround (removing originalText from link) works, I'd like to have an out-of-the-box solution for I don't have to google finding out that I shouldn't have added originalText into link tag. Or it should be highlighted in the official docs with a special paragraph or h1 tag in order that anyone who copy-pastes example code will avoid this issue out-of-the-box