From 16be4ef715a406321d2a8019de62d4da03fe5f81 Mon Sep 17 00:00:00 2001 From: Fenrir Date: Sun, 21 Jan 2018 23:12:55 -0700 Subject: [PATCH] Fix unsoundness in Console's API --- ctru-rs/src/console.rs | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/ctru-rs/src/console.rs b/ctru-rs/src/console.rs index 040096a..d1a22e6 100644 --- a/ctru-rs/src/console.rs +++ b/ctru-rs/src/console.rs @@ -1,31 +1,46 @@ use std::default::Default; -use std::ptr; +use std::mem; + +use libctru::{PrintConsole, consoleInit, consoleSelect, consoleClear, consoleSetWindow}; use gfx::Screen; pub struct Console { - context: ::libctru::PrintConsole, + context: Box, } impl Console { + /// Initialize a console on the chosen screen, overwriting whatever was on the screen + /// previously (including other consoles). The new console is automatically selected for + /// printing. pub fn init(screen: Screen) -> Self { unsafe { - let context = ptr::read(::libctru::consoleInit(screen.into(), ptr::null_mut())); + let mut context = Box::new(mem::uninitialized::()); + consoleInit(screen.into(), context.as_mut()); Console { context, } } } - pub fn select(&mut self) { - unsafe { ::libctru::consoleSelect(&mut self.context); } + /// Select this console as the current target for stdout + pub fn select(&self) { + unsafe { consoleSelect(self.context.as_ref() as *const _ as *mut _); } } - pub fn set_window(&mut self, x: i32, y: i32, width: i32, height: i32) { - unsafe { ::libctru::consoleSetWindow(&mut self.context, x, y, width, height) } - } - - pub fn clear(&mut self) { - unsafe { ::libctru::consoleClear() } + /// Clears all text from the console + pub fn clear(&self) { + unsafe { consoleClear() } } + + /// Resizes the active console to fit in a smaller portion of the screen. + /// + /// The first two arguments are the desired coordinates of the top-left corner + /// of the console, and the second pair is the new width and height + /// + /// This function is unsafe because it does not validate that the input will produce + /// a console that actually fits on the screen + pub unsafe fn set_window(&mut self, x: i32, y: i32, width: i32, height: i32) { + consoleSetWindow(self.context.as_mut(), x, y, width, height); + } } impl Default for Console {