Skip to content

Commit 050d981

Browse files
authored
fix: Correctly interpret missing line/column numbers (#129)
This correctly interprets sourcemap tokens that only have a minified column number as "unmapped". Previously, such tokens would inherit the source line and column numbers from the last valid token, but that is incorrect. Now we set the numbers to u32::MAX for such cases.
1 parent 229c1a4 commit 050d981

File tree

2 files changed

+45
-25
lines changed

2 files changed

+45
-25
lines changed

src/decoder.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,13 @@ fn decode_rmi(rmi_str: &str, val: &mut BitVec<u8, Lsb0>) -> Result<()> {
148148

149149
pub fn decode_regular(rsm: RawSourceMap) -> Result<SourceMap> {
150150
let mut dst_col;
151-
let mut src_id = 0;
152-
let mut src_line = 0;
153-
let mut src_col = 0;
154-
let mut name_id = 0;
151+
152+
// Source IDs, lines, columns, and names are "running" values.
153+
// Each token (except the first) contains the delta from the previous value.
154+
let mut running_src_id = 0;
155+
let mut running_src_line = 0;
156+
let mut running_src_col = 0;
157+
let mut running_name_id = 0;
155158

156159
let names = rsm.names.unwrap_or_default();
157160
let sources = rsm.sources.unwrap_or_default();
@@ -183,30 +186,41 @@ pub fn decode_regular(rsm: RawSourceMap) -> Result<SourceMap> {
183186

184187
nums.clear();
185188
parse_vlq_segment_into(segment, &mut nums)?;
189+
match nums.len() {
190+
1 | 4 | 5 => {}
191+
_ => return Err(Error::BadSegmentSize(nums.len() as u32)),
192+
}
193+
186194
dst_col = (i64::from(dst_col) + nums[0]) as u32;
187195

188-
let mut src = !0;
189-
let mut name = !0;
196+
// The source file , source line, source column, and name
197+
// may not be present in the current token. We use `u32::MAX`
198+
// as the placeholder for missing values.
199+
let mut current_src_id = !0;
200+
let mut current_src_line = !0;
201+
let mut current_src_col = !0;
202+
let mut current_name_id = !0;
190203

191204
if nums.len() > 1 {
192-
if nums.len() != 4 && nums.len() != 5 {
193-
return Err(Error::BadSegmentSize(nums.len() as u32));
194-
}
195-
src_id = (i64::from(src_id) + nums[1]) as u32;
196-
if src_id >= sources.len() as u32 {
197-
return Err(Error::BadSourceReference(src_id));
205+
running_src_id = (i64::from(running_src_id) + nums[1]) as u32;
206+
207+
if running_src_id >= sources.len() as u32 {
208+
return Err(Error::BadSourceReference(running_src_id));
198209
}
199210

200-
src = src_id;
201-
src_line = (i64::from(src_line) + nums[2]) as u32;
202-
src_col = (i64::from(src_col) + nums[3]) as u32;
211+
running_src_line = (i64::from(running_src_line) + nums[2]) as u32;
212+
running_src_col = (i64::from(running_src_col) + nums[3]) as u32;
213+
214+
current_src_id = running_src_id;
215+
current_src_line = running_src_line;
216+
current_src_col = running_src_col;
203217

204218
if nums.len() > 4 {
205-
name_id = (i64::from(name_id) + nums[4]) as u32;
206-
if name_id >= names.len() as u32 {
207-
return Err(Error::BadNameReference(name_id));
219+
running_name_id = (i64::from(running_name_id) + nums[4]) as u32;
220+
if running_name_id >= names.len() as u32 {
221+
return Err(Error::BadNameReference(running_name_id));
208222
}
209-
name = name_id;
223+
current_name_id = running_name_id;
210224
}
211225
}
212226

@@ -215,10 +229,10 @@ pub fn decode_regular(rsm: RawSourceMap) -> Result<SourceMap> {
215229
tokens.push(RawToken {
216230
dst_line: dst_line as u32,
217231
dst_col,
218-
src_line,
219-
src_col,
220-
src_id: src,
221-
name_id: name,
232+
src_line: current_src_line,
233+
src_col: current_src_col,
234+
src_id: current_src_id,
235+
name_id: current_name_id,
222236
is_range,
223237
});
224238
}

src/types.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,18 @@ impl<'a> Token<'a> {
242242
(self.get_dst_line(), self.get_dst_col())
243243
}
244244

245-
/// get the source line number
245+
/// Get the source line number.
246+
///
247+
/// `u32::MAX` is a sentinel value meaning
248+
/// this token is unmapped.
246249
pub fn get_src_line(&self) -> u32 {
247250
self.raw.src_line
248251
}
249252

250-
/// get the source column number
253+
/// Get the source column number.
254+
///
255+
/// `u32::MAX` is a sentinel value meaning
256+
/// this token is unmapped.
251257
pub fn get_src_col(&self) -> u32 {
252258
self.raw.src_col.saturating_add(self.offset)
253259
}

0 commit comments

Comments
 (0)