mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 05:28:19 -05:00
fix: drop diagnostics with missing range at the language diagnostics boundary (fixes #323148) (#323153)
* fix: drop diagnostics with missing range at the language diagnostics boundary Other extensions can publish vscode.Diagnostic entries whose `range` is undefined (violating the non-nullable `range: Range` type via an `any` cast). These reach copilot verbatim through `vscode.languages.getDiagnostics()` and crash the many consumers that dereference `diagnostic.range` - notably the `LintErrors.getData` telemetry path that scans every extension's diagnostics via `getAllDiagnostics()`. Sanitize at the boundary service so every consumer is protected once, and log dropped entries so the producer stays diagnosable. Fixes microsoft/vscode#323148 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Copilot - Test lint — use strict equality for range null/undefined check The eqeqeq ESLint rule (configured as 'warn', enforced with --max-warnings=0) flagged `range != null` in _dropMalformedDiagnostics. Replace the loose equality with an explicit strict check that preserves the original semantics of dropping diagnostics whose range is either null or undefined. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: vs-code-engineering[bot] <122617954+vs-code-engineering[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
8cffe33c85
commit
fc9a595992
@@ -4,18 +4,46 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ILogService } from '../../log/common/logService';
|
||||
import { AbstractLanguageDiagnosticsService } from '../common/languageDiagnosticsService';
|
||||
|
||||
export class LanguageDiagnosticsServiceImpl extends AbstractLanguageDiagnosticsService {
|
||||
private static ignoredSchemes = new Set(['git', 'chat-editing-snapshot-text-model', 'chat-editing-text-model']);
|
||||
override onDidChangeDiagnostics: vscode.Event<vscode.DiagnosticChangeEvent> = vscode.languages.onDidChangeDiagnostics;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
override getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[] {
|
||||
return vscode.languages.getDiagnostics(resource);
|
||||
return this._dropMalformedDiagnostics(vscode.languages.getDiagnostics(resource));
|
||||
}
|
||||
|
||||
override getAllDiagnostics(): [vscode.Uri, vscode.Diagnostic[]][] {
|
||||
return vscode.languages.getDiagnostics()
|
||||
.filter(([uri]) => !LanguageDiagnosticsServiceImpl.ignoredSchemes.has(uri.scheme));
|
||||
.filter(([uri]) => !LanguageDiagnosticsServiceImpl.ignoredSchemes.has(uri.scheme))
|
||||
.map(([uri, diagnostics]): [vscode.Uri, vscode.Diagnostic[]] => [uri, this._dropMalformedDiagnostics(diagnostics)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostics are produced by arbitrary extensions and reach us verbatim through the
|
||||
* `vscode.languages.getDiagnostics` API. An extension can publish an entry that violates the
|
||||
* {@link vscode.Diagnostic} contract at runtime - most notably with a missing `range` assigned
|
||||
* through an `any` cast - and such an entry crashes the many consumers that dereference
|
||||
* `diagnostic.range`. Drop the malformed entries here, at the extension boundary, and surface
|
||||
* the occurrence so the underlying producer stays diagnosable.
|
||||
*/
|
||||
private _dropMalformedDiagnostics(diagnostics: vscode.Diagnostic[]): vscode.Diagnostic[] {
|
||||
const valid = diagnostics.filter(diagnostic => {
|
||||
const range: vscode.Range | null | undefined = diagnostic.range;
|
||||
return range !== null && range !== undefined;
|
||||
});
|
||||
const dropped = diagnostics.length - valid.length;
|
||||
if (dropped > 0) {
|
||||
this._logService.warn(`[LanguageDiagnosticsService] Ignored ${dropped} diagnostic(s) with a missing range received from the diagnostics API.`);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user