Skip to content

Commit a6de117

Browse files
committed
Remove possible overflow during conversion
1 parent 5a1dc27 commit a6de117

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

src/aml/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,4 +3386,7 @@ pub enum AmlError {
33863386
/// This variant is set by the host, not by the library, and can be used when it is convenient
33873387
/// not to construct a more complex error type around [`AmlError`].
33883388
HostError(String),
3389+
3390+
/// An integer operation was attempted for an integer greater than 8 bytes long.
3391+
InvalidIntegerSize(usize),
33893392
}

src/aml/object.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ impl Object {
208208
///
209209
/// To avoid the cast, use [`Object::as_integer`] instead.
210210
pub fn to_integer(&self, allowed_bytes: usize) -> Result<u64, AmlError> {
211+
// This check shouldn't hit, but it protects the `to_interpret` buffer below from panicking.
212+
if allowed_bytes > size_of::<u64>() {
213+
return Err(AmlError::InvalidIntegerSize(allowed_bytes));
214+
}
215+
211216
match self {
212217
Object::Integer(value) => Ok(*value),
213218
Object::Buffer(bytes) => {
@@ -243,7 +248,11 @@ impl Object {
243248
Object::BufferField { .. } => {
244249
let mut buffer = [0u8; 8];
245250
self.read_buffer_field(&mut buffer)?;
246-
Ok(u64::from_le_bytes(buffer) % (1 << (allowed_bytes as u64 * 8)))
251+
let mut result = u64::from_le_bytes(buffer);
252+
if allowed_bytes < 8 {
253+
result &= (1 << (allowed_bytes as u64 * 8)) - 1;
254+
}
255+
Ok(result)
247256
}
248257
_ => Err(AmlError::InvalidOperationOnObject { op: Operation::ToInteger, typ: self.typ() })?,
249258
}
@@ -578,4 +587,17 @@ mod tests {
578587

579588
assert_eq!(buffer_field.to_integer(4).unwrap(), 0);
580589
}
590+
591+
#[test]
592+
fn buffer_field_to_8_byte_integer() {
593+
const BUFFER: [u8; 6] = [0x0f, 0x00, 0x00, 0x00, 0xf0, 0xff];
594+
let buffer = Object::Buffer(Vec::from(BUFFER)).wrap();
595+
let buffer_field = Object::BufferField {
596+
buffer,
597+
offset: 4,
598+
length: 36,
599+
};
600+
601+
assert_eq!(buffer_field.to_integer(8).unwrap(), 0x0000000f_00000000);
602+
}
581603
}

0 commit comments

Comments
 (0)