Skip to content

Commit a1fc199

Browse files
authored
Merge pull request #682 from kivikakk/push-txtvvkrsnxqk
don't append a newline at EOF; handle it in the parser.
2 parents 32b4f7d + a374c3c commit a1fc199

File tree

16 files changed

+832
-397
lines changed

16 files changed

+832
-397
lines changed

fuzz/fuzz_targets/all_options.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct FuzzExtensionOptions {
5454
subscript: bool,
5555
subtext: bool,
5656
cjk_friendly_emphasis: bool,
57+
highlight: bool,
58+
// non-bool below
5759
header_ids: bool,
5860
front_matter_delimiter: bool,
5961
image_url_rewriter: bool,
@@ -88,6 +90,8 @@ impl FuzzExtensionOptions {
8890
subscript: self.subscript,
8991
subtext: self.subtext,
9092
cjk_friendly_emphasis: self.cjk_friendly_emphasis,
93+
highlight: self.highlight,
94+
// non-bool below
9195
header_ids: if self.header_ids {
9296
Some("user-content-".into())
9397
} else {

src/arena_tree.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ impl<'a, T> Node<'a, T> {
205205
self.last_child.set(Some(new_child));
206206
}
207207

208+
/// Append multiple new children to this node, after existing children.
209+
pub fn extend(&'a self, new_children: impl IntoIterator<Item = &'a Node<'a, T>>) {
210+
for child in new_children.into_iter() {
211+
self.append(child);
212+
}
213+
}
214+
208215
/// Prepend a new child to this node, before existing children.
209216
pub fn prepend(&'a self, new_child: &'a Node<'a, T>) {
210217
new_child.detach();

src/html.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,9 +1622,10 @@ fn tagfilter(literal: &str) -> bool {
16221622
for t in TAGFILTER_BLACKLIST.iter() {
16231623
if lc.starts_with(t) {
16241624
let j = i + t.len();
1625-
return isspace(bytes[j])
1626-
|| bytes[j] == b'>'
1627-
|| (bytes[j] == b'/' && bytes.len() >= j + 2 && bytes[j + 1] == b'>');
1625+
let Some(&b) = bytes.get(j) else {
1626+
return false;
1627+
};
1628+
return isspace(b) || b == b'>' || (b == b'/' && bytes.get(j + 1) == Some(&b'>'));
16281629
}
16291630
}
16301631

src/nodes.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub enum NodeValue {
173173
Image(Box<NodeLink>),
174174

175175
/// **Inline**. A footnote reference.
176-
FootnoteReference(NodeFootnoteReference),
176+
FootnoteReference(Box<NodeFootnoteReference>),
177177

178178
#[cfg(feature = "shortcodes")]
179179
/// **Inline**. An Emoji character generated from a shortcode. Enable with feature "shortcodes".
@@ -459,6 +459,9 @@ pub struct NodeFootnoteReference {
459459
/// The name of the footnote.
460460
pub name: String,
461461

462+
/// The original text elements of the footnote, including their source position spans.
463+
pub texts: Vec<(String, usize)>,
464+
462465
/// The index of reference to the same footnote
463466
pub ref_num: u32,
464467

src/parser/inlines.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -994,11 +994,12 @@ impl<'a, 'r, 'o, 'd, 'c, 'p> Subject<'a, 'r, 'o, 'd, 'c, 'p> {
994994

995995
// Create the footnote reference node
996996
let ref_node = self.make_inline(
997-
NodeValue::FootnoteReference(NodeFootnoteReference {
997+
NodeValue::FootnoteReference(Box::new(NodeFootnoteReference {
998998
name: name.clone(),
999+
texts: vec![], // Unused.
9991000
ref_num: 0,
10001001
ix: 0,
1001-
}),
1002+
})),
10021003
startpos,
10031004
endpos,
10041005
);
@@ -1734,13 +1735,33 @@ impl<'a, 'r, 'o, 'd, 'c, 'p> Subject<'a, 'r, 'o, 'd, 'c, 'p> {
17341735
// do anything fancy here at all.
17351736
let mut sussy = false;
17361737

1738+
let mut texts = vec![];
1739+
17371740
for sibling in sibling_iterator {
1738-
match sibling.data().value {
1741+
let sibling_ast = sibling.data();
1742+
if sibling_ast.sourcepos.start.line != sibling_ast.sourcepos.end.line
1743+
|| sibling_ast.sourcepos.end.column < sibling_ast.sourcepos.start.column
1744+
{
1745+
sussy = true;
1746+
break;
1747+
}
1748+
1749+
match sibling_ast.value {
17391750
NodeValue::Text(ref literal) => {
17401751
text.push_str(literal);
1752+
texts.push((
1753+
literal.to_string(),
1754+
sibling_ast.sourcepos.end.column - sibling_ast.sourcepos.start.column
1755+
+ 1,
1756+
));
17411757
}
17421758
NodeValue::HtmlInline(ref literal) => {
17431759
text.push_str(literal);
1760+
texts.push((
1761+
literal.to_string(),
1762+
sibling_ast.sourcepos.end.column - sibling_ast.sourcepos.start.column
1763+
+ 1,
1764+
));
17441765
}
17451766
_ => {
17461767
sussy = true;
@@ -1751,11 +1772,12 @@ impl<'a, 'r, 'o, 'd, 'c, 'p> Subject<'a, 'r, 'o, 'd, 'c, 'p> {
17511772

17521773
if !sussy && text.len() > 1 {
17531774
let inl = self.make_inline(
1754-
NodeValue::FootnoteReference(NodeFootnoteReference {
1775+
NodeValue::FootnoteReference(Box::new(NodeFootnoteReference {
17551776
name: text[1..].to_string(),
1777+
texts,
17561778
ref_num: 0,
17571779
ix: 0,
1758-
}),
1780+
})),
17591781
// Overridden immediately below.
17601782
self.scanner.pos,
17611783
self.scanner.pos,
@@ -2341,7 +2363,7 @@ pub(crate) fn manual_scan_link_url_2(input: &str) -> Option<(&str, usize)> {
23412363
}
23422364
}
23432365

2344-
if i >= len || nb_p != 0 {
2366+
if len == 0 || nb_p != 0 {
23452367
None
23462368
} else {
23472369
Some((&input[..i], i))

0 commit comments

Comments
 (0)