13
13
* limitations under the License.
14
14
*/
15
15
16
+ use crate :: binary_reader:: BinaryReaderErrorKind ;
16
17
use crate :: limits:: {
17
18
MAX_WASM_FUNCTION_PARAMS , MAX_WASM_FUNCTION_RETURNS , MAX_WASM_STRUCT_FIELDS ,
18
19
MAX_WASM_SUPERTYPES , MAX_WASM_TYPES ,
@@ -1709,79 +1710,65 @@ impl<'a> FromReader<'a> for ValType {
1709
1710
reader. read_u8 ( ) ?;
1710
1711
Ok ( ValType :: V128 )
1711
1712
}
1712
- 0x70 | 0x6F | 0x65 | 0x64 | 0x63 | 0x6E | 0x71 | 0x72 | 0x73 | 0x74 | 0x75 | 0x6D
1713
- | 0x6B | 0x6A | 0x6C | 0x69 | 0x68 => Ok ( ValType :: Ref ( reader. read ( ) ?) ) ,
1714
- _ => bail ! ( reader. original_position( ) , "invalid value type" ) ,
1713
+ _ => {
1714
+ // Reclassify errors as invalid value types here because
1715
+ // that's the "root" of what was being parsed rather than
1716
+ // reference types.
1717
+ let refty = reader. read ( ) . map_err ( |mut e| {
1718
+ if let BinaryReaderErrorKind :: Invalid = e. kind ( ) {
1719
+ e. set_message ( "invalid value type" ) ;
1720
+ }
1721
+ e
1722
+ } ) ?;
1723
+ Ok ( ValType :: Ref ( refty) )
1724
+ }
1715
1725
}
1716
1726
}
1717
1727
}
1718
1728
1719
1729
impl < ' a > FromReader < ' a > for RefType {
1720
1730
fn from_reader ( reader : & mut BinaryReader < ' a > ) -> Result < Self > {
1721
- let absheapty = |byte, pos| match byte {
1722
- 0x70 => Ok ( RefType :: FUNC . nullable ( ) ) ,
1723
- 0x6F => Ok ( RefType :: EXTERN . nullable ( ) ) ,
1724
- 0x6E => Ok ( RefType :: ANY . nullable ( ) ) ,
1725
- 0x71 => Ok ( RefType :: NONE . nullable ( ) ) ,
1726
- 0x72 => Ok ( RefType :: NOEXTERN . nullable ( ) ) ,
1727
- 0x73 => Ok ( RefType :: NOFUNC . nullable ( ) ) ,
1728
- 0x6D => Ok ( RefType :: EQ . nullable ( ) ) ,
1729
- 0x6B => Ok ( RefType :: STRUCT . nullable ( ) ) ,
1730
- 0x6A => Ok ( RefType :: ARRAY . nullable ( ) ) ,
1731
- 0x6C => Ok ( RefType :: I31 . nullable ( ) ) ,
1732
- 0x69 => Ok ( RefType :: EXN . nullable ( ) ) ,
1733
- 0x74 => Ok ( RefType :: NOEXN . nullable ( ) ) ,
1734
- 0x68 => Ok ( RefType :: CONT . nullable ( ) ) ,
1735
- 0x75 => Ok ( RefType :: NOCONT . nullable ( ) ) ,
1736
- _ => bail ! ( pos, "invalid abstract heap type" ) ,
1737
- } ;
1738
-
1739
1731
// NB: See `FromReader<'a> for ValType` for a table of how this
1740
1732
// interacts with other value encodings.
1741
- match reader. read ( ) ? {
1742
- byte @ ( 0x70 | 0x6F | 0x6E | 0x71 | 0x72 | 0x73 | 0x6D | 0x6B | 0x6A | 0x6C | 0x69
1743
- | 0x74 ) => {
1744
- let pos = reader. original_position ( ) ;
1745
- absheapty ( byte, pos)
1746
- }
1747
- 0x65 => {
1748
- let byte = reader. read ( ) ?;
1749
- let pos = reader. original_position ( ) ;
1750
- Ok ( absheapty ( byte, pos) ?. shared ( ) . expect ( "must be abstract" ) )
1751
- }
1752
- byte @ ( 0x63 | 0x64 ) => {
1753
- let nullable = byte == 0x63 ;
1754
- let pos = reader. original_position ( ) ;
1733
+ let pos = reader. original_position ( ) ;
1734
+ match reader. peek ( ) ? {
1735
+ 0x63 | 0x64 => {
1736
+ let nullable = reader. read_u8 ( ) ? == 0x63 ;
1755
1737
RefType :: new ( nullable, reader. read ( ) ?)
1756
1738
. ok_or_else ( || crate :: BinaryReaderError :: new ( "type index too large" , pos) )
1757
1739
}
1758
- _ => bail ! ( reader. original_position( ) , "malformed reference type" ) ,
1740
+ _ => {
1741
+ // Reclassify errors as invalid reference types here because
1742
+ // that's the "root" of what was being parsed rather than
1743
+ // heap types.
1744
+ let hty = reader. read ( ) . map_err ( |mut e| {
1745
+ if let BinaryReaderErrorKind :: Invalid = e. kind ( ) {
1746
+ e. set_message ( "malformed reference type" ) ;
1747
+ }
1748
+ e
1749
+ } ) ?;
1750
+ RefType :: new ( true , hty)
1751
+ . ok_or_else ( || crate :: BinaryReaderError :: new ( "type index too large" , pos) )
1752
+ }
1759
1753
}
1760
1754
}
1761
1755
}
1762
1756
1763
1757
impl < ' a > FromReader < ' a > for HeapType {
1764
1758
fn from_reader ( reader : & mut BinaryReader < ' a > ) -> Result < Self > {
1765
- // NB: See `FromReader<'a> for ValType` for a table of how this
1766
- // interacts with other value encodings.
1767
- match reader. peek ( ) ? {
1768
- 0x65 => {
1769
- reader. read_u8 ( ) ?;
1770
- let ty = reader. read ( ) ?;
1771
- Ok ( HeapType :: Abstract { shared : true , ty } )
1772
- }
1773
- 0x70 | 0x6F | 0x6E | 0x71 | 0x72 | 0x73 | 0x6D | 0x6B | 0x6A | 0x6C | 0x68 | 0x69
1774
- | 0x74 | 0x75 => {
1775
- let ty = reader. read ( ) ?;
1776
- Ok ( HeapType :: Abstract { shared : false , ty } )
1777
- }
1778
- _ => {
1779
- let idx = match u32:: try_from ( reader. read_var_s33 ( ) ?) {
1780
- Ok ( idx) => idx,
1781
- Err ( _) => {
1782
- bail ! ( reader. original_position( ) , "invalid indexed ref heap type" ) ;
1783
- }
1784
- } ;
1759
+ // Unconditionally read a `s33` value. If it's positive then that means
1760
+ // it fits in a `u32` meaning that this is a valid concrete type index.
1761
+ // If it's negative, however, then it must be an abstract heap type due
1762
+ // to how non-concrete types are encoded (see `ValType` comments). In
1763
+ // that situation "rewind" the reader and go back to the original bytes
1764
+ // to parse them as an abstract heap type.
1765
+ let mut clone = reader. clone ( ) ;
1766
+ let s33 = clone. read_var_s33 ( ) ?;
1767
+ match u32:: try_from ( s33) {
1768
+ Ok ( idx) => {
1769
+ // Be sure to update `reader` with the state after the s33 was
1770
+ // read.
1771
+ * reader = clone;
1785
1772
let idx = PackedIndex :: from_module_index ( idx) . ok_or_else ( || {
1786
1773
BinaryReaderError :: new (
1787
1774
"type index greater than implementation limits" ,
@@ -1790,6 +1777,25 @@ impl<'a> FromReader<'a> for HeapType {
1790
1777
} ) ?;
1791
1778
Ok ( HeapType :: Concrete ( idx. unpack ( ) ) )
1792
1779
}
1780
+ Err ( _) => match reader. peek ( ) ? {
1781
+ 0x65 => {
1782
+ reader. read_u8 ( ) ?;
1783
+ let ty = reader. read ( ) ?;
1784
+ Ok ( HeapType :: Abstract { shared : true , ty } )
1785
+ }
1786
+ _ => {
1787
+ // Reclassify errors as "invalid heap type" here because
1788
+ // that's the "root" of what was being parsed rather than
1789
+ // abstract heap types.
1790
+ let ty = reader. read ( ) . map_err ( |mut e| {
1791
+ if let BinaryReaderErrorKind :: Invalid = e. kind ( ) {
1792
+ e. set_message ( "invalid heap type" ) ;
1793
+ }
1794
+ e
1795
+ } ) ?;
1796
+ Ok ( HeapType :: Abstract { shared : false , ty } )
1797
+ }
1798
+ } ,
1793
1799
}
1794
1800
}
1795
1801
}
@@ -1813,7 +1819,10 @@ impl<'a> FromReader<'a> for AbstractHeapType {
1813
1819
0x68 => Ok ( Cont ) ,
1814
1820
0x75 => Ok ( NoCont ) ,
1815
1821
_ => {
1816
- bail ! ( reader. original_position( ) , "invalid abstract heap type" ) ;
1822
+ return Err ( BinaryReaderError :: invalid (
1823
+ "invalid abstract heap type" ,
1824
+ reader. original_position ( ) - 1 ,
1825
+ ) )
1817
1826
}
1818
1827
}
1819
1828
}
0 commit comments