@@ -183,11 +183,14 @@ macro_rules! try_desync(
183
183
)
184
184
185
185
macro_rules! check_desync(
186
- ( $e: expr) => (
186
+ ( $e: expr) => ( {
187
+ if $e. canary( ) != CANARY {
188
+ fail!( "PostgresConnection use after free. See mozilla/rust#13246." ) ;
189
+ }
187
190
if $e. is_desynchronized( ) {
188
191
return Err ( PgStreamDesynchronized ) ;
189
192
}
190
- )
193
+ } )
191
194
)
192
195
193
196
pub mod error;
@@ -198,6 +201,7 @@ pub mod types;
198
201
mod test;
199
202
200
203
static DEFAULT_PORT : Port = 5432 ;
204
+ static CANARY : u32 = 0xdeadbeef ;
201
205
202
206
/// A typedef of the result returned by many methods.
203
207
pub type PostgresResult < T > = Result < T , PostgresError > ;
@@ -392,6 +396,7 @@ struct InnerPostgresConnection {
392
396
unknown_types : HashMap < Oid , ~str > ,
393
397
desynchronized : bool ,
394
398
finished : bool ,
399
+ canary : u32 ,
395
400
}
396
401
397
402
impl Drop for InnerPostgresConnection {
@@ -438,6 +443,7 @@ impl InnerPostgresConnection {
438
443
unknown_types : HashMap :: new ( ) ,
439
444
desynchronized : false ,
440
445
finished : false ,
446
+ canary : CANARY ,
441
447
} ;
442
448
443
449
args. push ( ( ~"client_encoding", ~"UTF8 ") ) ;
@@ -644,6 +650,10 @@ impl InnerPostgresConnection {
644
650
self . desynchronized
645
651
}
646
652
653
+ fn canary ( & self ) -> u32 {
654
+ self . canary
655
+ }
656
+
647
657
fn wait_for_ready ( & mut self ) -> PostgresResult < ( ) > {
648
658
match try_pg ! ( self . read_message( ) ) {
649
659
ReadyForQuery { .. } => Ok ( ( ) ) ,
@@ -677,6 +687,7 @@ impl InnerPostgresConnection {
677
687
678
688
fn finish_inner ( & mut self ) -> PostgresResult < ( ) > {
679
689
check_desync ! ( self ) ;
690
+ self . canary = 0 ;
680
691
Ok ( try_pg ! ( self . write_messages( [ Terminate ] ) ) )
681
692
}
682
693
}
@@ -835,6 +846,10 @@ impl PostgresConnection {
835
846
conn. finish_inner ( )
836
847
}
837
848
849
+ fn canary ( & self ) -> u32 {
850
+ self . conn . borrow_mut ( ) . canary ( )
851
+ }
852
+
838
853
fn quick_query ( & self , query : & str )
839
854
-> PostgresResult < Vec < Vec < Option < ~str > > > > {
840
855
self . conn . borrow_mut ( ) . quick_query ( query)
0 commit comments