FindClosestBlock incorrectly returns LinkReferenceDefinitionGroup #575

Open
opened 2026-01-29 14:40:08 +00:00 by claunia · 2 comments
Owner

Originally created by @AmadeusW on GitHub (Nov 14, 2022).

FindClosestBlock incorrectly returns LinkReferenceDefinitionGroup when:

  • Markdown document ends with a list,
  • AutoIdentifierExtension is active and provides the LinkReferenceDefinitionGroup
  • I call MarkdownDocument.FindClosestBlock() passing in line number of "Second list item" - hoping to get the second ListItemBlock

Example document, parsed with Markdig 0.30.4

Paragraph
 - First list item with a [link](target.txt)
 - Second list item with a [link](target.txt) <eod>

Associated MarkdownDocument has the following items at the end of the blocks collection:

ParapgraphBlock
ListBlock
LinkReferenceDefinitionGroup

MarkdownDocument.FindClosestBlock() incorrectly determines that the closest block is LinkReferenceDefinitionGroup, because it happens to be the last item in the blocks.
LinkReferenceDefinitionGroup should not be returned as it does not even exist in the actual document: LinkReferenceDefinitionGroup.Span is {0 - -1}, it IsEmpty and it's Line is 0.

This issue doesn't happen if I call MarkdownDocument.FindClosestBlock() passing in line number of "First list item" which directly matches the ListBlock, or if I type underneath the list, which places ParagraphBlock underneath ListBlock, and prevents the binary search from stumbling upon LinkReferenceDefinitionGroup.

Originally created by @AmadeusW on GitHub (Nov 14, 2022). `FindClosestBlock` incorrectly returns `LinkReferenceDefinitionGroup` when: - Markdown document ends with a list, - `AutoIdentifierExtension` is active and provides the `LinkReferenceDefinitionGroup` - I call `MarkdownDocument.FindClosestBlock()` passing in line number of "Second list item" - hoping to get the second `ListItemBlock` Example document, parsed with `Markdig 0.30.4` ``` Paragraph - First list item with a [link](target.txt) - Second list item with a [link](target.txt) <eod> ``` Associated `MarkdownDocument` has the following items at the end of the `blocks` collection: ``` ParapgraphBlock ListBlock LinkReferenceDefinitionGroup ``` `MarkdownDocument.FindClosestBlock()` incorrectly determines that the closest block is `LinkReferenceDefinitionGroup`, because it happens to be the last item in the `blocks`. `LinkReferenceDefinitionGroup` should not be returned as it does not even exist in the actual document: `LinkReferenceDefinitionGroup.Span` is `{0 - -1}`, it `IsEmpty` and it's `Line` is `0`. This issue doesn't happen if I call `MarkdownDocument.FindClosestBlock()` passing in line number of "First list item" which directly matches the `ListBlock`, or if I type underneath the list, which places `ParagraphBlock` underneath `ListBlock`, and prevents the binary search from stumbling upon `LinkReferenceDefinitionGroup`.
claunia added the question label 2026-01-29 14:40:08 +00:00
Author
Owner

@AmadeusW commented on GitHub (Nov 14, 2022):

What are your thoughts on the fix?
Excluding the zero-length ListReferenceDefinitionGroup from Document's children seems more appropriate than special-casing the binary search in FindClosestBlock to ignore empty elements. I'm not sure what would be the side effects of removing the ListReferenceDefinitnionGroup from Document's children, though.

@AmadeusW commented on GitHub (Nov 14, 2022): What are your thoughts on the fix? Excluding the zero-length `ListReferenceDefinitionGroup` from Document's children seems more appropriate than special-casing the binary search in `FindClosestBlock` to ignore empty elements. I'm not sure what would be the side effects of removing the `ListReferenceDefinitnionGroup` from Document's children, though.
Author
Owner

@xoofx commented on GitHub (Nov 18, 2022):

Excluding the zero-length ListReferenceDefinitionGroup from Document's children seems more appropriate than special-casing the binary search in FindClosestBlock to ignore empty elements. I'm not sure what would be the side effects of removing the ListReferenceDefinitnionGroup from Document's children, though.

Afair, ListReferenceDefinitnionGroup is an internal (and not visible) block that keeps track of link definitions. I guess, you can probably remove it after the document has been parsed.
It could be also special cased in the FindClosestBlock by fixing var upperIndex = blocks.Count - 1; if the last block is ListReferenceDefinitnionGroup. But all of this is very old to me, so all I'm saying here might be completely irrelevant! 😅

@xoofx commented on GitHub (Nov 18, 2022): > Excluding the zero-length ListReferenceDefinitionGroup from Document's children seems more appropriate than special-casing the binary search in FindClosestBlock to ignore empty elements. I'm not sure what would be the side effects of removing the ListReferenceDefinitnionGroup from Document's children, though. Afair, `ListReferenceDefinitnionGroup` is an internal (and not visible) block that keeps track of link definitions. I guess, you can probably remove it after the document has been parsed. It could be also special cased in the `FindClosestBlock` by fixing `var upperIndex = blocks.Count - 1;` if the last block is `ListReferenceDefinitnionGroup`. But all of this is very old to me, so all I'm saying here might be completely irrelevant! 😅
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#575