fix(react): prevent intra-word _ and * from rendering as emphasis - #1375
rahulnits-sketch wants to merge 1 commit into
Conversation
0151fef to
bd8a429
Compare
|
Hi @Spiral-Memory, I have updated the commit author to align with my signed CLA, so all checks (including the CLA assistant) are now passing green ✅. The changes in |
ishan-one8
left a comment
There was a problem hiding this comment.
Hi @rahulnits-sketch — fair warning before anything else: I filed #1372 and I have an overlapping PR open (#1376), so I'm not a neutral reviewer here. I'd rather be useful than quiet about it, so I checked your branch out and actually ran it instead of just reading the diff.
The three cases from the issue are genuinely fixed, and _italic_, **bold**, __init__ and (_italic_) all still work. I ran your branch and develop through the reference commonmark package side by side, and two cases come out worse than before this change:
| Input | develop today |
this PR | commonmark |
|---|---|---|---|
**bold**text |
<strong>bold</strong>text |
*<em>bold</em>*text |
<strong>bold</strong>text |
foo*bar*baz |
foo<em>bar</em>baz |
foo*bar*baz |
foo<em>bar</em>baz |
The first one looks like a real regression — the output gains stray asterisks and drops from <strong> to <em>. I left line comments on where I think each comes from.
My actual question (not rhetorical — I couldn't work it out from the diff): what is the isAlphanumeric(nextChar) check on line 62 for? CommonMark's closing rule cares about whitespace before the closer, and only _ cares about a word character after it. I'm guessing you hit a specific input that needed it and I can't reconstruct which one — if you tell me, I suspect it changes what the right fix is.
Nothing here is blocking from me; I'm not a maintainer. Just passing on what the comparison turned up.
|
|
||
| if (isWhitespace(firstInside) || isWhitespace(lastInside)) return false; | ||
| if (isAlphanumeric(prevChar)) return false; | ||
| if (isAlphanumeric(nextChar)) return false; |
There was a problem hiding this comment.
This line is what breaks **bold**text.
For that input the ** run is rejected here (nextChar is t), so the loop falls back one character and re-matches a single * instead. That single * does pass the checks, so you end up emitting <em>bold</em> plus two leftover literal asterisks: *<em>bold</em>*text. On develop the same input renders correctly as <strong>bold</strong>text, so this is a regression rather than a pre-existing gap.
The related one: this check also rejects intra-word *, which CommonMark actually allows — foo*bar*baz is foo<em>bar</em>baz in the reference implementation, and on develop today, but renders literally with this PR.
Scoping the word-character rule to _ only would fix both — _ is the one CommonMark forbids inside a word, * is deliberately allowed.
| @@ -92,7 +112,10 @@ const appendMarkdown = (parent, text) => { | |||
| if (token) { | |||
| const [marker, tagName] = token; | |||
| const end = text.indexOf(marker, index + marker.length); | |||
There was a problem hiding this comment.
Minor, and separate from the regression above: end is resolved once here, so when the nearest closer fails isValidEmphasis the whole run is abandoned even if a valid closer exists further along.
*foo * bar* is the case — commonmark gives <em>foo * bar</em>, this PR leaves it literal. Continuing the scan (indexOf(marker, end + marker.length) in a loop until one passes) handles it. Worth a follow-up rather than something I'd hold this PR for.
Brief Title
fix(react): prevent intra-word
_and*from rendering as emphasis in composerAcceptance Criteria fulfillment
_and*delimiters from being parsed as italics or bold (e.g.my_file_name.js,foo_bar_baz)2 * 3 * 4) do not trigger emphasis_italic_,**bold**,(_italic_))yarn buildFixes #1372
PR Test Details
Note: The PR will be ready for live testing at https://rocketchat.github.io/EmbeddedChat/pulls/pr-1375 after approval.
Test Matrix
my_file_name.jsmy<em>file</em>name.jsmy_file_name.jscall foo_bar_baz() nowcall foo<em>bar</em>baz() nowcall foo_bar_baz() now2 * 3 * 4 = 242 <em> 3 </em> 4 = 242 * 3 * 4 = 24This is _italic_ textThis is <em>italic</em> textThis is <em>italic</em> textThis is **bold** textThis is <strong>bold</strong> textThis is <strong>bold</strong> text(_italic_)(<em>italic</em>)(<em>italic</em>)