@@ -6,6 +6,13 @@ use syntect::{
6
6
util:: LinesWithEndings ,
7
7
} ;
8
8
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
+
9
16
static SYNTAXES : Lazy < SyntaxSet > = Lazy :: new ( || {
10
17
static SYNTAX_DATA : & [ u8 ] = include_bytes ! ( concat!( env!( "OUT_DIR" ) , "/syntect.packdump" ) ) ;
11
18
@@ -22,13 +29,20 @@ static SYNTAXES: Lazy<SyntaxSet> = Lazy::new(|| {
22
29
} ) ;
23
30
24
31
fn try_with_syntax ( syntax : & SyntaxReference , code : & str ) -> Result < String > {
32
+ if code. len ( ) > CODE_SIZE_LIMIT {
33
+ return Err ( LimitsExceeded . into ( ) ) ;
34
+ }
35
+
25
36
let mut html_generator = ClassedHTMLGenerator :: new_with_class_style (
26
37
syntax,
27
38
& SYNTAXES ,
28
39
ClassStyle :: SpacedPrefixed { prefix : "syntax-" } ,
29
40
) ;
30
41
31
42
for line in LinesWithEndings :: from ( code) {
43
+ if line. len ( ) > LINE_SIZE_LIMIT {
44
+ return Err ( LimitsExceeded . into ( ) ) ;
45
+ }
32
46
html_generator. parse_html_for_line_which_includes_newline ( line) ?;
33
47
}
34
48
@@ -54,15 +68,19 @@ pub fn with_lang(lang: Option<&str>, code: &str) -> String {
54
68
match try_with_lang ( lang, code) {
55
69
Ok ( highlighted) => highlighted,
56
70
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
+ }
58
76
code. to_owned ( )
59
77
}
60
78
}
61
79
}
62
80
63
81
#[ cfg( test) ]
64
82
mod tests {
65
- use super :: select_syntax;
83
+ use super :: { select_syntax, try_with_lang , LimitsExceeded , CODE_SIZE_LIMIT , LINE_SIZE_LIMIT } ;
66
84
67
85
#[ test]
68
86
fn custom_filetypes ( ) {
@@ -78,4 +96,15 @@ mod tests {
78
96
79
97
assert_eq ! ( select_syntax( Some ( ".rustfmt.toml" ) , "" ) . name, toml. name) ;
80
98
}
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
+ }
81
110
}
0 commit comments