From f7bb9972194d3cea0cf03a1fabf32fa72c20ce04 Mon Sep 17 00:00:00 2001 From: "Stanislav (Stas) Katkov" Date: Thu, 14 May 2026 16:07:38 +0200 Subject: [PATCH 1/2] Resolve markdown crash for invalid note reference Issue originally reported here: https://github.com/ruby/rdoc/issues/654 --- lib/rdoc/markdown.kpeg | 2 ++ lib/rdoc/markdown.rb | 2 ++ test/rdoc/rdoc_markdown_test.rb | 10 ++++++++++ 3 files changed, 14 insertions(+) diff --git a/lib/rdoc/markdown.kpeg b/lib/rdoc/markdown.kpeg index 0e15a604f4..b9a0990e62 100644 --- a/lib/rdoc/markdown.kpeg +++ b/lib/rdoc/markdown.kpeg @@ -403,6 +403,8 @@ # the note order list for proper display at the end of the document. def note_for ref + raise ParseError, "invalid note reference: #{ref}" unless @note_order + @note_order << ref label = @note_order.length diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb index c01cab0096..f6cfc9a24d 100644 --- a/lib/rdoc/markdown.rb +++ b/lib/rdoc/markdown.rb @@ -788,6 +788,8 @@ def note label # the note order list for proper display at the end of the document. def note_for ref + raise ParseError, "invalid note reference: #{ref}" unless @note_order + @note_order << ref label = @note_order.length diff --git a/test/rdoc/rdoc_markdown_test.rb b/test/rdoc/rdoc_markdown_test.rb index 646f12a999..b73300f578 100644 --- a/test/rdoc/rdoc_markdown_test.rb +++ b/test/rdoc/rdoc_markdown_test.rb @@ -1002,6 +1002,16 @@ def test_parse_note_inline assert_equal expected, doc end + def test_parse_note_invalid_reference + @parser.notes = true + + error = assert_raise RDoc::Markdown::ParseError do + parse "[[^0]\n" + end + + assert_equal "invalid note reference: 0", error.message + end + def test_parse_note_no_notes @parser.notes = false From 2505a3a88f3ae56e7f8a8955ee7e7c4c2689f366 Mon Sep 17 00:00:00 2001 From: "Stanislav (Stas) Katkov" Date: Thu, 14 May 2026 22:04:00 +0200 Subject: [PATCH 2/2] Ignore note references before note ordering Note references can be parsed while Markdown references are being collected, before footnote ordering has started. Treat that early pass as a no-op so malformed reference labels and valid labels containing footnotes do not crash the parser. --- lib/rdoc/markdown.kpeg | 2 +- lib/rdoc/markdown.rb | 2 +- test/rdoc/rdoc_markdown_test.rb | 21 +++++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/rdoc/markdown.kpeg b/lib/rdoc/markdown.kpeg index b9a0990e62..893204151f 100644 --- a/lib/rdoc/markdown.kpeg +++ b/lib/rdoc/markdown.kpeg @@ -403,7 +403,7 @@ # the note order list for proper display at the end of the document. def note_for ref - raise ParseError, "invalid note reference: #{ref}" unless @note_order + return unless @note_order @note_order << ref diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb index f6cfc9a24d..4326fb6549 100644 --- a/lib/rdoc/markdown.rb +++ b/lib/rdoc/markdown.rb @@ -788,7 +788,7 @@ def note label # the note order list for proper display at the end of the document. def note_for ref - raise ParseError, "invalid note reference: #{ref}" unless @note_order + return unless @note_order @note_order << ref diff --git a/test/rdoc/rdoc_markdown_test.rb b/test/rdoc/rdoc_markdown_test.rb index b73300f578..5d432c6cc5 100644 --- a/test/rdoc/rdoc_markdown_test.rb +++ b/test/rdoc/rdoc_markdown_test.rb @@ -1005,11 +1005,24 @@ def test_parse_note_inline def test_parse_note_invalid_reference @parser.notes = true - error = assert_raise RDoc::Markdown::ParseError do - parse "[[^0]\n" - end + assert_kind_of RDoc::Markup::Document, parse("[[^0]\n") + end + + def test_parse_note_reference_in_reference_label + @parser.notes = true + + doc = parse <<~MD + [foo[^1]bar] - assert_equal "invalid note reference: 0", error.message + [^1]: footnote + MD + + expected = doc( + para("[foo{*1}[rdoc-label:foottext-1:footmark-1]bar]"), + rule(1), + para("{^1}[rdoc-label:footmark-1:foottext-1] footnote")) + + assert_equal expected, doc end def test_parse_note_no_notes