Repository: raphlinus/pulldown-cmark (rust)

Issue:
[fuzz result] last line of link title is silently eaten
Here's a readable reduction:

```console
$ cargo run
   Compiling pulldown-cmark v0.9.2 (/home/michael/Development/pulldown-cmark)
    Finished dev [unoptimized + debuginfo] target(s) in 1.22s
     Running `target/debug/pulldown-cmark`
[mylink]

[mylink]: https://example.com
'
not part of the title'
<p><a href="https://example.com" title="
">mylink</a></p>
```

The phrase "not part of the title" should be part of the title, and it isn't.

<details>

```rust
"/ [^~]:'\nR\n+  [^~]:[\n'\n]^~]?'\n\n[\n" -> [
  Start(Paragraph)
    Text(Borrowed("/ "))
    Start(Link { link_type: Inline, dest_url: Borrowed("["), title: Inlined(InlineStr { inner: [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 1 }), id: Borrowed("") })
      Text(Borrowed("^~"))
    End(Link)
    Text(Boxed(":'"))
    SoftBreak
    Text(Boxed("R"))
  End(Paragraph)
  Start(List(None))
    Start(Item)
    End(Item)
  End(List(false))
  Start(Paragraph)
    Text(Borrowed("["))
  End(Paragraph)
]
```

Events from pandoc:

```rust
"/ [^~]:'\nR\n+  [^~]:[\n'\n]^~]?'\n\n[\n" -> [
  Start(Paragraph)
    Text(Boxed("/ "))
    Start(Link { link_type: Inline, dest_url: Inlined(InlineStr { inner: [91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 1 }), title: Inlined(InlineStr { inner: [10, 93, 94, 126, 93, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }), id: Borrowed("") })
      Text(Boxed("^~"))
    End(Link)
    Text(Boxed(":'"))
    SoftBreak
    Text(Boxed("R"))
  End(Paragraph)
  Start(List(None))
    Start(Item)
    End(Item)
  End(List(false))
  Start(Paragraph)
    Text(Boxed("["))
  End(Paragraph)
]
```

Events from commonmark.js:

```rust
"/ [^~]:'\nR\n+  [^~]:[\n'\n]^~]?'\n\n[\n" -> [
  Start(Paragraph)
    Text(Boxed("/ "))
    Start(Link { link_type: Inline, dest_url: Inlined(InlineStr { inner: [91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 1 }), title: Inlined(InlineStr { inner: [10, 93, 94, 126, 93, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }), id: Borrowed("") })
      Text(Boxed("^~"))
    End(Link)
    Text(Boxed(":'"))
    SoftBreak
    Text(Boxed("R"))
  End(Paragraph)
  Start(List(None))
    Start(Item)
    End(Item)
  End(List(false))
  Start(Paragraph)
    Text(Boxed("["))
  End(Paragraph)
]
```

</details>


Pull request:
Include last of line of link title
Fixes #808


Patch:
diff --git a/specs/regression.txt b/specs/regression.txt
index 457ec71..a82dee2 100644
--- a/specs/regression.txt
+++ b/specs/regression.txt
@@ -2116,3 +2116,16 @@ baz`</li>
 baz](https://example.com)</li>
 </ul>
 ````````````````````````````````
+
+ISSUE 808
+
+```````````````````````````````` example
+[mylink]
+
+[mylink]: https://example.com
+'
+part of the title'
+.
+<p><a href="https://example.com" title="
+part of the title">mylink</a></p>
+````````````````````````````````
diff --git a/src/firstpass.rs b/src/firstpass.rs
index b3d59e9..88532a7 100644
--- a/src/firstpass.rs
+++ b/src/firstpass.rs
@@ -1520,7 +1520,12 @@ impl<'a, 'b> FirstPass<'a, 'b> {
                     }
                 }
                 c if c == closing_delim => {
-                    let cow = linebuf.map(CowStr::from).unwrap_or(CowStr::from(&text[linestart..bytecount]));
+                    let cow = if let Some(mut linebuf) = linebuf {
+                        linebuf.push_str(&text[linestart..bytecount]);
+                        CowStr::from(linebuf)
+                    } else {
+                        CowStr::from(&text[linestart..bytecount])
+                    };
                     return Some((bytecount + 1, cow));
                 }
                 _ => {


Test patch:
diff --git a/tests/suite/regression.rs b/tests/suite/regression.rs
index 87eafc9..6da9535 100644
--- a/tests/suite/regression.rs
+++ b/tests/suite/regression.rs
@@ -2492,3 +2492,18 @@ baz](https://example.com)</li>
 
     test_markdown_html(original, expected, false, false, false);
 }
+
+#[test]
+fn regression_test_154() {
+    let original = r##"[mylink]
+
+[mylink]: https://example.com
+'
+part of the title'
+"##;
+    let expected = r##"<p><a href="https://example.com" title="
+part of the title">mylink</a></p>
+"##;
+
+    test_markdown_html(original, expected, false, false, false);
+}