@@ -10,7 +10,10 @@ use alloc::{string::String, vec::Vec};
1010
1111use ciborium_io:: Read ;
1212use ciborium_ll:: * ;
13- use serde:: { de, de:: Deserializer as _, forward_to_deserialize_any} ;
13+ use serde:: {
14+ de:: { self , value:: BytesDeserializer , Deserializer as _} ,
15+ forward_to_deserialize_any,
16+ } ;
1417
1518trait Expected < E : de:: Error > {
1619 fn expected ( self , kind : & ' static str ) -> E ;
@@ -52,6 +55,8 @@ pub struct Deserializer<'b, R: Read> {
5255 recurse : usize ,
5356}
5457
58+ fn noop ( _: u8 ) { }
59+
5560impl < ' a , R : Read > Deserializer < ' a , R >
5661where
5762 R :: Error : core:: fmt:: Debug ,
7277 }
7378
7479 #[ inline]
75- fn integer ( & mut self , mut header : Option < Header > ) -> Result < ( bool , u128 ) , Error < R :: Error > > {
80+ fn integer < A : FnMut ( u8 ) > (
81+ & mut self ,
82+ mut header : Option < Header > ,
83+ should_append : bool ,
84+ mut append : A ,
85+ ) -> Result < ( bool , u128 ) , Error < R :: Error > > {
7686 loop {
7787 let header = match header. take ( ) {
7888 Some ( h) => h,
@@ -99,7 +109,22 @@ where
99109 while let Some ( chunk) = segment. pull ( & mut buffer) ? {
100110 for b in chunk {
101111 match index {
102- 16 => return Err ( de:: Error :: custom ( "bigint too large" ) ) ,
112+ 16 => {
113+ if should_append {
114+ for v in value {
115+ append ( v) ;
116+ }
117+ append ( * b) ;
118+ index = 17 ; // Indicate overflow, see below
119+ continue ;
120+ }
121+ return Err ( de:: Error :: custom ( "bigint too large" ) ) ;
122+ }
123+ 17 => {
124+ debug_assert ! ( should_append) ;
125+ append ( * b) ;
126+ continue ;
127+ }
103128 0 if * b == 0 => continue , // Skip leading zeros
104129 _ => value[ index] = * b,
105130 }
@@ -109,8 +134,12 @@ where
109134 }
110135 }
111136
112- value[ ..index] . reverse ( ) ;
113- Ok ( ( neg, u128:: from_le_bytes ( value) ) )
137+ if index == 17 {
138+ Ok ( ( false , 0 ) )
139+ } else {
140+ value[ ..index] . reverse ( ) ;
141+ Ok ( ( neg, u128:: from_le_bytes ( value) ) )
142+ }
114143 }
115144
116145 h => Err ( h. expected ( "bytes" ) ) ,
@@ -157,18 +186,21 @@ where
157186 let header = self . decoder . pull ( ) ?;
158187 self . decoder . push ( header) ;
159188
160- // If it is bytes, capture the length.
161- let len = match header {
162- Header :: Bytes ( x) => x,
163- _ => None ,
164- } ;
165-
166- match ( tag, len) {
167- ( tag:: BIGPOS , Some ( len) ) | ( tag:: BIGNEG , Some ( len) ) if len <= 16 => {
168- let result = match self . integer ( Some ( Header :: Tag ( tag) ) ) ? {
169- ( false , raw) => return visitor. visit_u128 ( raw) ,
170- ( true , raw) => i128:: try_from ( raw) . map ( |x| x ^ !0 ) ,
171- } ;
189+ match tag {
190+ tag:: BIGPOS | tag:: BIGNEG => {
191+ let mut bytes = Vec :: new ( ) ;
192+ let result =
193+ match self . integer ( Some ( Header :: Tag ( tag) ) , true , |b| bytes. push ( b) ) ? {
194+ ( false , _) if !bytes. is_empty ( ) => {
195+ let access = crate :: tag:: TagAccess :: new (
196+ BytesDeserializer :: new ( & bytes) ,
197+ Some ( tag) ,
198+ ) ;
199+ return visitor. visit_enum ( access) ;
200+ }
201+ ( false , raw) => return visitor. visit_u128 ( raw) ,
202+ ( true , raw) => i128:: try_from ( raw) . map ( |x| x ^ !0 ) ,
203+ } ;
172204
173205 match result {
174206 Ok ( x) => visitor. visit_i128 ( x) ,
@@ -238,7 +270,7 @@ where
238270 }
239271
240272 fn deserialize_i64 < V : de:: Visitor < ' de > > ( self , visitor : V ) -> Result < V :: Value , Self :: Error > {
241- let result = match self . integer ( None ) ? {
273+ let result = match self . integer ( None , false , noop ) ? {
242274 ( false , raw) => i64:: try_from ( raw) ,
243275 ( true , raw) => i64:: try_from ( raw) . map ( |x| x ^ !0 ) ,
244276 } ;
@@ -250,7 +282,7 @@ where
250282 }
251283
252284 fn deserialize_i128 < V : de:: Visitor < ' de > > ( self , visitor : V ) -> Result < V :: Value , Self :: Error > {
253- let result = match self . integer ( None ) ? {
285+ let result = match self . integer ( None , false , noop ) ? {
254286 ( false , raw) => i128:: try_from ( raw) ,
255287 ( true , raw) => i128:: try_from ( raw) . map ( |x| x ^ !0 ) ,
256288 } ;
@@ -274,7 +306,7 @@ where
274306 }
275307
276308 fn deserialize_u64 < V : de:: Visitor < ' de > > ( self , visitor : V ) -> Result < V :: Value , Self :: Error > {
277- let result = match self . integer ( None ) ? {
309+ let result = match self . integer ( None , false , noop ) ? {
278310 ( false , raw) => u64:: try_from ( raw) ,
279311 ( true , ..) => return Err ( de:: Error :: custom ( "unexpected negative integer" ) ) ,
280312 } ;
@@ -286,7 +318,7 @@ where
286318 }
287319
288320 fn deserialize_u128 < V : de:: Visitor < ' de > > ( self , visitor : V ) -> Result < V :: Value , Self :: Error > {
289- match self . integer ( None ) ? {
321+ match self . integer ( None , false , noop ) ? {
290322 ( false , raw) => visitor. visit_u128 ( raw) ,
291323 ( true , ..) => Err ( de:: Error :: custom ( "unexpected negative integer" ) ) ,
292324 }
0 commit comments