imservice: Check pointer validity
This commit is contained in:
@ -61,9 +61,9 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_input_method_activate(imservice: *mut IMService,
|
fn imservice_handle_input_method_activate(imservice: *mut IMService,
|
||||||
_im: *const InputMethod)
|
im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice.preedit_string = String::new();
|
imservice.preedit_string = String::new();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
active: true,
|
active: true,
|
||||||
@ -74,9 +74,9 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
|
fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
|
||||||
_im: *const InputMethod)
|
im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
active: false,
|
active: false,
|
||||||
..imservice.pending.clone()
|
..imservice.pending.clone()
|
||||||
@ -86,10 +86,10 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_surrounding_text(imservice: *mut IMService,
|
fn imservice_handle_surrounding_text(imservice: *mut IMService,
|
||||||
_im: *const InputMethod,
|
im: *const InputMethod,
|
||||||
text: *const c_char, cursor: u32, _anchor: u32)
|
text: *const c_char, cursor: u32, _anchor: u32)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
surrounding_text: into_cstring(text).expect("Received invalid string"),
|
surrounding_text: into_cstring(text).expect("Received invalid string"),
|
||||||
surrounding_cursor: cursor,
|
surrounding_cursor: cursor,
|
||||||
@ -100,10 +100,10 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_content_type(imservice: *mut IMService,
|
fn imservice_handle_content_type(imservice: *mut IMService,
|
||||||
_im: *const InputMethod,
|
im: *const InputMethod,
|
||||||
hint: u32, purpose: u32)
|
hint: u32, purpose: u32)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
content_hint: {
|
content_hint: {
|
||||||
ContentHint::from_bits(hint).unwrap_or_else(|| {
|
ContentHint::from_bits(hint).unwrap_or_else(|| {
|
||||||
@ -124,10 +124,10 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_text_change_cause(imservice: *mut IMService,
|
fn imservice_handle_text_change_cause(imservice: *mut IMService,
|
||||||
_im: *const InputMethod,
|
im: *const InputMethod,
|
||||||
cause: u32)
|
cause: u32)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
text_change_cause: {
|
text_change_cause: {
|
||||||
ChangeCause::try_from(cause).unwrap_or_else(|_e| {
|
ChangeCause::try_from(cause).unwrap_or_else(|_e| {
|
||||||
@ -142,9 +142,9 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_commit_state(imservice: *mut IMService,
|
fn imservice_handle_commit_state(imservice: *mut IMService,
|
||||||
_im: *const InputMethod)
|
im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = &mut *imservice;
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
let active_changed = imservice.current.active ^ imservice.pending.active;
|
let active_changed = imservice.current.active ^ imservice.pending.active;
|
||||||
|
|
||||||
imservice.serial += Wrapping(1u32);
|
imservice.serial += Wrapping(1u32);
|
||||||
@ -171,10 +171,9 @@ pub mod c {
|
|||||||
fn imservice_handle_unavailable(imservice: *mut IMService,
|
fn imservice_handle_unavailable(imservice: *mut IMService,
|
||||||
im: *mut InputMethod)
|
im: *mut InputMethod)
|
||||||
{
|
{
|
||||||
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
imservice_destroy_im(im);
|
imservice_destroy_im(im);
|
||||||
|
|
||||||
let imservice = &mut *imservice;
|
|
||||||
|
|
||||||
// no need to care about proper double-buffering,
|
// no need to care about proper double-buffering,
|
||||||
// the keyboard is already decommissioned
|
// the keyboard is already decommissioned
|
||||||
imservice.current.active = false;
|
imservice.current.active = false;
|
||||||
@ -183,6 +182,31 @@ pub mod c {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: destroy and deallocate
|
// FIXME: destroy and deallocate
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
/// Convenience method for referencing the IMService raw pointer,
|
||||||
|
/// and for verifying that the input method passed along
|
||||||
|
/// matches the one in the `imservice`.
|
||||||
|
///
|
||||||
|
/// The lifetime of the returned value is 'static,
|
||||||
|
/// due to the fact that the lifetime of a raw pointer is undefined.
|
||||||
|
/// Care must be take
|
||||||
|
/// not to exceed the lifetime of the pointer with the reference,
|
||||||
|
/// especially not to store it.
|
||||||
|
fn check_imservice(imservice: *mut IMService, im: *const InputMethod)
|
||||||
|
-> Result<&'static mut IMService, &'static str>
|
||||||
|
{
|
||||||
|
if imservice.is_null() {
|
||||||
|
return Err("Null imservice pointer");
|
||||||
|
}
|
||||||
|
let imservice: &mut IMService = unsafe { &mut *imservice };
|
||||||
|
if im == imservice.im {
|
||||||
|
Ok(imservice)
|
||||||
|
} else {
|
||||||
|
Err("Imservice doesn't contain the input method")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -298,7 +322,7 @@ impl Default for IMProtocolState {
|
|||||||
|
|
||||||
pub struct IMService {
|
pub struct IMService {
|
||||||
/// Owned reference (still created and destroyed in C)
|
/// Owned reference (still created and destroyed in C)
|
||||||
im: *const c::InputMethod,
|
pub im: *const c::InputMethod,
|
||||||
/// Unowned reference. Be careful, it's shared with C at large
|
/// Unowned reference. Be careful, it's shared with C at large
|
||||||
ui_manager: *const c::UIManager,
|
ui_manager: *const c::UIManager,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user