Repository: raphlinus/pulldown-cmark (rust)

Issue:
[fuzz results] inline nested footnote defs don't work
This markdown:

```markdown
[^foo] [^bar]

[^foo]: [^bar]: 1
```

should work like this:

[^foo] [^bar]

[^foo]: [^bar]: 1

<details>

Events from pulldown-cmark:

```rust
"-*-FD\n[^+\\&~+ppppppppppp]:[^+\\&~+]:1          +\n\n*1    ppp]:[^+\\&~+]:*    D\n" -> [
  Start(Paragraph)
    Text(Boxed("-*-FD"))
  End(Paragraph)
  Start(Paragraph)
    Start(Emphasis)
      Text(Boxed("1 ppp]:[^+&~+]:"))
    End(Emphasis)
    Text(Boxed(" D"))
  End(Paragraph)
]
```

Events from pandoc:

```rust
"-*-FD\n[^+\\&~+ppppppppppp]:[^+\\&~+]:1          +\n\n*1    ppp]:[^+\\&~+]:*    D\n" -> [
  Start(Paragraph)
    Text(Boxed("-*-FD"))
  End(Paragraph)
  Start(Paragraph)
    Start(Emphasis)
      Text(Boxed("1 ppp]:"))
      FootnoteReference(Boxed("1"))
      Start(FootnoteDefinition(Boxed("1")))
        Start(Paragraph)
          Text(Inlined(InlineStr { inner: [49, 32, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 3 }))
        End(Paragraph)
      End(FootnoteDefinition)
      Text(Boxed(":"))
    End(Emphasis)
    Text(Boxed(" D"))
  End(Paragraph)
]
```

</details>

Pull request description:
Parse inline nested footnote definitions
Fixes #770

They look like this:

    [^foo]: [^bar]: test

They don't make much sense (foo is empty), but everyone else parses them correctly, so we should too.

Patch:
diff --git a/specs/footnotes.txt b/specs/footnotes.txt
index fb3fe6a..26c6262 100644
--- a/specs/footnotes.txt
+++ b/specs/footnotes.txt
@@ -237,6 +237,7 @@ As such, we can guarantee that the non-childish forms of entertainment are proba
 
 
 As a special exception, footnotes cannot be nested directly inside each other.
+If they are, they act like they're declared beside each other.
 
 ```````````````````````````````` example
 Nested footnotes are considered poor style. [^a] [^xkcd] [^indent1] [^indent2]
@@ -278,6 +279,17 @@ Nested footnotes are considered poor style. [^a] [^xkcd] [^indent1] [^indent2]
 </div>
 ````````````````````````````````
 
+```````````````````````````````` example
+[^foo] [^bar]
+
+[^foo]: [^bar]: 1
+.
+<p><sup class="footnote-reference"><a href="#foo">1</a></sup> <sup class="footnote-reference"><a href="#bar">2</a></sup></p>
+<div class="footnote-definition" id="foo"><sup class="footnote-definition-label">1</sup></div>
+<div class="footnote-definition" id="bar"><sup class="footnote-definition-label">2</sup>
+<p>1</p>
+</div>
+````````````````````````````````
 
 They do **not** need one line between each other.
 
diff --git a/src/firstpass.rs b/src/firstpass.rs
index 268ab4e..817a562 100644
--- a/src/firstpass.rs
+++ b/src/firstpass.rs
@@ -112,6 +112,7 @@ impl<'a, 'b> FirstPass<'a, 'b> {
                     if let Some(bytecount) = self.parse_footnote(container_start) {
                         start_ix = container_start + bytecount;
                         line_start = LineStart::new(&bytes[start_ix..]);
+                        continue;
                     } else {
                         line_start = save;
                     }


Test patch:
diff --git a/tests/suite/footnotes.rs b/tests/suite/footnotes.rs
index e81e610..7fce03c 100644
--- a/tests/suite/footnotes.rs
+++ b/tests/suite/footnotes.rs
@@ -282,6 +282,22 @@ fn footnotes_test_11() {
 
 #[test]
 fn footnotes_test_12() {
+    let original = r##"[^foo] [^bar]
+
+[^foo]: [^bar]: 1
+"##;
+    let expected = r##"<p><sup class="footnote-reference"><a href="#foo">1</a></sup> <sup class="footnote-reference"><a href="#bar">2</a></sup></p>
+<div class="footnote-definition" id="foo"><sup class="footnote-definition-label">1</sup></div>
+<div class="footnote-definition" id="bar"><sup class="footnote-definition-label">2</sup>
+<p>1</p>
+</div>
+"##;
+
+    test_markdown_html(original, expected, false, false, false);
+}
+
+#[test]
+fn footnotes_test_13() {
     let original = r##"[^Doh] Ray Me Fa So La Te Do! [^1]
 
 [^Doh]: I know. Wrong Doe. And it won't render right.
@@ -300,7 +316,7 @@ fn footnotes_test_12() {
 }
 
 #[test]
-fn footnotes_test_13() {
+fn footnotes_test_14() {
     let original = r##"Lorem ipsum.[^a]
 
 An unordered list before the footnotes:
@@ -324,7 +340,7 @@ An unordered list before the footnotes:
 }
 
 #[test]
-fn footnotes_test_14() {
+fn footnotes_test_15() {
     let original = r##"Songs that simply loop are a popular way to annoy people. [^examples]
 
 [^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ)
@@ -381,7 +397,7 @@ Songs that simply loop are a popular way to annoy people. [^examples3]
 }
 
 #[test]
-fn footnotes_test_15() {
+fn footnotes_test_16() {
     let original = r##"My [cmark-gfm][^c].
 
 My [cmark-gfm][cmark-gfm][^c].
@@ -419,7 +435,7 @@ test suite into pulldown-cmark should be fine.</p>
 }
 
 #[test]
-fn footnotes_test_16() {
+fn footnotes_test_17() {
     let original = r##"[^1]: footnote definition text
 
 <!-- -->
@@ -444,7 +460,7 @@ fn main() {
 }
 
 #[test]
-fn footnotes_test_17() {
+fn footnotes_test_18() {
     let original = r##"[^1]: footnote definition text
 [^1]\: this is a reference, rather than a definition
 "##;
@@ -458,7 +474,7 @@ fn footnotes_test_17() {
 }
 
 #[test]
-fn footnotes_test_18() {
+fn footnotes_test_19() {
     let original = r##"[^1]:
 
     | column1 | column2 |
@@ -482,7 +498,7 @@ fn footnotes_test_18() {
 }
 
 #[test]
-fn footnotes_test_19() {
+fn footnotes_test_20() {
     let original = r##"* First
   [^1]: test
 * Second [^1] test
@@ -544,7 +560,7 @@ Second <sup class="footnote-reference"><a href="#2">2</a></sup> test</p>
 }
 
 #[test]
-fn footnotes_test_20() {
+fn footnotes_test_21() {
     let original = r##"Test [^] link
 
 [^]: https://rust-lang.org
@@ -556,7 +572,7 @@ fn footnotes_test_20() {
 }
 
 #[test]
-fn footnotes_test_21() {
+fn footnotes_test_22() {
     let original = r##"[^foo\
 bar]: not a footnote definition
 
@@ -596,7 +612,7 @@ fourth]</p>
 }
 
 #[test]
-fn footnotes_test_22() {
+fn footnotes_test_23() {
     let original = r##"[^foo
 ]: https://rust-lang.org
 
@@ -611,7 +627,7 @@ fn footnotes_test_22() {
 }
 
 #[test]
-fn footnotes_test_23() {
+fn footnotes_test_24() {
     let original = r##"footnote [^baz]
 footnote [^quux]