mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 22:29:17 +00:00
fix(linter): clamp invalid JS plugin locations (#26144)
Follow-up to #26138, closes #25867. External plugins can report a node range past the source text. The default formatter rejects that invalid span and previously panicked. Clamp external diagnostic offsets to the source's UTF-16 length before normalizing reversed ranges. The end-to-end fixture now covers: - reversed locations - negative loc values - negative node ranges - an out-of-range node range in Unicode source text
This commit is contained in:
1 parent
c3dedc9b0c
commit
e412cf2ce3
11 files changed
+252
-177
No files matched your search
+10
-10
@@ -8,16 +8,6 @@
|
||||
| Error: `after` hook threw
|
||||
| at after (<fixture>/plugin.ts:108:15)
|
||||
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/throwInBefore/1.js
|
||||
| Error: `before` hook threw
|
||||
| at before (<fixture>/plugin.ts:82:15)
|
||||
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/throwInVisit/1.js
|
||||
| Error: `Identifier` visit function threw
|
||||
| at Identifier (<fixture>/plugin.ts:124:15)
|
||||
|
||||
x create-once-errors-plugin(before-and-after-late): after hook:
|
||||
| id: create-once-errors-plugin/before-and-after-late
|
||||
| filename: <fixture>/files/throwInAfter/2.js
|
||||
@@ -44,6 +34,11 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/throwInBefore/1.js
|
||||
| Error: `before` hook threw
|
||||
| at before (<fixture>/plugin.ts:82:15)
|
||||
|
||||
x create-once-errors-plugin(before-and-after-late): after hook:
|
||||
| id: create-once-errors-plugin/before-and-after-late
|
||||
| filename: <fixture>/files/throwInBefore/2.js
|
||||
@@ -64,6 +59,11 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/throwInVisit/1.js
|
||||
| Error: `Identifier` visit function threw
|
||||
| at Identifier (<fixture>/plugin.ts:124:15)
|
||||
|
||||
x create-once-errors-plugin(before-and-after-late): after hook:
|
||||
| id: create-once-errors-plugin/before-and-after-late
|
||||
| filename: <fixture>/files/throwInVisit/2.js
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
debugger;
|
||||
@@ -0,0 +1 @@
|
||||
debugger;
|
||||
@@ -0,0 +1,2 @@
|
||||
/* 😀 */
|
||||
debugger;
|
||||
+17
-2
@@ -39,8 +39,23 @@
|
||||
: ^^^^^^
|
||||
`----
|
||||
|
||||
Found 0 warnings and 5 errors.
|
||||
Finished in Xms on 1 file with 1 rules using X threads.
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/negative-loc.js
|
||||
| RangeError: Line/column pair translates to an out of range offset
|
||||
| at Program (<fixture>/plugin.ts:14:23)
|
||||
|
||||
x Error running JS plugin.
|
||||
| File path: <fixture>/files/negative-node.js
|
||||
| TypeError: `node.range[0]` and `node.range[1]` must be non-negative integers
|
||||
| at Program (<fixture>/plugin.ts:22:23)
|
||||
|
||||
x loc-plugin(no-bugger): Out-of-range node
|
||||
,-[files/out-of-range-node.js:3:1]
|
||||
2 | debugger;
|
||||
`----
|
||||
|
||||
Found 0 warnings and 8 errors.
|
||||
Finished in Xms on 4 files with 1 rules using X threads.
|
||||
```
|
||||
|
||||
# stderr
|
||||
|
||||
@@ -10,6 +10,30 @@ const plugin: Plugin = {
|
||||
let debuggerCount = 0;
|
||||
return {
|
||||
Program(_node) {
|
||||
if (context.filename.endsWith("negative-loc.js")) {
|
||||
context.report({
|
||||
message: "Negative location",
|
||||
loc: { start: { line: 1, column: -1 } },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.filename.endsWith("negative-node.js")) {
|
||||
context.report({
|
||||
message: "Negative node",
|
||||
node: { range: [-1, 0] } as never,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.filename.endsWith("out-of-range-node.js")) {
|
||||
context.report({
|
||||
message: "Out-of-range node",
|
||||
node: { range: [999, 1000] } as never,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({
|
||||
message: "Misaligned location",
|
||||
loc: {
|
||||
@@ -26,6 +50,8 @@ const plugin: Plugin = {
|
||||
});
|
||||
},
|
||||
DebuggerStatement(_node) {
|
||||
if (context.filename.endsWith("out-of-range-node.js")) return;
|
||||
|
||||
debuggerCount++;
|
||||
context.report({
|
||||
message: "Bugger!",
|
||||
|
||||
+48
-48
@@ -3,54 +3,6 @@
|
||||
|
||||
# stdout
|
||||
```
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): Replace "a" with "daddy"
|
||||
,-[files/bom_remove.js:1:4]
|
||||
1 | a = c;
|
||||
@@ -65,6 +17,14 @@
|
||||
2 | d = b
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): end negative
|
||||
,-[files/range_end_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -77,6 +37,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x fixes-plugin(fixes): end out of bounds
|
||||
,-[files/range_end_out_of_bounds.js:1:5]
|
||||
1 | let x;
|
||||
@@ -89,6 +57,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): end too large
|
||||
,-[files/range_end_too_large.js:1:5]
|
||||
1 | let x;
|
||||
@@ -101,6 +77,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x fixes-plugin(fixes): start after end
|
||||
,-[files/range_start_after_end.js:1:5]
|
||||
1 | let x;
|
||||
@@ -113,6 +97,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): start negative
|
||||
,-[files/range_start_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -125,6 +117,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): start too large
|
||||
,-[files/range_start_too_large.js:1:5]
|
||||
1 | let x;
|
||||
|
||||
+48
-48
@@ -3,54 +3,6 @@
|
||||
|
||||
# stdout
|
||||
```
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): Replace "a" with "daddy"
|
||||
,-[files/bom.js:1:4]
|
||||
1 | a = c;
|
||||
@@ -269,6 +221,14 @@
|
||||
: ^^^^^^^^^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): end negative
|
||||
,-[files/range_end_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -281,6 +241,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x fixes-plugin(fixes): end out of bounds
|
||||
,-[files/range_end_out_of_bounds.js:1:5]
|
||||
1 | let x;
|
||||
@@ -293,6 +261,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): end too large
|
||||
,-[files/range_end_too_large.js:1:5]
|
||||
1 | let x;
|
||||
@@ -305,6 +281,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x fixes-plugin(fixes): start after end
|
||||
,-[files/range_start_after_end.js:1:5]
|
||||
1 | let x;
|
||||
@@ -317,6 +301,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): start negative
|
||||
,-[files/range_start_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -329,6 +321,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `fixes-plugin/fixes` returned invalid fixes.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x fixes-plugin(fixes): start too large
|
||||
,-[files/range_start_too_large.js:1:5]
|
||||
1 | let x;
|
||||
|
||||
+48
-48
@@ -3,54 +3,6 @@
|
||||
|
||||
# stdout
|
||||
```
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x suggestions-plugin(suggestions): Replace "a" with "daddy"
|
||||
,-[files/bom_remove.js:1:4]
|
||||
1 | a = c;
|
||||
@@ -65,6 +17,14 @@
|
||||
2 | d = b
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x suggestions-plugin(suggestions): end negative
|
||||
,-[files/range_end_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -77,6 +37,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_out_of_bounds.js
|
||||
| Invalid range: 7..7
|
||||
|
||||
x suggestions-plugin(suggestions): end out of bounds
|
||||
,-[files/range_end_out_of_bounds.js:1:5]
|
||||
1 | let x;
|
||||
@@ -89,6 +57,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_end_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x suggestions-plugin(suggestions): end too large
|
||||
,-[files/range_end_too_large.js:1:5]
|
||||
1 | let x;
|
||||
@@ -101,6 +77,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_after_end.js
|
||||
| Negative range is invalid: Span { start: 3, end: 2 }
|
||||
|
||||
x suggestions-plugin(suggestions): start after end
|
||||
,-[files/range_start_after_end.js:1:5]
|
||||
1 | let x;
|
||||
@@ -113,6 +97,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_negative.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x suggestions-plugin(suggestions): start negative
|
||||
,-[files/range_start_negative.js:1:5]
|
||||
1 | let x;
|
||||
@@ -125,6 +117,14 @@
|
||||
: ^
|
||||
`----
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x Plugin `suggestions-plugin/suggestions` returned invalid suggestions.
|
||||
| File path: <fixture>/files/range_start_too_large.js
|
||||
| Invalid range: 0..0
|
||||
|
||||
x suggestions-plugin(suggestions): start too large
|
||||
,-[files/range_start_too_large.js:1:5]
|
||||
1 | let x;
|
||||
|
||||
@@ -173,29 +173,46 @@ impl Info {
|
||||
let mut severity = Severity::Warning;
|
||||
let rule_id = diagnostic.code().map(|code| code.to_string());
|
||||
|
||||
if let Some(source) = diagnostic.source_code()
|
||||
&& let Some(label) = diagnostic.labels().first()
|
||||
&& let Ok(start_offset) = usize::try_from(label.offset())
|
||||
&& let Some(end_offset) = label.offset().checked_add(label.len())
|
||||
&& let Ok(end_offset) = usize::try_from(end_offset)
|
||||
&& source.data().get(start_offset..end_offset).is_some()
|
||||
&& let Some(start_position) = line_column(source.data(), start_offset)
|
||||
{
|
||||
start = start_position;
|
||||
if let Some(end_position) = line_column(source.data(), end_offset) {
|
||||
end = end_position;
|
||||
}
|
||||
|
||||
if let Some(source) = diagnostic.source_code() {
|
||||
if let Some(name) = source.name() {
|
||||
filename = name.to_string();
|
||||
}
|
||||
if matches!(diagnostic.severity(), Some(Severity::Error)) {
|
||||
severity = Severity::Error;
|
||||
}
|
||||
|
||||
message = diagnostic.to_string();
|
||||
if let Some(label) = diagnostic.labels().first()
|
||||
&& let Ok(start_offset) = usize::try_from(label.offset())
|
||||
&& let Some(end_offset) = label.offset().checked_add(label.len())
|
||||
&& let Ok(end_offset) = usize::try_from(end_offset)
|
||||
&& source.data().get(start_offset..end_offset).is_some()
|
||||
&& let Some(start_position) = line_column(source.data(), start_offset)
|
||||
{
|
||||
start = start_position;
|
||||
if let Some(end_position) = line_column(source.data(), end_offset) {
|
||||
end = end_position;
|
||||
}
|
||||
|
||||
if matches!(diagnostic.severity(), Some(Severity::Error)) {
|
||||
severity = Severity::Error;
|
||||
}
|
||||
|
||||
message = diagnostic.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
Self { start, end, filename, message, severity, rule_id }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{Error, NamedSource, OxcDiagnostic};
|
||||
|
||||
use super::Info;
|
||||
|
||||
#[test]
|
||||
fn includes_source_name_for_unlabelled_diagnostic() {
|
||||
let error: Error = OxcDiagnostic::error("Something went wrong")
|
||||
.with_source_code(NamedSource::new("file.js", ""));
|
||||
|
||||
assert_eq!(Info::new(&error).filename, "file.js");
|
||||
}
|
||||
}
|
||||
@@ -741,6 +741,10 @@ impl Linter {
|
||||
program.source_text = source_text;
|
||||
}
|
||||
|
||||
#[expect(clippy::cast_possible_truncation)]
|
||||
let source_text_utf8_end =
|
||||
source_text.len() as u32 + if has_bom { BOM_LEN as u32 } else { trim_leading };
|
||||
|
||||
// Create span converter.
|
||||
// If source starts with BOM, create converter which ignores the BOM.
|
||||
let span_converter = if has_bom {
|
||||
@@ -752,6 +756,12 @@ impl Linter {
|
||||
Utf8ToUtf16::new(source_text)
|
||||
};
|
||||
|
||||
// Convert the end of the (trimmed) source text to the UTF-16 offsets used by JS plugins.
|
||||
let mut source_text_utf16_len = source_text_utf8_end;
|
||||
if let Some(mut converter) = span_converter.converter() {
|
||||
converter.convert_offset(&mut source_text_utf16_len);
|
||||
}
|
||||
|
||||
// Convert token spans to UTF-16 and update token kinds
|
||||
#[expect(clippy::if_not_else, clippy::cast_possible_truncation)]
|
||||
let (tokens_offset, tokens_len) = if !tokens.is_empty() {
|
||||
@@ -848,12 +858,15 @@ impl Linter {
|
||||
Ok(diagnostics) => {
|
||||
for diagnostic in diagnostics {
|
||||
// Convert UTF-16 offsets back to UTF-8.
|
||||
// ESLint permits a reported location to end before it starts. Represent those
|
||||
// as an empty span at the reported start, preserving its displayed position.
|
||||
// External plugins may report locations outside the source text, or which end
|
||||
// before they start. Clamp them to the end of the source, and represent
|
||||
// reversed locations as empty spans at their stated start.
|
||||
//
|
||||
// Also make sure offsets do not fall in middle of a multi-byte UTF-8 character.
|
||||
// That's possible if UTF-16 offset points to middle of a surrogate pair.
|
||||
let mut span =
|
||||
Span::new(diagnostic.start, diagnostic.end.max(diagnostic.start));
|
||||
let start = diagnostic.start.min(source_text_utf16_len);
|
||||
let end = diagnostic.end.min(source_text_utf16_len).max(start);
|
||||
let mut span = Span::new(start, end);
|
||||
span_converter.convert_span_back(&mut span);
|
||||
|
||||
let (external_rule_id, _options_id, severity) =
|
||||
|
||||
Reference in new issue
Block a user