@@ -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
7575for 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
8088let mut inner_buf = vec ! [ ] ;
8189for v in self {
8290match try!( v. to_sql ( element_type, & mut inner_buf, info) ) {
8391IsNull :: Yes => try!( w. write_i32 :: < BigEndian > ( -1 ) ) ,
8492IsNull :: 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{
102110to_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 {
107124use std:: fmt;
0 commit comments