Esempio n. 1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceStream"></param>
        protected override void Parse(BinaryReader sourceStream)
        {
            _DebugType = AVM2.Static.VariableLengthInteger.ReadU8(sourceStream);
            _Index = AVM2.Static.VariableLengthInteger.ReadU30(sourceStream);
            _Reg = AVM2.Static.VariableLengthInteger.ReadU8(sourceStream);
            _Extra = AVM2.Static.VariableLengthInteger.ReadU30(sourceStream);

            if (0 != _Extra)
            {
                // Of course, Adobe Flash CS4 makes use of this field
                AbcFormatException abcfe = new AbcFormatException("Extra (reserved) field in Debug instruction used: 0x" + _Extra.ToString("X"));
                Log.Warn(this, abcfe);
                //throw abcfe;
                //Log.Warn(this, "Extra (reserved) field in Debug instruction used: 0x" + _Extra.ToString("X"));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse( Stream source )
        {
            _Ns = new List<uint>();

            UInt32 setMemberCount = VariableLengthInteger.ReadU30( source );

            for ( uint i = 0; i < setMemberCount; i++ )
            {
                UInt32 entry = VariableLengthInteger.ReadU30( source );

                if ( 0 == entry )
                {
                    AbcFormatException fe = new AbcFormatException( "Namespace set entry is 0" );
                   Log.Error(this,  fe );
                    throw fe;
                }

                _Ns.Add( entry );
            }
        }
Esempio n. 3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse(Stream source)
        {
            // UNTESTED
            _Name = VariableLengthInteger.ReadU30(source);

            if (0 == _Name)
            {
                AbcFormatException fe = new AbcFormatException("Metadata_info with Name == 0");
                Log.Error(this, fe);
                throw fe;
            }

            UInt32 itemCount = VariableLengthInteger.ReadU30(source);
            _ItemInfo = new List<Metadata_item_info>();
            for (uint i = 0; i < itemCount; i++)
            {
                Metadata_item_info mdii = new Metadata_item_info();
                mdii.Parse(source);
                _ItemInfo.Add(mdii);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse( Stream source )
        {
            //Log.Debug(this, "Offset : " + source.Position);
            _Name = VariableLengthInteger.ReadU30( source );
            _Supername = VariableLengthInteger.ReadU30( source );

            byte flags = VariableLengthInteger.ReadU8( source );
            _FlagClassSealed = ( ( flags & 0x01 ) != 0 );
            _FlagClassFinal = ( ( flags & 0x02 ) != 0 );
            _FlagClassInterface = ( ( flags & 0x04 ) != 0 );
            _FlagClassProtectedNs = ( ( flags & 0x08 ) != 0 );

            if ( ( flags & 0xF0 ) != 0 )
            {
                AbcFormatException fe = new AbcFormatException( "Reserved flags used in Instance_Info" );
               Log.Error(this,  fe );
                throw fe;
            }

            if ( _FlagClassProtectedNs )
            {
                _ProtectedNs = VariableLengthInteger.ReadU30( source );
            }

            UInt32 interfaceCount = VariableLengthInteger.ReadU30( source );
            _Interface = new List<UInt32>( (int)interfaceCount );
            for ( uint i = 0; i < interfaceCount; i++ )
            {
                UInt32 interf = VariableLengthInteger.ReadU30( source );

                if ( 0 == interf )
                {
                    AbcFormatException fe = new AbcFormatException( "Instance_info interface index is 0" );
                   Log.Error(this,  fe );
                    throw fe;
                }

                _Interface.Add( interf );
            }

            _Iinit = VariableLengthInteger.ReadU30( source );

            UInt32 traitCount = VariableLengthInteger.ReadU30( source );
            _Trait = new List<Traits_info>( ( int )traitCount );
            for ( uint i = 0; i < traitCount; i++ )
            {
                Traits_info ti = new Traits_info();
                ti.Parse( source );
                _Trait.Add( ti );
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Parses this object out of a stream
        /// </summary>
        /// <param name="source">The source stream.</param>
        public void Parse(Stream source)
        {
            long startPos = source.Position;

            _MinorVersion = VariableLengthInteger.ReadU16(source);
            _MajorVersion = VariableLengthInteger.ReadU16(source);

            String s1 = String.Format("ABC Version {0:d}.{1:d}", _MajorVersion, _MinorVersion);
            Log.Debug(this, s1);
            if (_MajorVersion != 46)
            {
                AbcFormatException fe = new AbcFormatException("ABC major version mismatch: " + _MajorVersion.ToString("d") + " (expected: 46)");
                Log.Error(this, fe);
                throw fe;
            }
            if (_MinorVersion != 16)
            {
                String s2 = String.Format("ABC minor version {d:0} is not equal to expected version 16", _MinorVersion);
                Log.Warn(this, s2);
            }

            // (1) ConstantPool
            String s3 = String.Format("0x{0:X08}: ConstantPool", source.Position - startPos);
            Log.Debug(this, s3);
            _ConstantPool = new Cpool_info();
            _ConstantPool.Parse(source);
            Log.Debug(this, _ConstantPool.ToString(this));

            // (2) Method_Info
            String s4 = String.Format("0x{0:X08}: Method_info", source.Position - startPos);
            Log.Debug(this, s4);
            UInt32 methodCount = VariableLengthInteger.ReadU30(source);
            _Method = new List<Method_info>();
            for (uint i = 0; i < methodCount; i++)
            {
                Method_info mi = new Method_info();
                mi.Parse(source);
                _Method.Add(mi);
            }
            String s5 = String.Format("{0:d} Methods", _Method.Count);
            Log.Debug(this, s5);

            // (3) Metadata
            String s6 = String.Format("0x{0:X08}: Metadata", source.Position - startPos);
               // //Log.Debug(this, s6);
            UInt32 metadataInfoCount = VariableLengthInteger.ReadU30(source);
            _Metadata = new List<Metadata_info>();
            for (uint i = 0; i < metadataInfoCount; i++)
            {
                Metadata_info mdi = new Metadata_info();
                mdi.Parse(source);
                _Metadata.Add(mdi);
            }

            String s7 = String.Format("{0:d} Metadata entries", _Metadata.Count);
            Log.Debug(this, s7);

            // (4) Instance_info
            String s8 = String.Format("0x{0:X08}: Instance_info", source.Position - startPos);
            Log.Debug(this, s8);
            UInt32 classCount = VariableLengthInteger.ReadU30(source);
            _Instance = new List<Instance_info>((int)classCount);
            for (uint i = 0; i < classCount; i++)
            {
                Instance_info ii = new Instance_info();
                ii.Parse(source);
                _Instance.Add(ii);
            }
            String s9 = String.Format("{0:d} Instances", _Instance.Count);
            Log.Debug(this, s9);

            // (5) Class_info
            String s10 = String.Format("0x{0:X08}: Class_info", source.Position - startPos);
            Log.Debug(this, s10);
            _Class = new List<Class_info>((int)classCount);
            for (uint i = 0; i < classCount; i++)
            {
                Class_info ci = new Class_info();
                ci.Parse(source);
                _Class.Add(ci);
            }
            String s11 = String.Format("{0:d} Classes", _Class.Count);
            Log.Debug(this, s11);

            // (6) Script_info
            String s12 = String.Format("0x{0:X08}: Script_info", source.Position - startPos);
            Log.Debug(this, s12);

            UInt32 scriptCount = VariableLengthInteger.ReadU30(source);
            _Script = new List<Script_info>((int)scriptCount);
            for (uint i = 0; i < scriptCount; i++)
            {
                Script_info si = new Script_info();
                si.Parse(source);
                _Script.Add(si);
            }
            String s13 = String.Format("{0:d} Scripts", _Script.Count);
            Log.Debug(this, s13);

            // (7) Method_body_info
            String s14 = String.Format("0x{0:X08}: MethodBody_info", source.Position - startPos);
            Log.Debug(this, s14);

            UInt32 methodBodyCount = VariableLengthInteger.ReadU30(source);

            if (methodBodyCount > methodCount)
            {
                String s15 = String.Format("More method bodies ({0:d}) than methods ({1:d})!", methodBodyCount, methodCount);
                Log.Warn(this, s15);
            }

            _MethodBody = new Dictionary<UInt32, Method_body_info>((int)methodBodyCount);

            for (uint i = 0; i < methodBodyCount; i++)
            {
                Method_body_info mbi = new Method_body_info();
                mbi.Parse(source);
                _MethodBody.Add(mbi.Method, mbi);
            }

            String s16 = String.Format("{0:d} Method bodies", _MethodBody.Count);
            Log.Debug(this, s16);

            if (source.Position != source.Length)
            {
                AbcFormatException fe = new AbcFormatException(
                    "Trailing garbage after reading ABC file: at offset 0x" +
                    source.Position.ToString("X08") + " of 0x" + source.Length.ToString("X08"));
                Log.Error(this, fe);
                throw fe;
            }
            String s17 = String.Format("0x{0:X08}: End", source.Position - startPos);
            Log.Debug(this, s17);
            Log.Debug(this, "Done reading ABC");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="kindId"></param>
        public AbstractMultinameEntry( byte kindId )
        {
            if ( !Enum.IsDefined( typeof( MultinameType ), kindId ) )
            {
                AbcFormatException fe = new AbcFormatException( "Invalid Multiname entry kind " + kindId.ToString( "X2" ) );
                Log.Error(this,  fe );
                throw ( fe );
            }

            _Type = ( MultinameType )kindId;
        }
Esempio n. 7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private AbstractMultinameEntry MultinameEntryFactory(Stream source)
        {
            BinaryReader br = new BinaryReader(source);
            byte kind = br.ReadByte();

            if (!Enum.IsDefined(typeof(MultinameType), kind))
            {
                AbcFormatException fe = new AbcFormatException("Invalid multiname type 0x" + kind.ToString("X2"));
                Log.Error(this, fe);
                throw fe;
            }

            AbstractMultinameEntry product = null;

            switch ((MultinameType)kind)
            {
                case MultinameType.QName:
                case MultinameType.QNameA:
                    product = new MultinameQname(kind);
                    product.Namespace = VariableLengthInteger.ReadU30(source);
                    product.NameIndex = VariableLengthInteger.ReadU30(source);
                    break;

                case MultinameType.RTQName:
                case MultinameType.RTQNameA:
                    product = new MultinameRTQname(kind);
                    product.NameIndex = VariableLengthInteger.ReadU30(source);
                    break;

                case MultinameType.RTQNameL:
                case MultinameType.RTQNameLA:
                    product = new MultinameRTQnameL(kind);
                    break;

                case MultinameType.Multiname:
                case MultinameType.MultinameA:
                    product = new MultinameMultiname(kind);
                    product.NameIndex = VariableLengthInteger.ReadU30(source);
                    product.NsSet = VariableLengthInteger.ReadU30(source);
                    break;

                case MultinameType.MultinameL:
                case MultinameType.MultinameLA:
                    product = new MultinameMultinameL(kind);
                    product.NsSet = VariableLengthInteger.ReadU30(source);
                    break;

                case MultinameType.Multiname0x1D:
                    product = new Multiname0x1D(kind);
                    ((Multiname0x1D)product).Parse(source);
                    break;

                default:
                    Exception e = new Exception("Internal error, Multiname type " + kind.ToString("X2") + " reached end of factory!!");
                    Log.Error(this, e);
                    throw e;
            }

            return product;
        }
Esempio n. 8
0
        /// <summary>
        /// Parses this object out of a stream
        /// </summary>
        /// <param name="source">The input stream</param>
        public void Parse(Stream source)
        {
            // "The “0” entry of the integer array is not present in the abcFile; it
            // represents the zero value for the purposes of providing values for optional
            // parameters and field initialization."
            //
            UInt32 integerCount = VariableLengthInteger.ReadU30(source);
            // Note: integerCount == 0 seems to be valid
            Integers = new List<Int32>((int)integerCount);
            Integers.Add((int)0);
            for (uint i = 1; i < integerCount; i++)
            {
                Integers.Add(VariableLengthInteger.ReadS32(source));
            }

            //
            // "The “0” entry of the uinteger array is not present in the abcFile; it
            // represents the zero value for the purposes of providing values for optional
            // parameters and field initialization."
            //
            UInt32 uIntegerCount = VariableLengthInteger.ReadU30(source);
            // Note: uIntegerCount == 0 seems to be valid
            UIntegers = new List<UInt32>((int)uIntegerCount);
            UIntegers.Add((UInt32)0);
            for (uint i = 1; i < uIntegerCount; i++)
            {
                UIntegers.Add(VariableLengthInteger.ReadU32(source));
            }

            //
            // Double
            //
            UInt32 doubleCount = VariableLengthInteger.ReadU30(source);
            //Note: doubleCount == 0 seems to be valid too
            Doubles = new List<double>();
            Doubles.Add(Double.NaN);
            BinaryReader br = new BinaryReader(source);
            for (uint i = 1; i < doubleCount; i++)
            {
                Doubles.Add(br.ReadDouble());
            }

            //
            // String pool
            //
            UInt32 stringCount = VariableLengthInteger.ReadU30(source);
            //
            // "The value of string_count is the number of entries in the string array, plus one."
            //
            if (1 > stringCount)
            {
                AbcFormatException fe = new AbcFormatException("Constant pool string count < 1");
                Log.Error(this, fe);
                throw fe;
            }
            stringCount--;

            Strings = new List<string>();
            // Money quote: "Entry “0” of the string array is not present in the abcFile; it
            // represents the empty string in most contexts but is also used to represent the
            // “any” name in others (known as “*” in ActionScript)."
            Strings.Add("");
            // WARNING: Adobe Flash CS4 often includes an empty string at _String[1] (the first
            //          actually present in the file), _despite_ the fact that _String[0] is
            //          defined to be there for that purpose.
            for (uint i = 0; i < stringCount; i++)
            {
                Strings.Add(StringInfo.Read(source));
            }

            //
            // Namespaces
            //

            UInt32 namespaceCount = VariableLengthInteger.ReadU30(source);
            //
            // "The value of namespace_count is the number of entries in
            // the namespace array, plus one."
            //
            if (1 > namespaceCount)
            {
                /*
                AbcFormatException fe = new AbcFormatException( "Name space count < 1" );
               Log.Error(this,  fe );
                throw fe;
                 */
                Log.Warn(this, "Namespace count < 1");
                namespaceCount = 1;
            }
            namespaceCount--;

            Namespaces = new List<Namespace_info>();
            Namespaces.Add(new Namespace_info());
            for (uint i = 0; i < namespaceCount; i++)
            {
                Namespace_info nsi = new Namespace_info();
                nsi.Parse(source);
                Namespaces.Add(nsi);
            }

            //
            // NS Set
            //

            UInt32 nsSetCount = VariableLengthInteger.ReadU30(source);
            // another "plus one" case
            if (1 > nsSetCount)
            {
                /*
                AbcFormatException fe = new AbcFormatException( "Namespace set count < 1" );
               Log.Error(this,  fe );
                throw fe;
                 */
                Log.Warn(this, "NsSetCount < 1");
                nsSetCount = 1;
            }
            nsSetCount--;

            NsSets = new List<Ns_set_info>();
            NsSets.Add(new Ns_set_info()); // dummy entry for array[0] not in file
            for (uint i = 0; i < nsSetCount; i++)
            {
                Ns_set_info nssi = new Ns_set_info();
                nssi.Parse(source);
                NsSets.Add(nssi);
            }

            //
            // Multinames
            //
            UInt32 multinameCount = VariableLengthInteger.ReadU30(source);
            // another "plus one" case, doh!
            if (1 > multinameCount)
            {
                /*
                AbcFormatException fe = new AbcFormatException( "Multiname count < 1" );
               Log.Error(this,  fe );
                throw fe;
                 */
                Log.Warn(this, "Multiname count < 1");
                multinameCount = 1;
            }
            multinameCount--;

            Multinames = new List<AbstractMultinameEntry>();
            Multinames.Add(new MultinameRTQnameL((byte)MultinameType.RTQNameL)); // dummy entry for array[0] not in file
            for (uint i = 0; i < multinameCount; i++)
            {
                AbstractMultinameEntry entry = MultinameEntryFactory(source);
                Multinames.Add(entry);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse(Stream source)
        {
            Log.Debug(this, "Offset : " + source.Position);
            _Value = VariableLengthInteger.ReadU30(source);
            byte type = VariableLengthInteger.ReadU8(source);

            if (!Enum.IsDefined(typeof(OptionType), type))
            {
                AbcFormatException fe = new AbcFormatException("Option_detail entry type 0x" + type.ToString("X02") + " is invalid");
                Log.Error(this, fe);
                throw fe;
            }

            _Type = (OptionType)type;
        }
Esempio n. 10
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private TraitsData_Slot ParseSlot(Stream source)
        {
            TraitsData_Slot s = new TraitsData_Slot();

            s.SlotID = VariableLengthInteger.ReadU30(source);
            s.TypeName = VariableLengthInteger.ReadU30(source);
            s.Vindex = VariableLengthInteger.ReadU30(source);

            if (0 != s.Vindex)
            {
                byte kind = VariableLengthInteger.ReadU8(source);
                if (!Enum.IsDefined(typeof(OptionType), kind))
                {
                    AbcFormatException fe = new AbcFormatException("TraitsData Slot invalid constant type 0x" + kind.ToString("X02"));
                    Log.Error(this, fe);
                    throw fe;
                }

                s.Vkind = (OptionType)kind;
            }
            else
            {
                s.Vkind = OptionType.TotallyInvalid;
            }

            return s;
        }
Esempio n. 11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse(Stream source)
        {
            // UNTESTED
            Name = VariableLengthInteger.ReadU30(source);

            byte kind = VariableLengthInteger.ReadU8(source);
            byte kindType = (byte)(kind & 0x0F);
            byte kindAttr = (byte)((kind & 0xF0) >> 4);

            if (!Enum.IsDefined(typeof(TraitType), kindType))
            {
                AbcFormatException fe = new AbcFormatException("Invalid Traits_info kind " + kindType.ToString("d"));
                Log.Error(this, fe);
                throw fe;
            }
            Type = (TraitType)kindType;

            //
            // "Any other combination of attribute with kind is ignored."
            // - so we test for it.
            //
            AttribFinal = (kindAttr & 0x01) != 0 ? true : false;
            AttribOverride = (kindAttr & 0x02) != 0 ? true : false;
            AttribMetadata = (kindAttr & 0x04) != 0 ? true : false;

            if (AttribFinal && (!((Type == TraitType.Trait_Getter) || (Type == TraitType.Trait_Setter) || (Type == TraitType.Trait_Method))))
            {
                AbcFormatException fe = new AbcFormatException("ATTR_Final with trait type " + Enum.GetName(typeof(TraitType), Type));
                Log.Error(this, fe);
                throw fe;
            }
            if (AttribOverride && (!((Type == TraitType.Trait_Getter) || (Type == TraitType.Trait_Setter) || (Type == TraitType.Trait_Method))))
            {
                AbcFormatException fe = new AbcFormatException("ATTR_Override with trait type " + Enum.GetName(typeof(TraitType), Type));
                Log.Error(this, fe);
                throw fe;
            }

            //
            // Just to point out how this works: only one of them
            // is going to be valid
            //
            switch (Type)
            {
                case TraitType.Trait_Const:
                case TraitType.Trait_Slot:
                    _Data_Slot = ParseSlot(source);
                    break;

                case TraitType.Trait_Class:
                    _Data_Class = ParseClass(source);
                    break;

                case TraitType.Trait_Function:
                    _Data_Function = ParseFunction(source);
                    break;

                case TraitType.Trait_Method:
                case TraitType.Trait_Getter:
                case TraitType.Trait_Setter:
                    _Data_Method = ParseMethod(source);
                    break;

                default:
                    Exception e = new Exception("Internal error: invalid _Type 0x" + Type.ToString("X02") + " reached end of switch");
                    Log.Error(this, e);
                    throw e;
            }

            if (AttribMetadata)
            {
                UInt32 metadataCount = VariableLengthInteger.ReadU30(source);
                _Metadata = new List<UInt32>((int)metadataCount);
                for (uint i = 0; i < metadataCount; i++)
                {
                    UInt32 metav = VariableLengthInteger.ReadU30(source);
                    _Metadata.Add(metav);
                }
            }
        }
Esempio n. 12
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse(Stream source)
        {
            BinaryReader br = new BinaryReader(source);
            byte kindId = br.ReadByte();

            if (!Enum.IsDefined(typeof(NamespaceKind), kindId))
            {
                AbcFormatException fe = new AbcFormatException("Namespace kind 0x" + kindId.ToString("X2") + " is undefined");
                Log.Error(this, fe);
                throw fe;
            }

            _Kind = (NamespaceKind)kindId;
            _Name = VariableLengthInteger.ReadU30(source);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private static UInt32 Read32( Stream source )
        {
            UInt32 value = 0;
            bool moreToFollow = false;
            int shift = 0;
            long pos = source.Position;
            UInt32 addition = 0;
            byte b = 0;
            byte[] buf = new byte[ 2 ];

            do
            {
                source.Read( buf, 0, 1 );
                b = buf[ 0 ];
                moreToFollow = ( 0 != ( b & 0x80 ) );
                addition = unchecked( ( UInt32 )( ( b & 0x7F ) << shift ) );
                value = value | addition ;
                shift = shift + 7;
            }
            while ( ( ( source.Position - pos ) < 5 ) && moreToFollow );

            if ( moreToFollow )
            {
                AbcFormatException fe = new AbcFormatException( "Variable length integer indicating > 5 bytes (stream pos: 0x"
                    + pos.ToString( "X08" ) + ", value=0x" + value.ToString( "X08" ) +
                    ", last byte=0x" + b.ToString( "X02" ) + ")" );
                Log.Error(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, fe);
                throw fe;
            }
            if ( ( ( source.Position - pos ) == 5 ) && ( ( b & 0xF0 ) != 0 ) )
            {
                AbcFormatException fe = new AbcFormatException( "Overlong variable length integer detected! (stream pos: 0x"
                    + pos.ToString( "X08" ) + ", value=0x" + value.ToString( "X08" ) +
                    ", last byte=0x" + b.ToString( "X02" ) + ")" );
                Log.Error(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, fe);
                throw fe;
            }

            return value;
        }
Esempio n. 14
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public void Parse(Stream source)
        {
            Log.Debug(this, "Offset : " + source.Position);
            UInt32 paramCount = VariableLengthInteger.ReadU30(source);
            ReturnType = VariableLengthInteger.ReadU30(source);

            ParamType = new List<UInt32>();
            for (uint i = 0; i < paramCount; i++)
            {
                ParamType.Add(VariableLengthInteger.ReadU30(source));
            }

            Name = VariableLengthInteger.ReadU30(source);

            byte flags = VariableLengthInteger.ReadU8(source);
            FlagNeedArguments = ((flags & 0x01) != 0);
            FlagActivation = ((flags & 0x02) != 0);
            FlagNeedRest = ((flags & 0x04) != 0);
            FlagHasOptional = ((flags & 0x08) != 0);
            FlagSetDxns = ((flags & 0x40) != 0);
            FlagHasParamNames = ((flags & 0x80) != 0);

            if ((flags & 0x30) != 0)
            {
                AbcFormatException fe = new AbcFormatException("Reserved flags used in Method_info");
                Log.Error(this, fe);
                throw fe;
            }

            if (FlagHasOptional)
            {
                UInt32 optionCount = VariableLengthInteger.ReadU30(source);

                if (optionCount > paramCount)
                {
                    AbcFormatException fe = new AbcFormatException("optionCount (" + optionCount.ToString("d") + ") > paramCount (" + paramCount.ToString("d") + ") in Method_info");
                    Log.Error(this, fe);
                    throw fe;
                }

                Option = new List<Option_detail>();
                for (uint i = 0; i < optionCount; i++)
                {
                    Option_detail od = new Option_detail();
                    od.Parse(source);
                    Option.Add(od);
                }
            }

            if (FlagHasParamNames)
            {
                ParamNames = new List<UInt32>();
                for (uint i = 0; i < paramCount; i++)
                {
                    ParamNames.Add(VariableLengthInteger.ReadU30(source));
                }
            }

            if (FlagNeedRest && FlagNeedArguments)
            {
                AbcFormatException fe = new AbcFormatException("NeedRest and NeedArguments both set");
                Log.Error(this, fe);
                throw fe;
            }
        }