@@ -2,7 +2,7 @@ use std::io::prelude::*;
22use std:: error;
33use byteorder:: { ReadBytesExt , WriteBytesExt , BigEndian } ;
44
5- use postgres;
5+ use postgres:: { self , Result } ;
66use postgres:: error:: Error ;
77use postgres:: types:: { Type , Kind , ToSql , FromSql , Oid , IsNull , SessionInfo } ;
88
@@ -68,21 +68,29 @@ impl<T> ToSql for Array<T> where T: ToSql {
6868 _ => panic ! ( "unexpected type {:?}" , ty) ,
6969 } ;
7070
71- try!( w. write_u32 :: < BigEndian > ( self . dimensions ( ) . len ( ) as u32 ) ) ;
71+ try!( w. write_i32 :: < BigEndian > ( try! ( downcast ( self . dimensions ( ) . len ( ) ) ) ) ) ;
7272 try!( w. write_i32 :: < BigEndian > ( 1 ) ) ;
7373 try!( w. write_u32 :: < BigEndian > ( element_type. oid ( ) ) ) ;
7474
7575 for info in self . dimensions ( ) {
76- try!( w. write_u32 :: < BigEndian > ( info. len as u32 ) ) ;
77- try!( w. write_i32 :: < BigEndian > ( info. lower_bound as i32 ) ) ;
76+ try!( w. write_i32 :: < BigEndian > ( try!( downcast ( info. len ) ) ) ) ;
77+
78+ let bound = if info. lower_bound > i32:: max_value ( ) as isize
79+ || info. lower_bound < i32:: min_value ( ) as isize {
80+ let err: Box < error:: Error +Sync +Send > = "value too large to transmit" . into ( ) ;
81+ return Err ( Error :: Conversion ( err) ) ;
82+ } else {
83+ info. lower_bound as i32
84+ } ;
85+ try!( w. write_i32 :: < BigEndian > ( bound) ) ;
7886 }
7987
8088 let mut inner_buf = vec ! [ ] ;
8189 for v in self {
8290 match try!( v. to_sql ( element_type, & mut inner_buf, info) ) {
8391 IsNull :: Yes => try!( w. write_i32 :: < BigEndian > ( -1 ) ) ,
8492 IsNull :: No => {
85- try!( w. write_i32 :: < BigEndian > ( inner_buf. len ( ) as i32 ) ) ;
93+ try!( w. write_i32 :: < BigEndian > ( try! ( downcast ( inner_buf. len ( ) ) ) ) ) ;
8694 try!( w. write_all ( & inner_buf) ) ;
8795 }
8896 }
@@ -102,6 +110,15 @@ impl<T> ToSql for Array<T> where T: ToSql {
102110 to_sql_checked ! ( ) ;
103111}
104112
113+ fn downcast ( len : usize ) -> Result < i32 > {
114+ if len > i32:: max_value ( ) as usize {
115+ let err: Box < error:: Error +Sync +Send > = "value too large to transmit" . into ( ) ;
116+ Err ( Error :: Conversion ( err) )
117+ } else {
118+ Ok ( len as i32 )
119+ }
120+ }
121+
105122#[ cfg( test) ]
106123mod test {
107124 use std:: fmt;
0 commit comments