Repository: raphlinus/pulldown-cmark (rust)

Issue:
[fuzz result] incorrect run length matching in emphasis
Consider this examples, specifically the parts that are underlined with `-`s

```
**a.*.**a*.**.
 -          -
```

The [dingus](https://spec.commonmark.org/dingus/?text=**a.*.**a*.**.%0A%0A*a.*.**a*.**.) and pandoc both match the underlines delimiters together, but pulldown-cmark isn't.

This looks like a bug in lower bound tracking, because lower bounds are being tracked by delimiter length instead of being tracked by run length.

Pull request description:
Fix emphasis run length delimiter lower limit bug
Fixes #741

Patch:
diff --git a/specs/regression.txt b/specs/regression.txt
index 2ecd229..a3f2ddc 100644
--- a/specs/regression.txt
+++ b/specs/regression.txt
@@ -1484,4 +1484,12 @@ an unmatched asterisk.</p>
 <em>{</em>{</p>
 <p><em>x</em>
 <em>{</em>{</p>
-````````````````````````````````
\ No newline at end of file
+````````````````````````````````
+
+ISSUE 741
+
+```````````````````````````````` example
+**a.*.**a*.**.
+.
+<p>*<em>a.*.<em><em>a</em>.</em></em>.</p>
+````````````````````````````````
diff --git a/src/parse.rs b/src/parse.rs
index 167acdf..97d5579 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -583,7 +583,7 @@ impl<'input, 'callback> Parser<'input, 'callback> {
                     let both = can_open && can_close;
                     if can_close {
                         while let Some(el) =
-                            self.inline_stack.find_match(&mut self.tree, c, count, run_length, both)
+                            self.inline_stack.find_match(&mut self.tree, c, run_length, both)
                         {
                             // have a match!
                             if let Some(prev_ix) = prev {
@@ -1116,11 +1116,10 @@ impl InlineStack {
         &mut self,
         tree: &mut Tree<Item>,
         c: u8,
-        count: usize,
         run_length: usize,
         both: bool,
     ) -> Option<InlineEl> {
-        let lowerbound = min(self.stack.len(), self.get_lowerbound(c, count, both));
+        let lowerbound = min(self.stack.len(), self.get_lowerbound(c, run_length, both));
         let res = self.stack[lowerbound..]
             .iter()
             .cloned()
@@ -1139,7 +1138,7 @@ impl InlineStack {
             self.truncate(matching_ix);
             Some(matching_el)
         } else {
-            self.set_lowerbound(c, count, both, self.stack.len());
+            self.set_lowerbound(c, run_length, both, self.stack.len());
             None
         }
     }


Test patch:
diff --git a/tests/suite/regression.rs b/tests/suite/regression.rs
index f844ff5..6ee23f9 100644
--- a/tests/suite/regression.rs
+++ b/tests/suite/regression.rs
@@ -1752,4 +1752,14 @@ an unmatched asterisk.</p>
 "##;
   
     test_markdown_html(original, expected, false, false, false);
-}
\ No newline at end of file
+}
+
+#[test]
+fn regression_test_115() {
+    let original = r##"**a.*.**a*.**.
+"##;
+    let expected = r##"<p>*<em>a.*.<em><em>a</em>.</em></em>.</p>
+"##;
+  
+    test_markdown_html(original, expected, false, false, false);
+}