Skip to content

Commit 7e49343

Browse files
nwellnhofkevinbackhouse
authored andcommitted
Fix quadratic behavior with smart quotes
Make sure to remove matching smart quote delimiters. Otherwise, the same opener could be found over and over again, preventing the `openers_bottom` optimization from kicking in and leading to quadratic behavior when processing lots of quotes. Fixes commonmark#388.
1 parent 6a6e335 commit 7e49343

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/inlines.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -696,22 +696,24 @@ static void process_emphasis(cmark_parser *parser, subject *subj, delimiter *sta
696696
} else {
697697
closer = closer->next;
698698
}
699-
} else if (closer->delim_char == '\'') {
699+
} else if (closer->delim_char == '\'' || closer->delim_char == '"') {
700700
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
701-
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
702-
if (opener_found) {
703-
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
704-
opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
701+
if (closer->delim_char == '\'') {
702+
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
703+
} else {
704+
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
705705
}
706706
closer = closer->next;
707-
} else if (closer->delim_char == '"') {
708-
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
709-
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
710707
if (opener_found) {
711708
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
712-
opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
709+
if (old_closer->delim_char == '\'') {
710+
opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
711+
} else {
712+
opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
713+
}
714+
remove_delimiter(subj, opener);
715+
remove_delimiter(subj, old_closer);
713716
}
714-
closer = closer->next;
715717
}
716718
if (!opener_found) {
717719
// set lower bound for future searches for openers

0 commit comments

Comments
 (0)