Add a canary to PostgresConnection
This is a workaround for mozilla/rust#13246 to prevent total badness until it gets fixed. cc #34, #31
This commit is contained in:
parent
0d70c17151
commit
3c4dcf8768
19
src/lib.rs
19
src/lib.rs
@ -183,11 +183,14 @@ macro_rules! try_desync(
|
|||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! check_desync(
|
macro_rules! check_desync(
|
||||||
($e:expr) => (
|
($e:expr) => ({
|
||||||
|
if $e.canary() != CANARY {
|
||||||
|
fail!("PostgresConnection use after free. See mozilla/rust#13246.");
|
||||||
|
}
|
||||||
if $e.is_desynchronized() {
|
if $e.is_desynchronized() {
|
||||||
return Err(PgStreamDesynchronized);
|
return Err(PgStreamDesynchronized);
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
@ -198,6 +201,7 @@ pub mod types;
|
|||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
static DEFAULT_PORT: Port = 5432;
|
static DEFAULT_PORT: Port = 5432;
|
||||||
|
static CANARY: u32 = 0xdeadbeef;
|
||||||
|
|
||||||
/// A typedef of the result returned by many methods.
|
/// A typedef of the result returned by many methods.
|
||||||
pub type PostgresResult<T> = Result<T, PostgresError>;
|
pub type PostgresResult<T> = Result<T, PostgresError>;
|
||||||
@ -392,6 +396,7 @@ struct InnerPostgresConnection {
|
|||||||
unknown_types: HashMap<Oid, ~str>,
|
unknown_types: HashMap<Oid, ~str>,
|
||||||
desynchronized: bool,
|
desynchronized: bool,
|
||||||
finished: bool,
|
finished: bool,
|
||||||
|
canary: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for InnerPostgresConnection {
|
impl Drop for InnerPostgresConnection {
|
||||||
@ -438,6 +443,7 @@ impl InnerPostgresConnection {
|
|||||||
unknown_types: HashMap::new(),
|
unknown_types: HashMap::new(),
|
||||||
desynchronized: false,
|
desynchronized: false,
|
||||||
finished: false,
|
finished: false,
|
||||||
|
canary: CANARY,
|
||||||
};
|
};
|
||||||
|
|
||||||
args.push((~"client_encoding", ~"UTF8"));
|
args.push((~"client_encoding", ~"UTF8"));
|
||||||
@ -644,6 +650,10 @@ impl InnerPostgresConnection {
|
|||||||
self.desynchronized
|
self.desynchronized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn canary(&self) -> u32 {
|
||||||
|
self.canary
|
||||||
|
}
|
||||||
|
|
||||||
fn wait_for_ready(&mut self) -> PostgresResult<()> {
|
fn wait_for_ready(&mut self) -> PostgresResult<()> {
|
||||||
match try_pg!(self.read_message()) {
|
match try_pg!(self.read_message()) {
|
||||||
ReadyForQuery { .. } => Ok(()),
|
ReadyForQuery { .. } => Ok(()),
|
||||||
@ -677,6 +687,7 @@ impl InnerPostgresConnection {
|
|||||||
|
|
||||||
fn finish_inner(&mut self) -> PostgresResult<()> {
|
fn finish_inner(&mut self) -> PostgresResult<()> {
|
||||||
check_desync!(self);
|
check_desync!(self);
|
||||||
|
self.canary = 0;
|
||||||
Ok(try_pg!(self.write_messages([Terminate])))
|
Ok(try_pg!(self.write_messages([Terminate])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,6 +846,10 @@ impl PostgresConnection {
|
|||||||
conn.finish_inner()
|
conn.finish_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn canary(&self) -> u32 {
|
||||||
|
self.conn.borrow_mut().canary()
|
||||||
|
}
|
||||||
|
|
||||||
fn quick_query(&self, query: &str)
|
fn quick_query(&self, query: &str)
|
||||||
-> PostgresResult<Vec<Vec<Option<~str>>>> {
|
-> PostgresResult<Vec<Vec<Option<~str>>>> {
|
||||||
self.conn.borrow_mut().quick_query(query)
|
self.conn.borrow_mut().quick_query(query)
|
||||||
|
Loading…
Reference in New Issue
Block a user