-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
One of my main goals of several recent refactorings is to get rid of as many `*(*(*foo).bar).baz` as possible, replacing them with proper `.as_ref().unwrap()` -- in other words replacing pointer dereferences with proper references. This ensures a single NULL validation location in the `.unwrap()`, and allows Rust to validate all references thereafter. All these PRs should be considered as intermediary steps - I'm sure we can come up with a better overall abstraction that ensures that no `unsafe` API is exposed by default. * consolidate `get_backend` into a single validatable function * a few more wrapper validation functions for clearer intent * Added a few more `FIXME` -- these are more like notes for future refactorings, to make sure we don't forget about them. Some of them could be fixed with just a comment, explaining why something is done that way.
- Loading branch information
Showing
2 changed files
with
83 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,65 @@ | ||
use crate::ffi; | ||
use crate::ffi::{vfp_entry, vrt_ctx}; | ||
use crate::vcl::backend::VCLBackendPtr; | ||
use crate::ffi::{ | ||
director, req, sess, vcldir, vfp_ctx, vfp_entry, vrt_ctx, ws, DIRECTOR_MAGIC, REQ_MAGIC, | ||
SESS_MAGIC, VCLDIR_MAGIC, VFP_CTX_MAGIC, VFP_ENTRY_MAGIC, VRT_CTX_MAGIC, WS_MAGIC, | ||
}; | ||
use crate::vcl::backend::{Serve, Transfer, VCLBackendPtr}; | ||
|
||
pub(crate) unsafe fn validate_vfp_ctx(ctxp: *mut ffi::vfp_ctx) -> &'static mut ffi::vfp_ctx { | ||
let ctx = ctxp.as_mut().unwrap(); | ||
assert_eq!(ctx.magic, ffi::VFP_CTX_MAGIC); | ||
ctx | ||
pub(crate) unsafe fn validate_vfp_ctx(ctxp: *mut vfp_ctx) -> &'static mut vfp_ctx { | ||
let val = ctxp.as_mut().unwrap(); | ||
assert_eq!(val.magic, VFP_CTX_MAGIC); | ||
val | ||
} | ||
|
||
pub(crate) unsafe fn validate_vrt_ctx(ctxp: *const vrt_ctx) -> &'static vrt_ctx { | ||
let ctxp = ctxp.as_ref().unwrap(); | ||
assert_eq!(ctxp.magic, ffi::VRT_CTX_MAGIC); | ||
ctxp | ||
let val = ctxp.as_ref().unwrap(); | ||
assert_eq!(val.magic, VRT_CTX_MAGIC); | ||
val | ||
} | ||
|
||
pub(crate) unsafe fn validate_vfp_entry(vfep: *mut vfp_entry) -> &'static mut vfp_entry { | ||
let vfe = vfep.as_mut().unwrap(); | ||
assert_eq!(vfe.magic, ffi::VFP_ENTRY_MAGIC); | ||
vfe | ||
let val = vfep.as_mut().unwrap(); | ||
assert_eq!(val.magic, VFP_ENTRY_MAGIC); | ||
val | ||
} | ||
|
||
pub(crate) unsafe fn validate_director(be: VCLBackendPtr) -> &'static ffi::director { | ||
let be = be.as_ref().unwrap(); | ||
assert_eq!(be.magic, ffi::DIRECTOR_MAGIC); | ||
be | ||
pub(crate) unsafe fn validate_director(be: VCLBackendPtr) -> &'static director { | ||
let val = be.as_ref().unwrap(); | ||
assert_eq!(val.magic, DIRECTOR_MAGIC); | ||
val | ||
} | ||
|
||
pub(crate) unsafe fn validate_ws(wsp: *mut ffi::ws) -> &'static mut ffi::ws { | ||
let ws = wsp.as_mut().unwrap(); | ||
assert_eq!(ws.magic, ffi::WS_MAGIC); | ||
ws | ||
pub(crate) unsafe fn validate_ws(wsp: *mut ws) -> &'static mut ws { | ||
let val = wsp.as_mut().unwrap(); | ||
assert_eq!(val.magic, WS_MAGIC); | ||
val | ||
} | ||
|
||
pub(crate) unsafe fn validate_vdir(be: &director) -> &'static mut vcldir { | ||
let val = be.vdir.as_mut().unwrap(); | ||
assert_eq!(val.magic, VCLDIR_MAGIC); | ||
val | ||
} | ||
|
||
impl vrt_ctx { | ||
pub fn validated_req(&mut self) -> &mut req { | ||
let val = unsafe { self.req.as_mut().unwrap() }; | ||
assert_eq!(val.magic, REQ_MAGIC); | ||
val | ||
} | ||
} | ||
|
||
impl req { | ||
pub fn validated_session(&mut self) -> &sess { | ||
let val = unsafe { self.sp.as_ref().unwrap() }; | ||
assert_eq!(val.magic, SESS_MAGIC); | ||
val | ||
} | ||
} | ||
|
||
impl director { | ||
/// Return the private pointer as a reference to the [`Serve`] object | ||
/// FIXME: should it return a `&mut` instead? | ||
pub fn get_backend<S: Serve<T>, T: Transfer>(&self) -> &S { | ||
unsafe { self.priv_.cast::<S>().as_ref().unwrap() } | ||
} | ||
} |