Skip to content

Commit

Permalink
Merge pull request #11 from wravery/main
Browse files Browse the repository at this point in the history
fix: potentially unaligned pointers in PropValueData::Unicode
  • Loading branch information
wravery authored Oct 24, 2024
2 parents b27119c + 5c1d404 commit 5e783d9
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/mapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.15.3](https://github.com/wravery/outlook-mapi-rs/compare/outlook-mapi-v0.15.2...outlook-mapi-v0.15.3) - 2024-10-24

### Fixed
- copy potentially unaligned Unicode string pointers to owned `Vec<u16>`

## [0.15.2](https://github.com/wravery/outlook-mapi-rs/compare/outlook-mapi-v0.15.1...outlook-mapi-v0.15.2) - 2024-09-26

### Other
Expand Down
2 changes: 1 addition & 1 deletion crates/mapi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "outlook-mapi"
version = "0.15.2"
version = "0.15.3"
description = "Rust bindings for the Outlook MAPI interface"

authors.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/mapi/examples/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn main() -> Result<()> {
eprintln!("Store {idx}: missing display name");
continue;
};
let display_name = unsafe { display_name.to_string() }
let display_name = unsafe { PCWSTR::from_raw(display_name.as_ptr()).to_string() }
.unwrap_or_else(|err| format!("bad display name: {err}"));

println!(
Expand Down
26 changes: 19 additions & 7 deletions crates/mapi/src/prop_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub enum PropValueData<'a> {
Binary(&'a [u8]),

/// [`sys::PT_UNICODE`]
Unicode(PCWSTR),
Unicode(Vec<u16>),

/// [`sys::PT_CLSID`]
Guid(GUID),
Expand Down Expand Up @@ -146,7 +146,17 @@ impl<'a> From<&'a sys::SPropValue> for PropValue<'a> {
if value.Value.lpszW.is_null() {
PropValueData::Error(E_POINTER)
} else {
PropValueData::Unicode(PCWSTR::from_raw(value.Value.lpszW.as_ptr()))
let mut aligned = Vec::new();
let mut raw = value.Value.lpszW.as_ptr();
loop {
let next = ptr::read_unaligned(raw);
raw = raw.offset(1);
aligned.push(next);
if next == 0 {
break;
}
}
PropValueData::Unicode(aligned)
}
}
sys::PT_CLSID => {
Expand Down Expand Up @@ -318,7 +328,7 @@ mod tests {
use super::*;

use crate::{sys, PropTag, PropType};
use core::{mem, ptr};
use core::{iter, mem, ptr};
use windows_core::{s, w};

#[test]
Expand Down Expand Up @@ -516,11 +526,13 @@ mod tests {
};
value.Value.lpszW.0 = expected.0 as *mut _;
let value = PropValue::from(&value);
let PropValueData::Unicode(actual) = value.value else {
panic!("wrong type");
};
assert_eq!(u32::from(value.tag.prop_type()), sys::PT_UNICODE);
assert!(matches!(
value.value,
PropValueData::Unicode(actual) if actual.0 == expected.0
));
let expected = unsafe { expected.as_wide() };
let expected: Vec<_> = expected.iter().copied().chain(iter::once(0)).collect();
assert_eq!(actual, expected);
}

#[test]
Expand Down

0 comments on commit 5e783d9

Please sign in to comment.