Skip to content

Commit 5885b3f

Browse files
committed
Don't allow objects split between elements
1 parent a2883b7 commit 5885b3f

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

src/lexer.jl

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,9 +1146,10 @@ skipchars(bytes::DenseVector{UInt8}, pos::Integer, charsets::Union{StepRange{Cha
11461146
11471147
Skip over a balanced pair of characters (`bpair`) in `bytes` starting at `pos`.
11481148
1149-
It is expected that `bytes[pos]` is the opening character of the pair, from which
1150-
point all characters until as many closing characters of the pair have been
1151-
encountered as opening characters.
1149+
It is expected that `bytes[pos]` is the opening character of the pair, from
1150+
which point all characters until as many closing characters of the pair have
1151+
been encountered as opening characters. Searching will halt if a heading or
1152+
blank line is encountered.
11521153
11531154
If `quotes` is provided, then the characters in `quotes` are considered as
11541155
additional opening characters, only characters outside quotes are considered.
@@ -1177,14 +1178,29 @@ function skipbalanced(bytes::DenseVector{UInt8}, pos::Integer, bpair::Pair{Char,
11771178
uclose = UInt8(last(bpair))
11781179
uquotes = map(q -> UInt8(q), quotes)
11791180
uescape = UInt8(something(escapechar, '\0'))
1181+
afternewline = false
11801182
depth = 1
11811183
currentquote = 0x00
11821184
bytes[pos] == uopen || return zero(pos)
11831185
pos += 0x1
11841186
while true
11851187
pos <= limit || break
11861188
chr = bytes[pos]
1187-
if !isnothing(escapechar) && chr == uescape && pos < limit
1189+
if afternewline
1190+
chr == UInt8('*') && let starend = skipchars(bytes, pos, '*')
1191+
starend < length(bytes) && bytes[starend] == UInt8(' ') && break
1192+
end
1193+
if iswhitespace(bytes, pos)
1194+
pos = skipspaces(bytes, pos).stop
1195+
pos <= limit || break
1196+
chr = bytes[pos]
1197+
end
1198+
chr == UInt8('\n') && break
1199+
afternewline = false
1200+
end
1201+
if chr == UInt8('\n')
1202+
afternewline = true
1203+
elseif !isnothing(escapechar) && chr == uescape && pos < limit
11881204
pos += 0x1
11891205
elseif currentquote != 0
11901206
if chr == currentquote

test/runtests.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,13 @@ end
484484
[Token(K"<paragraph", 1, 1)]
485485
@test collect(Lexer("@@inv alid:@@")) ==
486486
[Token(K"<paragraph", 1, 1)]
487+
@test collect(Lexer("@@x:multi\nline@@")) ==
488+
[Token(K"<paragraph", 1, 1),
489+
Token(K"export_snippet[148]", 1, 16)]
490+
@test collect(Lexer("@@x:dis\n\ncontinued@@")) ==
491+
[Token(K"<paragraph", 1, 1),
492+
Token(K">paragraph", 7, 7),
493+
Token(K"<paragraph", 10, 10)]
487494
@test collect(Lexer("@@x:content@@")) ==
488495
[Token(K"<paragraph", 1, 1),
489496
Token(K"export_snippet[148]", 1, 13)]
@@ -509,6 +516,21 @@ end
509516
@test collect(Lexer("[fn:label:desc]")) ==
510517
[Token(K"<paragraph", 1, 1)
511518
Token(K"footnote_reference[3]", 1, 15)]
519+
@test collect(Lexer("[fn:1:multi\nline]")) ==
520+
[Token(K"<paragraph", 1, 1),
521+
Token(K"footnote_reference[3]", 1, 17)]
522+
@test collect(Lexer("[fn:1:multi\n*bold*\nline]")) ==
523+
[Token(K"<paragraph", 1, 1),
524+
Token(K"footnote_reference[3]", 1, 24)]
525+
@test collect(Lexer("[fn::dis\n* heading\ncontinued]")) ==
526+
[Token(K"<paragraph", 1, 1),
527+
Token(K">paragraph", 8, 8),
528+
Token(K"heading[1]", 10, 18),
529+
Token(K"<paragraph", 20, 20)]
530+
@test collect(Lexer("[fn::dis\n\ncontinued]")) ==
531+
[Token(K"<paragraph", 1, 1),
532+
Token(K">paragraph", 8, 8),
533+
Token(K"<paragraph", 11, 11)]
512534
@test collect(Lexer("[fn:in valid]")) ==
513535
[Token(K"<paragraph", 1, 1)]
514536
end

0 commit comments

Comments
 (0)