From eecf87bfc77f58919ff5b8e4ff33c25dddcb71ce Mon Sep 17 00:00:00 2001 From: Hana Date: Thu, 19 Sep 2024 15:36:47 +0800 Subject: [PATCH] test: add --- crates/node_binding/src/diagnostic.rs | 26 ++++++++++++++----- .../loader-emit-diagnostic/stats.err | 13 ++++++++++ .../with-multiple-line.js | 16 ++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/crates/node_binding/src/diagnostic.rs b/crates/node_binding/src/diagnostic.rs index 3112d77550b..a5be31b6834 100644 --- a/crates/node_binding/src/diagnostic.rs +++ b/crates/node_binding/src/diagnostic.rs @@ -1,4 +1,4 @@ -use napi::bindgen_prelude::External; +use napi::bindgen_prelude::*; use rspack_error::{ miette::{self, LabeledSpan, MietteDiagnostic, Severity}, Diagnostic, @@ -32,7 +32,7 @@ pub struct JsDiagnostic { } #[napi(ts_return_type = "ExternalObject<'Diagnostic'>")] -pub fn format_diagnostic(diagnostic: JsDiagnostic) -> External { +pub fn format_diagnostic(diagnostic: JsDiagnostic) -> Result> { let JsDiagnostic { message, help, @@ -59,14 +59,26 @@ pub fn format_diagnostic(diagnostic: JsDiagnostic) -> External { location.column as usize, location.length as usize, ); - if let Some((offset, length)) = try_line_column_length_to_offset_length( + let (offset, length) = try_line_column_length_to_offset_length( &rope, location.line as usize, location.column as usize, location.length as usize, - ) { - d = d.with_label(LabeledSpan::new(location.text, offset, length)); + ) + .ok_or_else(|| { + Error::new( + Status::Unknown, + "Format diagnostic failed: Invalid location. Did you pass the correct line, column and length?", + ) + })?; + let end_byte = offset.saturating_add(length); + if end_byte > rope.len_bytes() { + return Err(Error::new( + Status::Unknown, + "Format diagnostic failed: Invalid `length` in location.", + )); } + d = d.with_label(LabeledSpan::new(location.text, offset, length)); } } @@ -74,10 +86,10 @@ pub fn format_diagnostic(diagnostic: JsDiagnostic) -> External { if let Some(source_code) = source_code { error = error.with_source_code(source_code); } - External::new( + Ok(External::new( Diagnostic::from(error) .with_file(file.map(Into::into)) .with_loc(loc.map(|l| l.to_string())) .with_module_identifier(module_identifier.map(Into::into)), - ) + )) } diff --git a/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/stats.err b/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/stats.err index 550f3e46e05..28ad133fcf0 100644 --- a/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/stats.err +++ b/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/stats.err @@ -56,6 +56,19 @@ ERROR in (./with-multiple-line.js!) 1:0-2:4 · ╰──── unexpected '~' ╰──── +ERROR in (./with-multiple-line.js!) + × Module build failed: + ╰─▶ × Error: Format diagnostic failed: Invalid `length` in location. + │ at xxx + │ at xxx + │ at xxx + │ at xxx + │ at xxx + │ at xxx + │ at xxx + │ at xxx + │ + ERROR in (./with-multiple-line.js!) 3:4 × ModuleError: Multiple line snippet ╭─[3:4] diff --git a/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/with-multiple-line.js b/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/with-multiple-line.js index 97044707e7f..6d922ccd920 100644 --- a/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/with-multiple-line.js +++ b/packages/rspack-test-tools/tests/diagnosticsCases/module-build-failed/loader-emit-diagnostic/with-multiple-line.js @@ -38,5 +38,21 @@ module.exports = function() { length: 0, }, }); + // Length overflow + this.experiments.emitDiagnostic({ + message: "Multiple line snippet", + severity: "error", + sourceCode: `~~~~~ +~~~~~ +~~~~~ +~~~~~ +~~~~~`, + location: { + text: "unexpected '~'", + line: 3, + column: 4, + length: 100, + }, + }); return "" }