diff options
author | John MacFarlane <jgm@berkeley.edu> | 2017-01-03 23:28:21 -0800 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2017-01-03 23:28:21 -0800 |
commit | a8d5bd452ae8a7b2d3285a85a9117f95ed1732cc (patch) | |
tree | d5b221fa86bb96ee1f141d31873cbc5a9752ea91 /src | |
parent | b5c4a228252d8351ca42c0ae3bca626dabfff66d (diff) |
Fixes #178, quadratic parsing bug.
Diffstat (limited to 'src')
-rw-r--r-- | src/inlines.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/src/inlines.c b/src/inlines.c index 6a27aea..c8bdebc 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -516,13 +516,16 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) { delimiter *old_closer; bool opener_found; bool odd_match; - delimiter *openers_bottom[128]; + delimiter *openers_bottom[3][128]; + int i; // initialize openers_bottom: - openers_bottom['*'] = stack_bottom; - openers_bottom['_'] = stack_bottom; - openers_bottom['\''] = stack_bottom; - openers_bottom['"'] = stack_bottom; + for (i=0; i < 3; i++) { + openers_bottom[i]['*'] = stack_bottom; + openers_bottom[i]['_'] = stack_bottom; + openers_bottom[i]['\''] = stack_bottom; + openers_bottom[i]['"'] = stack_bottom; + } // move back to first relevant delim. while (closer != NULL && closer->previous != stack_bottom) { @@ -537,7 +540,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) { opener_found = false; odd_match = false; while (opener != NULL && opener != stack_bottom && - opener != openers_bottom[closer->delim_char]) { + opener != openers_bottom[closer->length % 3][closer->delim_char]) { if (opener->can_open && opener->delim_char == closer->delim_char) { // interior closer of size 2 can't match opener of size 1 // or of size 1 can't match 2 @@ -574,13 +577,10 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) { } closer = closer->next; } - if (!opener_found && !odd_match) { + if (!opener_found) { // set lower bound for future searches for openers - // (we don't do this with 'odd_match' set because - // a ** that didn't match an earlier * might turn into - // an opener, and the * might be matched by something - // else. - openers_bottom[old_closer->delim_char] = old_closer->previous; + openers_bottom[old_closer->length % 3][old_closer->delim_char] = + old_closer->previous; if (!old_closer->can_open) { // we can remove a closer that can't be an // opener, once we've seen there's no |