@@ -12,25 +12,23 @@ import { getJavaExtensionAPI, isJavaExtEnabled, ServerMode } from "./utility";
1212const ANALYZE_STACK_TRACE_COMMAND = "java.debug.analyzeStackTrace" ;
1313const NAVIGATE_TO_STACK_FRAME_COMMAND = "_java.debug.navigateToStackFrame" ;
1414
15- // Only linkify pasted traces in untitled (scratch) documents - including the one opened by the
16- // `Analyze Stack Trace` command. Kept deliberately narrow: a `.log` opened without a Java project
17- // couldn't resolve anyway, so we don't scan `.log` files or every plaintext file the user opens.
15+ // Linkify stack traces in scratch documents and .log files. Other plaintext documents stay
16+ // excluded so the extension does not passively scan unrelated files.
1817const STACK_TRACE_DOCUMENT_SELECTOR : DocumentSelector = [
1918 { scheme : "untitled" } ,
19+ { pattern : "**/*.log" } ,
2020] ;
2121
22- // Guard against pathological input: cap the length of a scanned line (mitigates ReDoS on the
23- // nested-quantifier regex) and the number of links produced for very large pasted traces .
22+ // Bound the work performed for large documents and pathological input. The per- line cap mitigates
23+ // ReDoS in the nested-quantifier regex; the document budgets keep large logs from being fully scanned .
2424const MAX_SCANNED_LINE_LENGTH = 1000 ;
25+ const MAX_SCANNED_LINES_PER_DOCUMENT = 10000 ;
26+ const MAX_SCANNED_CHARACTERS_PER_DOCUMENT = 1000000 ;
2527const MAX_LINKS_PER_DOCUMENT = 2000 ;
2628
2729// Only resolve to source locations the language server is expected to return.
2830const ALLOWED_SOURCE_SCHEMES = new Set < string > ( [ "file" , "jdt" ] ) ;
2931
30- // Bound both stack-trace detection and scratch-document prefill so a large clipboard cannot create
31- // an expensive untitled document (and keeps the detection regex input bounded).
32- const MAX_CLIPBOARD_PREFILL_LENGTH = 20000 ;
33-
3432interface IStackFrameLinkArgs {
3533 stackTrace : string ;
3634 methodName : string ;
@@ -66,12 +64,20 @@ function isStackFrameLinkArgs(args: unknown): args is IStackFrameLinkArgs {
6664export class JavaStackTraceLinkProvider implements DocumentLinkProvider {
6765 public provideDocumentLinks ( document : TextDocument , token : CancellationToken ) : ProviderResult < DocumentLink [ ] > {
6866 const links : DocumentLink [ ] = [ ] ;
69- for ( let i = 0 ; i < document . lineCount ; i ++ ) {
67+ let scannedCharacters = 0 ;
68+ const linesToScan = Math . min ( document . lineCount , MAX_SCANNED_LINES_PER_DOCUMENT ) ;
69+ for ( let i = 0 ; i < linesToScan ; i ++ ) {
7070 if ( token . isCancellationRequested || links . length >= MAX_LINKS_PER_DOCUMENT ) {
7171 break ;
7272 }
7373
7474 const lineText = document . lineAt ( i ) . text ;
75+ const lineScanCost = lineText . length + 1 ;
76+ if ( scannedCharacters + lineScanCost > MAX_SCANNED_CHARACTERS_PER_DOCUMENT ) {
77+ break ;
78+ }
79+ scannedCharacters += lineScanCost ;
80+
7581 if ( lineText . length > MAX_SCANNED_LINE_LENGTH ) {
7682 continue ;
7783 }
@@ -145,14 +151,13 @@ async function navigateToStackFrame(args: unknown): Promise<void> {
145151}
146152
147153/**
148- * Opens a scratch document prefilled with bounded clipboard content. The document link provider
149- * scans the content after the document opens and makes any stack frames clickable.
154+ * Opens a scratch document prefilled with the clipboard content. The document link provider scans
155+ * a bounded portion after the document opens and makes any stack frames clickable.
150156 */
151157async function analyzeStackTrace ( ) : Promise < void > {
152158 // The command itself is auto-instrumented via instrumentOperationAsVsCodeCommand, so no
153159 // manual telemetry is needed here to track invocations.
154- const clipboard = await env . clipboard . readText ( ) ;
155- const clipboardContent = clipboard . slice ( 0 , MAX_CLIPBOARD_PREFILL_LENGTH ) ;
160+ const clipboardContent = await env . clipboard . readText ( ) ;
156161 const document = await workspace . openTextDocument ( { language : "log" , content : clipboardContent } ) ;
157162 await window . showTextDocument ( document ) ;
158163}
0 commit comments