From 4afd38a15026164c6da7ec667fa6ae4ecd3d7f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Sun, 17 Jun 2018 21:58:39 +0200 Subject: [PATCH] Fix possible overflow when calculating short name checksum Affects debug build only. Overflow was not handled when calculating checksum used for short name generation when avoiding a conflict. LFN checksum was working properly but got refactored in this commit to use num::Wrapping as well. --- src/dir.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) 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];