Skip to content

Commit 9ab9703

Browse files
authored
Fix panic in Python 3.12 line number handling (#736)
The read_varint function would panic when trying to read past the end of the line table. This fix adds bounds checking and returns Option<usize> to handle this case gracefully. Fixes #735
1 parent bdd1cd4 commit 9ab9703

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

src/python_interpreters.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,28 +248,34 @@ macro_rules! PythonCodeObjectImpl {
248248
};
249249
}
250250

251-
fn read_varint(index: &mut usize, table: &[u8]) -> usize {
251+
fn read_varint(index: &mut usize, table: &[u8]) -> Option<usize> {
252+
if *index >= table.len() {
253+
return None;
254+
}
252255
let mut ret: usize;
253256
let mut byte = table[*index];
254257
let mut shift = 0;
255258
*index += 1;
256259
ret = (byte & 63) as usize;
257260

258261
while byte & 64 != 0 {
262+
if *index >= table.len() {
263+
return None;
264+
}
259265
byte = table[*index];
260266
*index += 1;
261267
shift += 6;
262268
ret += ((byte & 63) as usize) << shift;
263269
}
264-
ret
270+
Some(ret)
265271
}
266272

267-
fn read_signed_varint(index: &mut usize, table: &[u8]) -> isize {
268-
let unsigned_val = read_varint(index, table);
273+
fn read_signed_varint(index: &mut usize, table: &[u8]) -> Option<isize> {
274+
let unsigned_val = read_varint(index, table)?;
269275
if unsigned_val & 1 != 0 {
270-
-((unsigned_val >> 1) as isize)
276+
Some(-((unsigned_val >> 1) as isize))
271277
} else {
272-
(unsigned_val >> 1) as isize
278+
Some((unsigned_val >> 1) as isize)
273279
}
274280
}
275281

@@ -324,13 +330,13 @@ macro_rules! CompactCodeObjectImpl {
324330
let line_delta = match code {
325331
15 => 0,
326332
14 => {
327-
let delta = read_signed_varint(&mut index, table);
333+
let delta = read_signed_varint(&mut index, table).unwrap_or(0);
328334
read_varint(&mut index, table); // end line
329335
read_varint(&mut index, table); // start column
330336
read_varint(&mut index, table); // end column
331337
delta
332338
}
333-
13 => read_signed_varint(&mut index, table),
339+
13 => read_signed_varint(&mut index, table).unwrap_or(0),
334340
10..=12 => {
335341
index += 2; // start column / end column
336342
(code - 10).into()

0 commit comments

Comments
 (0)