mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 11:21:30 +11:00
Implemented bounds checking for update_with_buffer
This commit is contained in:
parent
6db90d717f
commit
900deba9a7
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "minifb"
|
||||
version = "0.9.2"
|
||||
version = "0.10.0"
|
||||
license = "MIT/Apache-2.0"
|
||||
authors = ["Daniel Collin <daniel@collin.com>"]
|
||||
description = "Cross-platform window setup with optional bitmap rendering"
|
||||
|
|
|
@ -43,7 +43,8 @@ fn main() {
|
|||
*i = 0; // write something more funny here!
|
||||
}
|
||||
|
||||
window.update_with_buffer(&buffer);
|
||||
// We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way
|
||||
window.update_with_buffer(&buffer).unwrap();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -26,7 +26,7 @@ fn main() {
|
|||
|
||||
let mut window = Window::new("Menu Test - Press ESC to exit",
|
||||
WIDTH,
|
||||
HEIGHT,
|
||||
HEIGHT + 2,
|
||||
WindowOptions {
|
||||
resize: true,
|
||||
scale: Scale::X2,
|
||||
|
@ -98,6 +98,7 @@ fn main() {
|
|||
}
|
||||
});
|
||||
|
||||
window.update_with_buffer(&buffer);
|
||||
// We unwrap here as we want this code to exit if it fails
|
||||
window.update_with_buffer(&buffer).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ fn main() {
|
|||
println!("Scrolling {} - {}", scroll.0, scroll.1);
|
||||
});
|
||||
|
||||
window.update_with_buffer(&buffer);
|
||||
// We unwrap here as we want this code to exit if it fails
|
||||
window.update_with_buffer(&buffer).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ fn main() {
|
|||
}
|
||||
});
|
||||
|
||||
window.update_with_buffer(&buffer);
|
||||
// We unwrap here as we want this code to exit if it fails
|
||||
window.update_with_buffer(&buffer).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,8 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
window.update_with_buffer(&buffer);
|
||||
// We unwrap here as we want this code to exit if it fails
|
||||
window.update_with_buffer(&buffer).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/buffer_helper.rs
Normal file
15
src/buffer_helper.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use error::Error;
|
||||
use Result;
|
||||
|
||||
pub fn check_buffer_size(window_width: usize, window_height: usize, scale: usize, buffer: &[u32]) -> Result<()> {
|
||||
let buffer_size = buffer.len() * 4; // len is the number of entries so * 4 as we want bytes
|
||||
let required_buffer_size = (window_width / scale) * (window_height / scale) * 4; // * 4 for 32-bit buffer
|
||||
|
||||
if buffer_size < required_buffer_size {
|
||||
let err = format!("Update failed because input buffer is too small. Required size for {} x {} window ({}x scale) is {} bytes but the size of the input buffer has the size {} bytes",
|
||||
window_width, window_height, scale, required_buffer_size, buffer_size);
|
||||
Err(Error::UpdateFailed(err))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
15
src/error.rs
15
src/error.rs
|
@ -5,12 +5,14 @@ use std::fmt;
|
|||
///
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Returned if menu Menu function isn't supported
|
||||
/// Returned if menu Menu function isn't supported
|
||||
MenusNotSupported,
|
||||
/// Menu already exists
|
||||
/// Menu already exists
|
||||
MenuExists(String),
|
||||
/// Menu already exists
|
||||
/// Menu already exists
|
||||
WindowCreate(String),
|
||||
/// Unable to Update
|
||||
UpdateFailed(String),
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
|
@ -18,7 +20,8 @@ impl StdError for Error {
|
|||
match *self {
|
||||
Error::MenusNotSupported => "Menus not supported",
|
||||
Error::MenuExists(_) => "Menu already exists",
|
||||
Error::WindowCreate(_) => "Failed to create Window",
|
||||
Error::WindowCreate(_) => "Failed to create window",
|
||||
Error::UpdateFailed(_) => "Failed to Update",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +30,7 @@ impl StdError for Error {
|
|||
Error::MenusNotSupported => None,
|
||||
Error::MenuExists(_) => None,
|
||||
Error::WindowCreate(_) => None,
|
||||
Error::UpdateFailed(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +47,9 @@ impl fmt::Display for Error {
|
|||
Error::WindowCreate(ref e) => {
|
||||
write!(fmt, "{} {:?}", self.description(), e)
|
||||
}
|
||||
Error::UpdateFailed(ref e) => {
|
||||
write!(fmt, "{} {:?}", self.description(), e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ pub use key::Key as Key;
|
|||
#[doc(hidden)]
|
||||
pub mod os;
|
||||
mod mouse_handler;
|
||||
mod buffer_helper;
|
||||
mod key_handler;
|
||||
mod window_flags;
|
||||
//mod menu;
|
||||
|
@ -222,10 +223,10 @@ impl Window {
|
|||
///
|
||||
/// let mut window = match Window::new("Test", 640, 400, WindowOptions::default()).unwrap();
|
||||
///
|
||||
/// window.update_with_buffer(&buffer);
|
||||
/// window.update_with_buffer(&buffer).unwrap();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) {
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) -> Result<()> {
|
||||
self.0.update_with_buffer(buffer)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use Result;
|
|||
// use MenuItem;
|
||||
use InputCallback;
|
||||
use mouse_handler;
|
||||
use buffer_helper;
|
||||
use window_flags;
|
||||
use {CursorStyle, MenuItem, MenuItemHandle, MenuHandle};
|
||||
// use menu::Menu;
|
||||
|
@ -291,9 +292,17 @@ impl Window {
|
|||
mfb_set_mouse_data(self.window_handle, &mut self.shared_data);
|
||||
}
|
||||
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) {
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) -> Result<()> {
|
||||
self.key_handler.update();
|
||||
|
||||
let check_res = buffer_helper::check_buffer_size(self.shared_data.width as usize,
|
||||
self.shared_data.height as usize,
|
||||
self.scale_factor as usize,
|
||||
buffer);
|
||||
if check_res.is_err() {
|
||||
return check_res;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
mfb_update_with_buffer(self.window_handle, buffer.as_ptr() as *const u8);
|
||||
Self::set_mouse_data(self);
|
||||
|
@ -302,6 +311,8 @@ impl Window {
|
|||
key_callback,
|
||||
char_callback);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
|
|
|
@ -6,6 +6,7 @@ use os::redox::orbclient::Renderer;
|
|||
use error::Error;
|
||||
use Result;
|
||||
use mouse_handler;
|
||||
use buffer_height;
|
||||
use key_handler::KeyHandler;
|
||||
use InputCallback;
|
||||
use {CursorStyle, MouseButton, MouseMode};
|
||||
|
@ -100,11 +101,19 @@ impl Window {
|
|||
0 as *mut raw::c_void
|
||||
}
|
||||
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) {
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) -> Result<()> {
|
||||
self.process_events();
|
||||
self.key_handler.update();
|
||||
|
||||
let check_res = buffer_helper::check_buffer_size(self.buffer_width, self.buffer_height, self.window_scale, buffer);
|
||||
if check_res.is_err() {
|
||||
return check_res;
|
||||
}
|
||||
|
||||
self.render_buffer(buffer);
|
||||
self.window.sync();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
|
|
|
@ -19,6 +19,7 @@ use std::ptr;
|
|||
use std::mem;
|
||||
use std::os::raw;
|
||||
use mouse_handler;
|
||||
use buffer_helper;
|
||||
use window_flags;
|
||||
|
||||
#[link(name = "X11")]
|
||||
|
@ -235,6 +236,14 @@ impl Window {
|
|||
pub fn update_with_buffer(&mut self, buffer: &[u32]) {
|
||||
self.key_handler.update();
|
||||
|
||||
let check_res = buffer_helper::check_buffer_size(self.shared_data.width as usize,
|
||||
self.shared_data.height as usize,
|
||||
self.scale_factor as usize,
|
||||
buffer);
|
||||
if check_res.is_err() {
|
||||
return check_res;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
Self::set_shared_data(self);
|
||||
mfb_update_with_buffer(self.window_handle, buffer.as_ptr() as *const u8);
|
||||
|
|
|
@ -21,6 +21,7 @@ use std::ffi::OsStr;
|
|||
use std::mem;
|
||||
use std::os::raw;
|
||||
use mouse_handler;
|
||||
use buffer_helper;
|
||||
|
||||
//use self::winapi::windef::HWND;
|
||||
//use self::winapi::windef::HDC;
|
||||
|
@ -634,17 +635,27 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) {
|
||||
pub fn update_with_buffer(&mut self, buffer: &[u32]) -> Result<()> {
|
||||
let window = self.window.unwrap();
|
||||
|
||||
Self::generic_update(self, window);
|
||||
|
||||
let check_res = buffer_helper::check_buffer_size(self.width as usize,
|
||||
self.height as usize,
|
||||
self.scale_factor as usize,
|
||||
buffer);
|
||||
if check_res.is_err() {
|
||||
return check_res;
|
||||
}
|
||||
|
||||
self.buffer = buffer.to_vec();
|
||||
unsafe {
|
||||
user32::InvalidateRect(window, ptr::null_mut(), winapi::TRUE);
|
||||
}
|
||||
|
||||
Self::message_loop(self, window);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
|
|
Loading…
Reference in a new issue