mirror of
https://github.com/openai/codex.git
synced 2026-11-04 08:25:29 +00:00
Skip syntax highlighting for lines over 4 KiB (#34796)
## Why Very long individual lines can make syntax highlighting consume excessive CPU or memory even when the overall input remains below the existing size and line-count limits. ## What changed - Fall back to plain, unstyled text when any input line exceeds 4 KiB. - Keep the existing 512 KiB total-size and 10,000-line guardrails. ## Testing - Cover highlighting fallback and text preservation for a long single-line Bash command. - Snapshot rendering of a command that exceeds the per-line limit. GitOrigin-RevId: ba02997331a294d8a32ca89ee06acb12dd3bbd83
This commit is contained in:
1 parent
2c49493b5b
commit
5381edb133
3 files changed
+59
-4
No files matched your search
@@ -18,9 +18,10 @@
|
||||
//! swap/snapshot the theme for live preview. All highlighting functions read
|
||||
//! the theme via `theme_lock()`.
|
||||
//!
|
||||
//! **Guardrails:** inputs exceeding 512 KB or 10 000 lines are rejected early
|
||||
//! (returns `None`) to prevent pathological CPU/memory usage. Callers must
|
||||
//! fall back to plain unstyled text.
|
||||
//! **Guardrails:** inputs exceeding 512 KB or 10 000 lines, or containing an
|
||||
//! individual line longer than 4 KiB, are rejected early (returns `None`) to
|
||||
//! prevent pathological CPU/memory usage. Callers must fall back to plain
|
||||
//! unstyled text.
|
||||
|
||||
use ratatui::style::Color as RtColor;
|
||||
use ratatui::style::Modifier;
|
||||
@@ -581,6 +582,9 @@ const MAX_HIGHLIGHT_BYTES: usize = 512 * 1024;
|
||||
/// Skip highlighting for inputs with more than 10,000 lines.
|
||||
const MAX_HIGHLIGHT_LINES: usize = 10_000;
|
||||
|
||||
/// Skip highlighting when an individual line is longer than 4 KiB.
|
||||
pub(crate) const MAX_HIGHLIGHT_LINE_BYTES: usize = 4 * 1024;
|
||||
|
||||
/// Check whether an input exceeds the safe highlighting limits.
|
||||
///
|
||||
/// Callers that highlight content in a loop (e.g. per diff-line) should
|
||||
@@ -611,7 +615,12 @@ fn highlight_to_line_spans_with_theme(
|
||||
// Bail out early for oversized inputs to avoid excessive resource usage.
|
||||
// Count actual lines (not newline bytes) to avoid an off-by-one when
|
||||
// the input does not end with a newline.
|
||||
if code.len() > MAX_HIGHLIGHT_BYTES || code.lines().count() > MAX_HIGHLIGHT_LINES {
|
||||
if code.len() > MAX_HIGHLIGHT_BYTES
|
||||
|| code.lines().count() > MAX_HIGHLIGHT_LINES
|
||||
|| code
|
||||
.lines()
|
||||
.any(|line| line.len() > MAX_HIGHLIGHT_LINE_BYTES)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -1139,6 +1148,18 @@ mod tests {
|
||||
assert!(result.is_none(), "oversized input should fall back to None");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_single_line_bash_skips_highlighting_and_preserves_text() {
|
||||
let token = "eHh4".repeat(MAX_HIGHLIGHT_LINE_BYTES / 4 + 1);
|
||||
let code = format!("printf %s {token} | base64 -d >/dev/null");
|
||||
|
||||
assert!(highlight_code_to_styled_spans(&code, "bash").is_none());
|
||||
assert_eq!(
|
||||
highlight_code_to_lines(&code, "bash"),
|
||||
vec![Line::from(code)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn highlight_many_lines_falls_back() {
|
||||
// Input exceeding MAX_HIGHLIGHT_LINES should return None.
|
||||
|
||||
Reference in new issue
Block a user