Skip to content

Commit 96d5184

Browse files
authored
Merge pull request #191 from TheEdward162/fix-minifb-example-ub
fix UB in minifb example
2 parents 6da6db4 + 91d8a99 commit 96d5184

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

Diff for: examples/minifb-demo/src/main.rs

+42-5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,49 @@ use plotters_bitmap::BitMapBackend;
55
use std::collections::VecDeque;
66
use std::error::Error;
77
use std::time::SystemTime;
8+
use std::borrow::{Borrow, BorrowMut};
89
const W: usize = 480;
910
const H: usize = 320;
1011

1112
const SAMPLE_RATE: f64 = 10_000.0;
1213
const FREAME_RATE: f64 = 30.0;
1314

15+
struct BufferWrapper(Vec<u32>);
16+
impl Borrow<[u8]> for BufferWrapper {
17+
fn borrow(&self) -> &[u8] {
18+
// Safe for alignment: align_of(u8) <= align_of(u32)
19+
// Safe for cast: u32 can be thought of as being transparent over [u8; 4]
20+
unsafe {
21+
std::slice::from_raw_parts(
22+
self.0.as_ptr() as *const u8,
23+
self.0.len() * 4
24+
)
25+
}
26+
}
27+
}
28+
impl BorrowMut<[u8]> for BufferWrapper {
29+
fn borrow_mut(&mut self) -> &mut [u8] {
30+
// Safe for alignment: align_of(u8) <= align_of(u32)
31+
// Safe for cast: u32 can be thought of as being transparent over [u8; 4]
32+
unsafe {
33+
std::slice::from_raw_parts_mut(
34+
self.0.as_mut_ptr() as *mut u8,
35+
self.0.len() * 4
36+
)
37+
}
38+
}
39+
}
40+
impl Borrow<[u32]> for BufferWrapper {
41+
fn borrow(&self) -> &[u32] {
42+
self.0.as_slice()
43+
}
44+
}
45+
impl BorrowMut<[u32]> for BufferWrapper {
46+
fn borrow_mut(&mut self) -> &mut [u32] {
47+
self.0.as_mut_slice()
48+
}
49+
}
50+
1451
fn get_window_title(fx: f64, fy: f64, iphase: f64) -> String {
1552
format!(
1653
"x={:.1}Hz, y={:.1}Hz, phase={:.1} +/-=Adjust y 9/0=Adjust x <Esc>=Exit",
@@ -19,7 +56,7 @@ fn get_window_title(fx: f64, fy: f64, iphase: f64) -> String {
1956
}
2057

2158
fn main() -> Result<(), Box<dyn Error>> {
22-
let mut buf = vec![0u8; W * H * 4];
59+
let mut buf = BufferWrapper(vec![0u32; W * H]);
2360

2461
let mut fx: f64 = 1.0;
2562
let mut fy: f64 = 1.1;
@@ -33,7 +70,7 @@ fn main() -> Result<(), Box<dyn Error>> {
3370
WindowOptions::default(),
3471
)?;
3572
let root =
36-
BitMapBackend::<BGRXPixel>::with_buffer_and_format(&mut buf[..], (W as u32, H as u32))?
73+
BitMapBackend::<BGRXPixel>::with_buffer_and_format(buf.borrow_mut(), (W as u32, H as u32))?
3774
.into_drawing_area();
3875
root.fill(&BLACK)?;
3976

@@ -81,7 +118,7 @@ fn main() -> Result<(), Box<dyn Error>> {
81118

82119
if epoch - last_flushed > 1.0 / FREAME_RATE {
83120
let root = BitMapBackend::<BGRXPixel>::with_buffer_and_format(
84-
&mut buf[..],
121+
buf.borrow_mut(),
85122
(W as u32, H as u32),
86123
)?
87124
.into_drawing_area();
@@ -134,8 +171,8 @@ fn main() -> Result<(), Box<dyn Error>> {
134171
break;
135172
}
136173
}
137-
let buf = unsafe { std::slice::from_raw_parts(&buf[0] as *const _ as *const _, H * W) };
138-
window.update_with_buffer(buf)?;
174+
175+
window.update_with_buffer(buf.borrow())?;
139176
last_flushed = epoch;
140177
}
141178

0 commit comments

Comments
 (0)