@@ -51,18 +51,24 @@ fn map_key_cmp(a: &Vec<u8>, b: &Vec<u8>) -> std::cmp::Ordering {
5151 }
5252}
5353
54- fn sort_map_keys ( keys : & Bound < PyList > , len : usize ) -> Vec < ( PyBackedStr , usize ) > {
54+ fn sort_map_keys ( keys : & Bound < PyList > , len : usize ) -> Result < Vec < ( PyBackedStr , usize ) > > {
5555 // Returns key and index.
5656 let mut keys_str = Vec :: with_capacity ( len) ;
5757 for i in 0 ..len {
58- let item = keys. get_item ( i) . unwrap ( ) ;
59- let key = item. downcast :: < PyString > ( ) . unwrap ( ) . to_owned ( ) ;
60- let backed_str = PyBackedStr :: try_from ( key) . unwrap ( ) ;
58+ let item = keys. get_item ( i) ?;
59+ let key = match item. downcast :: < PyString > ( ) {
60+ Ok ( k) => k. to_owned ( ) ,
61+ Err ( _) => return Err ( anyhow ! ( "Map keys must be strings" ) ) ,
62+ } ;
63+ let backed_str = match PyBackedStr :: try_from ( key) {
64+ Ok ( bs) => bs,
65+ Err ( _) => return Err ( anyhow ! ( "Failed to convert PyString to PyBackedStr" ) ) ,
66+ } ;
6167 keys_str. push ( ( backed_str, i) ) ;
6268 }
6369
6470 if keys_str. len ( ) < 2 {
65- return keys_str;
71+ return Ok ( keys_str) ;
6672 }
6773
6874 keys_str. sort_by ( |a, b| {
@@ -78,7 +84,7 @@ fn sort_map_keys(keys: &Bound<PyList>, len: usize) -> Vec<(PyBackedStr, usize)>
7884 }
7985 } ) ;
8086
81- keys_str
87+ Ok ( keys_str)
8288}
8389
8490fn get_bytes_from_py_any < ' py > ( obj : & ' py Bound < ' py , PyAny > ) -> PyResult < & ' py [ u8 ] > {
@@ -96,11 +102,13 @@ fn get_bytes_from_py_any<'py>(obj: &'py Bound<'py, PyAny>) -> PyResult<&'py [u8]
96102 }
97103}
98104
99- fn string_new_bound < ' py > ( py : Python < ' py > , s : & [ u8 ] ) -> Bound < ' py , PyString > {
105+ fn string_new_bound < ' py > ( py : Python < ' py > , s : & [ u8 ] ) -> Result < Bound < ' py , PyString > > {
106+ std:: str:: from_utf8 ( s) . map_err ( |e| anyhow ! ( "Invalid UTF-8 string: {}" , e) ) ?;
107+
100108 let ptr = s. as_ptr ( ) as * const c_char ;
101109 let len = s. len ( ) as ffi:: Py_ssize_t ;
102110 unsafe {
103- Bound :: from_owned_ptr ( py, ffi:: PyUnicode_FromStringAndSize ( ptr, len) ) . downcast_into_unchecked ( )
111+ Ok ( Bound :: from_owned_ptr ( py, ffi:: PyUnicode_FromStringAndSize ( ptr, len) ) . downcast_into_unchecked ( ) )
104112 }
105113}
106114
@@ -122,14 +130,14 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(
122130 let major = decode:: read_major ( r) ?;
123131 Ok ( match major. kind ( ) {
124132 MajorKind :: UnsignedInt => decode:: read_uint ( r, major) ?. into_pyobject ( py) ?. into ( ) ,
125- MajorKind :: NegativeInt => ( -1 - decode:: read_uint ( r, major) ? as i64 ) . into_pyobject ( py) ?. into ( ) ,
133+ MajorKind :: NegativeInt => ( -1 - decode:: read_uint ( r, major) ? as i128 ) . into_pyobject ( py) ?. into ( ) ,
126134 MajorKind :: ByteString => {
127135 let len = decode:: read_uint ( r, major) ?;
128136 PyBytes :: new ( py, & decode:: read_bytes ( r, len) ?) . into_pyobject ( py) ?. into ( )
129137 }
130138 MajorKind :: TextString => {
131139 let len = decode:: read_uint ( r, major) ?;
132- string_new_bound ( py, & decode:: read_bytes ( r, len) ?) . into_pyobject ( py) ?. into ( )
140+ string_new_bound ( py, & decode:: read_bytes ( r, len) ?) ? . into_pyobject ( py) ?. into ( )
133141 }
134142 MajorKind :: Array => {
135143 let len: ffi:: Py_ssize_t = decode_len ( decode:: read_uint ( r, major) ?) ?. try_into ( ) ?;
@@ -167,7 +175,7 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(
167175 }
168176 }
169177
170- let key_py = string_new_bound ( py, key. as_slice ( ) ) . into_pyobject ( py) ?;
178+ let key_py = string_new_bound ( py, key. as_slice ( ) ) ? . into_pyobject ( py) ?;
171179 prev_key = Some ( key) ;
172180
173181 let value_py = decode_dag_cbor_to_pyobject ( py, r, depth + 1 ) ?;
@@ -191,8 +199,20 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(
191199 cbor:: FALSE => false . into_pyobject ( py) ?. into_any ( ) . unbind ( ) ,
192200 cbor:: TRUE => true . into_pyobject ( py) ?. into_any ( ) . unbind ( ) ,
193201 cbor:: NULL => py. None ( ) ,
194- cbor:: F32 => decode:: read_f32 ( r) ?. into_pyobject ( py) ?. into ( ) ,
195- cbor:: F64 => decode:: read_f64 ( r) ?. into_pyobject ( py) ?. into ( ) ,
202+ cbor:: F32 => {
203+ let value = decode:: read_f32 ( r) ?;
204+ if !value. is_finite ( ) {
205+ return Err ( anyhow ! ( "Number out of range for f32 (NaNs are forbidden)" . to_string( ) ) ) ;
206+ }
207+ value. into_pyobject ( py) ?. into ( )
208+ } ,
209+ cbor:: F64 => {
210+ let value = decode:: read_f64 ( r) ?;
211+ if !value. is_finite ( ) {
212+ return Err ( anyhow ! ( "Number out of range for f64 (NaNs are forbidden)" . to_string( ) ) ) ;
213+ }
214+ value. into_pyobject ( py) ?. into ( )
215+ } ,
196216 _ => return Err ( anyhow ! ( "Unsupported major type" . to_string( ) ) ) ,
197217 } ,
198218 } )
@@ -231,7 +251,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
231251
232252 Ok ( ( ) )
233253 } else if obj. is_instance_of :: < PyInt > ( ) {
234- let i: i64 = obj. extract ( ) ?;
254+ let i: i128 = obj. extract ( ) ?;
235255
236256 if i. is_negative ( ) {
237257 encode:: write_u64 ( w, MajorKind :: NegativeInt , -( i + 1 ) as u64 ) ?
@@ -252,7 +272,7 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>(
252272 Ok ( ( ) )
253273 } else if let Ok ( map) = obj. downcast :: < PyDict > ( ) {
254274 let len = map. len ( ) ;
255- let keys = sort_map_keys ( & map. keys ( ) , len) ;
275+ let keys = sort_map_keys ( & map. keys ( ) , len) ? ;
256276 let values = map. values ( ) ;
257277
258278 encode:: write_u64 ( w, MajorKind :: Map , len as u64 ) ?;
0 commit comments