File tree Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Original file line number Diff line number Diff line change @@ -232,6 +232,27 @@ func Deserialize(data []byte) (Item, error) {
232
232
return item , nil
233
233
}
234
234
235
+ // DeserializeLimited returns Item deserialized from the given byte slice. limit
236
+ // restricts the maximum number of items deserialized item can contain (including
237
+ // itself). The default limit of MaxDeserialized is used if non-positive limit is
238
+ // specified.
239
+ func DeserializeLimited (data []byte , limit int ) (Item , error ) {
240
+ r := io .NewBinReaderFromBuf (data )
241
+ dc := deserContext {
242
+ BinReader : r ,
243
+ allowInvalid : false ,
244
+ limit : MaxDeserialized ,
245
+ }
246
+ if limit > 0 {
247
+ dc .limit = limit
248
+ }
249
+ item := dc .decodeBinary ()
250
+ if r .Err != nil {
251
+ return nil , r .Err
252
+ }
253
+ return item , nil
254
+ }
255
+
235
256
// DecodeBinary decodes the previously serialized Item from the given
236
257
// reader. It's similar to the io.Serializable's DecodeBinary() but implemented
237
258
// as a function because Item itself is an interface. Caveat: always check
@@ -283,7 +304,7 @@ func (r *deserContext) decodeBinary() Item {
283
304
return NewBigInteger (num )
284
305
case ArrayT , StructT :
285
306
size := int (r .ReadVarUint ())
286
- if size > MaxDeserialized {
307
+ if size > r . limit {
287
308
r .Err = errTooBigElements
288
309
return nil
289
310
}
@@ -298,7 +319,7 @@ func (r *deserContext) decodeBinary() Item {
298
319
return NewStruct (arr )
299
320
case MapT :
300
321
size := int (r .ReadVarUint ())
301
- if size > MaxDeserialized {
322
+ if size > r . limit / 2 {
302
323
r .Err = errTooBigElements
303
324
return nil
304
325
}
Original file line number Diff line number Diff line change @@ -209,6 +209,26 @@ func TestDeserializeTooManyElements(t *testing.T) {
209
209
require .True (t , errors .Is (err , ErrTooBig ), err )
210
210
}
211
211
212
+ func TestDeserializeLimited (t * testing.T ) {
213
+ customLimit := MaxDeserialized + 1
214
+ item := Make (0 )
215
+ for i := 0 ; i < customLimit - 1 ; i ++ { // 1 for zero inner element.
216
+ item = Make ([]Item {item })
217
+ }
218
+ data , err := Serialize (item )
219
+ require .NoError (t , err )
220
+ actual , err := DeserializeLimited (data , customLimit )
221
+ require .NoError (t , err )
222
+ require .Equal (t , item , actual )
223
+
224
+ item = Make ([]Item {item })
225
+ data , err = Serialize (item )
226
+ require .NoError (t , err )
227
+ _ , err = DeserializeLimited (data , customLimit )
228
+ require .Error (t , err )
229
+ require .True (t , errors .Is (err , ErrTooBig ), err )
230
+ }
231
+
212
232
func BenchmarkEncodeBinary (b * testing.B ) {
213
233
arr := getBigArray (15 )
214
234
You can’t perform that action at this time.
0 commit comments