Skip to content

Commit dc9366c

Browse files
committed
Fix #383.
Previously cmark incorrectly parsed input like *****Hello*world**** because once an emphasis opener failed to match a closer of the same shape, it was taken off the list of potential openers. However, if the reason for the match failure is the "mod 3 rule," then the possibility remains that a different closer, later in the string, might match an opener that was rejected. So, if the reason for the match failure was the mod 3 rule, we don't adjust the stack bottom.
1 parent ba699f9 commit dc9366c

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/inlines.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,10 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
644644
delimiter *opener;
645645
delimiter *old_closer;
646646
bool opener_found;
647+
bool mod_three_rule_invoked;
647648
int openers_bottom_index = 0;
648649
delimiter *openers_bottom[6] = {stack_bottom, stack_bottom, stack_bottom,
649-
stack_bottom, stack_bottom, stack_bottom};
650+
stack_bottom};
650651

651652
// move back to first relevant delim.
652653
while (closer != NULL && closer->previous != stack_bottom) {
@@ -667,7 +668,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
667668
openers_bottom_index = 2;
668669
break;
669670
case '*':
670-
openers_bottom_index = 3 + (closer->length % 3);
671+
openers_bottom_index = 3;
671672
break;
672673
default:
673674
assert(false);
@@ -676,6 +677,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
676677
// Now look backwards for first matching opener:
677678
opener = closer->previous;
678679
opener_found = false;
680+
mod_three_rule_invoked = false;
679681
while (opener != NULL && opener != openers_bottom[openers_bottom_index]) {
680682
if (opener->can_open && opener->delim_char == closer->delim_char) {
681683
// interior closer of size 2 can't match opener of size 1
@@ -685,7 +687,9 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
685687
(opener->length + closer->length) % 3 != 0) {
686688
opener_found = true;
687689
break;
688-
}
690+
} else {
691+
mod_three_rule_invoked = true;
692+
}
689693
}
690694
opener = opener->previous;
691695
}
@@ -711,7 +715,12 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
711715
}
712716
if (!opener_found) {
713717
// set lower bound for future searches for openers
714-
openers_bottom[openers_bottom_index] = old_closer->previous;
718+
// unless we failed to match because of the mod 3 rule --
719+
// since in that case another closer could still match an
720+
// earlier opener (see #383).
721+
if (!mod_three_rule_invoked) {
722+
openers_bottom[openers_bottom_index] = old_closer->previous;
723+
}
715724
if (!old_closer->can_open) {
716725
// we can remove a closer that can't be an
717726
// opener, once we've seen there's no

0 commit comments

Comments
 (0)