Skip to content

Commit

Permalink
better fix for code block with definition list #326
Browse files Browse the repository at this point in the history
The bug was not in parsing code blocks but in parsing definition lists
that had code block start marker in previous line. In this case it
wouldn't consume the input, leading to infinite loop
  • Loading branch information
kjk committed Dec 4, 2024
1 parent 87d094f commit 865e83d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
16 changes: 12 additions & 4 deletions parser/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ func (p *Parser) fencedCodeBlock(data []byte, doRender bool) int {
work.WriteString(syntax)
work.WriteByte('\n')

for beg < len(data) {
for {
// check for the end of the code block
fenceEnd, _ := isFenceLine(data[beg:], nil, marker)
if fenceEnd != 0 {
Expand All @@ -963,7 +963,7 @@ func (p *Parser) fencedCodeBlock(data []byte, doRender bool) int {

// did we reach the end of the buffer without a closing marker?
if end >= len(data) {
end = len(data)
return 0
}

// verbatim copy to the working buffer
Expand Down Expand Up @@ -1350,6 +1350,7 @@ func finalizeList(list *ast.List) {
// Parse a single list item.
// Assumes initial prefix is already removed if this is a sublist.
func (p *Parser) listItem(data []byte, flags *ast.ListType) int {
isDefinitionList := *flags&ast.ListTypeDefinition != 0
// keep track of the indentation of the first line
itemIndent := 0
if data[0] == '\t' {
Expand Down Expand Up @@ -1382,7 +1383,7 @@ func (p *Parser) listItem(data []byte, flags *ast.ListType) int {
}
if i == 0 {
// if in definition list, set term flag and continue
if *flags&ast.ListTypeDefinition != 0 {
if isDefinitionList {
*flags |= ast.ListTypeTerm
} else {
return 0
Expand Down Expand Up @@ -1443,7 +1444,14 @@ gatherlines:

// If there is a fence line (marking starting of a code block)
// without indent do not process it as part of the list.
if p.extensions&FencedCode != 0 {
//
// does not apply for definition lists because it causes infinite
// loop if text before defintion term is fenced code block start
// marker but not part of actual fenced code block
// for defnition lists we're called after parsing fence code blocks
// so we kno this cannot be a fenced block
// https://github.com/gomarkdown/markdown/issues/326
if !isDefinitionList && p.extensions&FencedCode != 0 {
fenceLineEnd, _ := isFenceLine(chunk, nil, "")
if fenceLineEnd > 0 && indent == 0 {
*flags |= ast.ListItemEndOfList
Expand Down
3 changes: 2 additions & 1 deletion parser/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ func TestRect(t *testing.T) {

// https://github.com/gomarkdown/markdown/issues/326
func TestInfiniteLoopFix(t *testing.T) {
input := "```\n: "
input := "```\n: la"
p := NewWithExtensions(CommonExtensions)
doc := p.Parse([]byte(input))
if doc == nil {
t.Errorf("Expected non-nil AST")
}
//ast.Print(os.Stdout, doc)
}
1 change: 1 addition & 0 deletions s/run_tests.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
$ErrorActionPreference = 'Stop'
go clean -testcache
#go test -race -v .
#go test -race -v ./ast
Expand Down

0 comments on commit 865e83d

Please sign in to comment.