Skip to content

Commit b42137d

Browse files
committed
Add a code and line length limit on highlighting
1 parent eb80347 commit b42137d

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

src/web/highlight.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ use syntect::{
66
util::LinesWithEndings,
77
};
88

9+
const CODE_SIZE_LIMIT: usize = 2 * 1024 * 1024;
10+
const LINE_SIZE_LIMIT: usize = 512;
11+
12+
#[derive(Debug, thiserror::Error)]
13+
#[error("the code exceeded a highlighting limit")]
14+
pub struct LimitsExceeded;
15+
916
static SYNTAXES: Lazy<SyntaxSet> = Lazy::new(|| {
1017
static SYNTAX_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/syntect.packdump"));
1118

@@ -22,13 +29,20 @@ static SYNTAXES: Lazy<SyntaxSet> = Lazy::new(|| {
2229
});
2330

2431
fn try_with_syntax(syntax: &SyntaxReference, code: &str) -> Result<String> {
32+
if code.len() > CODE_SIZE_LIMIT {
33+
return Err(LimitsExceeded.into());
34+
}
35+
2536
let mut html_generator = ClassedHTMLGenerator::new_with_class_style(
2637
syntax,
2738
&SYNTAXES,
2839
ClassStyle::SpacedPrefixed { prefix: "syntax-" },
2940
);
3041

3142
for line in LinesWithEndings::from(code) {
43+
if line.len() > LINE_SIZE_LIMIT {
44+
return Err(LimitsExceeded.into());
45+
}
3246
html_generator.parse_html_for_line_which_includes_newline(line)?;
3347
}
3448

@@ -54,15 +68,19 @@ pub fn with_lang(lang: Option<&str>, code: &str) -> String {
5468
match try_with_lang(lang, code) {
5569
Ok(highlighted) => highlighted,
5670
Err(err) => {
57-
log::error!("failed while highlighting code: {err:?}");
71+
if err.is::<LimitsExceeded>() {
72+
log::debug!("hit limit while highlighting code");
73+
} else {
74+
log::error!("failed while highlighting code: {err:?}");
75+
}
5876
code.to_owned()
5977
}
6078
}
6179
}
6280

6381
#[cfg(test)]
6482
mod tests {
65-
use super::select_syntax;
83+
use super::{select_syntax, try_with_lang, LimitsExceeded, CODE_SIZE_LIMIT, LINE_SIZE_LIMIT};
6684

6785
#[test]
6886
fn custom_filetypes() {
@@ -78,4 +96,15 @@ mod tests {
7896

7997
assert_eq!(select_syntax(Some(".rustfmt.toml"), "").name, toml.name);
8098
}
99+
100+
#[test]
101+
fn limits() {
102+
let is_limited = |s: String| {
103+
try_with_lang(Some("toml"), &s)
104+
.unwrap_err()
105+
.is::<LimitsExceeded>()
106+
};
107+
assert!(is_limited("a\n".repeat(CODE_SIZE_LIMIT)));
108+
assert!(is_limited("aa".repeat(LINE_SIZE_LIMIT)));
109+
}
81110
}

0 commit comments

Comments
 (0)