diff --git a/src/dir.rs b/src/dir.rs index 87eef2b..0fc343b 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -1,6 +1,6 @@ #[cfg(feature = "alloc")] use core::{slice, iter}; -use core::{str, char, cmp}; +use core::{str, char, cmp, num}; use io::prelude::*; use io; @@ -537,11 +537,11 @@ fn validate_long_name(name: &str) -> io::Result<()> { #[cfg(feature = "alloc")] fn lfn_checksum(short_name: &[u8]) -> u8 { - let mut chksum = 0u8; + let mut chksum = num::Wrapping(0u8); for i in 0..11 { - chksum = (((chksum & 1) << 7) as u16 + (chksum >> 1) as u16 + short_name[i] as u16) as u8; + chksum = (chksum << 7) + (chksum >> 1) + num::Wrapping(short_name[i]); } - chksum + chksum.0 } #[cfg(feature = "alloc")] @@ -796,11 +796,11 @@ impl ShortNameGenerator { fn checksum(name: &str) -> u16 { // BSD checksum algorithm - let mut chksum = 0u16; + let mut chksum = num::Wrapping(0u16); for c in name.chars() { - chksum = (chksum >> 1) + ((chksum & 1) << 15) + (c as u16); + chksum = (chksum >> 1) + (chksum << 15) + num::Wrapping(c as u16); } - chksum + chksum.0 } fn generate(&self) -> io::Result<[u8; 11]> { @@ -873,6 +873,16 @@ mod tests { assert_eq!(&ShortNameGenerator::new(".bashrc.swp").generate().unwrap(), "BASHRC~1SWP".as_bytes()); } + #[test] + fn test_short_name_checksum_overflow() { + ShortNameGenerator::checksum("\u{FF5A}\u{FF5A}\u{FF5A}\u{FF5A}"); + } + + #[test] + fn test_lfn_checksum_overflow() { + lfn_checksum(&[0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8]); + } + #[test] fn test_generate_short_name_collisions_long() { let mut buf: [u8; 11];