1
- // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
@@ -115,6 +115,7 @@ pub enum EbmlEncoderTag {
115
115
#[ derive( Debug ) ]
116
116
pub enum Error {
117
117
IntTooBig ( uint ) ,
118
+ InvalidTag ( uint ) ,
118
119
Expected ( String ) ,
119
120
IoError ( std:: old_io:: IoError ) ,
120
121
ApplicationError ( String )
@@ -142,7 +143,7 @@ pub mod reader {
142
143
EsMapLen , EsMapKey , EsEnumVid , EsU64 , EsU32 , EsU16 , EsU8 , EsInt , EsI64 ,
143
144
EsI32 , EsI16 , EsI8 , EsBool , EsF64 , EsF32 , EsChar , EsStr , EsMapVal ,
144
145
EsEnumBody , EsUint , EsOpaque , EsLabel , EbmlEncoderTag , Doc , TaggedDoc ,
145
- Error , IntTooBig , Expected } ;
146
+ Error , IntTooBig , InvalidTag , Expected } ;
146
147
147
148
pub type DecodeResult < T > = Result < T , Error > ;
148
149
// rbml reading
@@ -165,6 +166,18 @@ pub mod reader {
165
166
pub next : uint
166
167
}
167
168
169
+ pub fn tag_at ( data : & [ u8 ] , start : uint ) -> DecodeResult < Res > {
170
+ let v = data[ start] as uint ;
171
+ if v < 0xf0 {
172
+ Ok ( Res { val : v, next : start + 1 } )
173
+ } else if v > 0xf0 {
174
+ Ok ( Res { val : ( ( v & 0xf ) << 8 ) | data[ start + 1 ] as uint , next : start + 2 } )
175
+ } else {
176
+ // every tag starting with byte 0xf0 is an overlong form, which is prohibited.
177
+ Err ( InvalidTag ( v) )
178
+ }
179
+ }
180
+
168
181
#[ inline( never) ]
169
182
fn vuint_at_slow ( data : & [ u8 ] , start : uint ) -> DecodeResult < Res > {
170
183
let a = data[ start] ;
@@ -238,7 +251,7 @@ pub mod reader {
238
251
}
239
252
240
253
pub fn doc_at < ' a > ( data : & ' a [ u8 ] , start : uint ) -> DecodeResult < TaggedDoc < ' a > > {
241
- let elt_tag = try!( vuint_at ( data, start) ) ;
254
+ let elt_tag = try!( tag_at ( data, start) ) ;
242
255
let elt_size = try!( vuint_at ( data, elt_tag. next ) ) ;
243
256
let end = elt_size. next + elt_size. val ;
244
257
Ok ( TaggedDoc {
@@ -250,7 +263,7 @@ pub mod reader {
250
263
pub fn maybe_get_doc < ' a > ( d : Doc < ' a > , tg : uint ) -> Option < Doc < ' a > > {
251
264
let mut pos = d. start ;
252
265
while pos < d. end {
253
- let elt_tag = try_or ! ( vuint_at ( d. data, pos) , None ) ;
266
+ let elt_tag = try_or ! ( tag_at ( d. data, pos) , None ) ;
254
267
let elt_size = try_or ! ( vuint_at( d. data, elt_tag. next) , None ) ;
255
268
pos = elt_size. next + elt_size. val ;
256
269
if elt_tag. val == tg {
@@ -276,7 +289,7 @@ pub mod reader {
276
289
{
277
290
let mut pos = d. start ;
278
291
while pos < d. end {
279
- let elt_tag = try_or ! ( vuint_at ( d. data, pos) , false ) ;
292
+ let elt_tag = try_or ! ( tag_at ( d. data, pos) , false ) ;
280
293
let elt_size = try_or ! ( vuint_at( d. data, elt_tag. next) , false ) ;
281
294
pos = elt_size. next + elt_size. val ;
282
295
let doc = Doc { data : d. data , start : elt_size. next , end : pos } ;
@@ -292,7 +305,7 @@ pub mod reader {
292
305
{
293
306
let mut pos = d. start ;
294
307
while pos < d. end {
295
- let elt_tag = try_or ! ( vuint_at ( d. data, pos) , false ) ;
308
+ let elt_tag = try_or ! ( tag_at ( d. data, pos) , false ) ;
296
309
let elt_size = try_or ! ( vuint_at( d. data, elt_tag. next) , false ) ;
297
310
pos = elt_size. next + elt_size. val ;
298
311
if elt_tag. val == tg {
@@ -718,6 +731,20 @@ pub mod writer {
718
731
size_positions : Vec < uint > ,
719
732
}
720
733
734
+ fn write_tag < W : Writer > ( w : & mut W , n : uint ) -> EncodeResult {
735
+ if n < 0xf0 {
736
+ w. write_all ( & [ n as u8 ] )
737
+ } else if 0x100 <= n && n < 0x1000 {
738
+ w. write_all ( & [ 0xf0 | ( n >> 8 ) as u8 , n as u8 ] )
739
+ } else {
740
+ Err ( old_io:: IoError {
741
+ kind : old_io:: OtherIoError ,
742
+ desc : "invalid tag" ,
743
+ detail : Some ( format ! ( "{}" , n) )
744
+ } )
745
+ }
746
+ }
747
+
721
748
fn write_sized_vuint < W : Writer > ( w : & mut W , n : uint , size : uint ) -> EncodeResult {
722
749
match size {
723
750
1 => w. write_all ( & [ 0x80u8 | ( n as u8 ) ] ) ,
@@ -766,7 +793,7 @@ pub mod writer {
766
793
debug ! ( "Start tag {:?}" , tag_id) ;
767
794
768
795
// Write the enum ID:
769
- try!( write_vuint ( self . writer , tag_id) ) ;
796
+ try!( write_tag ( self . writer , tag_id) ) ;
770
797
771
798
// Write a placeholder four-byte size.
772
799
self . size_positions . push ( try!( self . writer . tell ( ) ) as uint ) ;
@@ -795,7 +822,7 @@ pub mod writer {
795
822
}
796
823
797
824
pub fn wr_tagged_bytes ( & mut self , tag_id : uint , b : & [ u8 ] ) -> EncodeResult {
798
- try!( write_vuint ( self . writer , tag_id) ) ;
825
+ try!( write_tag ( self . writer , tag_id) ) ;
799
826
try!( write_vuint ( self . writer , b. len ( ) ) ) ;
800
827
self . writer . write_all ( b)
801
828
}
0 commit comments