A compressed Swf file
Inheritance: FwsFile
Esempio n. 1
0
 /// <summary>
 /// Writes the contents of this SwfFile instance to a stream. 
 /// Compression is used if configured.
 /// </summary>
 /// <param name="output">The destination stream to write to</param>
 public void Write(Stream output)
 {
     if (SwfFile.Configuration.WriteCompressed)
     {
         CwsFile cws = new CwsFile();
         cws.CompressionLevel = SwfFile.Configuration.WriteCompressionLevel;
         cws.WriteContent = new MemoryStream();
         WriteContent(cws.WriteContent);
         cws.Version = this.Version;
         // copy frame information from old FWS record
         cws.FrameHeader = FwsSource.FrameHeader;
         cws.Write(output);
     }
     else
     {
         FwsFile fws = new FwsFile();
         fws.WriteContent = new MemoryStream();
         WriteContent(fws.WriteContent);
         fws.Version = this.Version;
         // copy frame information from old FWS record
         fws.FrameHeader = FwsSource.FrameHeader;
         fws.Write(output);
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Parses a Swf file tag by tag
        /// </summary>
        /// <param name="input">The Swf file as stream</param>
        /// <returns>The next tag</returns>
        public Stream Read(Stream input)
        {
            CwsSource = new CwsFile();
            FwsSource = new FwsFile();
            List<Tag> tags = new List<Tag>();

            Stream next = CwsSource.Read(input);

            if (this.CwsSource.Compressed)
            {
                // Fire compressed event
                if (null != SwfFileCompressed)
                    SwfFileCompressed(this, new CompressedEventArgs(true));
            }

            next = FwsSource.Read(next);

            HeaderDeclaredLength = FwsSource.Length;

            #region Reading tags

            Tag t;
            int tagNumber = 1;
            uint tagsLenghts = (uint)next.Position;

            do
            {
                t = new Tag();

                try
                {
                    next = t.Read(next);
                    Log.Debug(this, "Reading Tag #" + tagNumber + "(" + t.TagTypeName +")" + " Offset : 0x" + t.Offset.ToString("X08") + " Total-Length : 0x" + t.LengthTotal.ToString("X08"));
                    // Fire TagReadCompleted, ReadProgressChanged, if protected SwfFileProtected  events
                    if (null != TagReadCompleted)
                        TagReadCompleted(this, new TagHandlerReadCompleteEventArgs(t.TagType));
                    if (null != this.ReadProgressChanged)
                        ReadProgressChanged(this, new SwfReadProgressChangedEventArgs(next.Length, next.Position));
                    if (null != SwfFileProtected && t.TagType == TagTypes.Protect)
                        SwfFileProtected(this, new ProtectionEventArgs(""));

                    // Knowing if the offset end is longer than header declared length is enough to verfiy
                    if (t.OffsetEnd > this.FwsSource.Length)
                    {
                        if ((SwfFile.Configuration.HandleHeadSizeIssue == HandleHeadSizeIssueBy.Fix) && t.OffsetEnd <= (ulong)input.Length)
                        {
                            this.FwsSource.Length = (uint)t.OffsetEnd;
                            Log.Warn(this, "Tag #" + tagNumber + " ends outside (0x" + t.OffsetEnd.ToString("X08") + ") the declared Swf content range 0x" + this.FwsSource.Length.ToString("X08") + " Fixing.");
                        }
                        if ((SwfFile.Configuration.HandleHeadSizeIssue == HandleHeadSizeIssueBy.Ignore) && t.OffsetEnd <= (ulong)input.Length)
                        {
                            Log.Warn(this, "Tag #" + tagNumber + " ends outside (0x" + t.OffsetEnd.ToString("X08") + ") the declared Swf content range 0x" + this.FwsSource.Length.ToString("X08") + " Ignoring.");
                        }
                        else
                        {
                            SwfFormatException e = new SwfFormatException("Tag #" + tagNumber + " ends outside (0x" + t.OffsetEnd.ToString("X08") + ") the declared Swf content range 0x" + this.FwsSource.Length.ToString("X08"));
                            Log.Error(this, e);
                            throw e;
                        }

                    }

                    tagsLenghts += t.LengthTotal;
                    tagNumber++;
                    tags.Add(t);
                }
                catch (IOException ioe)
                {
                    //This is the point where we find no end tag which basically means that a tag declared more memory than the stream actaully has
                    Log.Error(this, ioe);
                    SwfFormatException e = new SwfFormatException("Tag list is incomplete, does not end with an END tag or a tag length exceeds the file size.");
                    Log.Error(this, e);

                    throw e;
                }
            }
            while (t.TagType != TagTypes.End);

            #endregion

            #region Length checking

            // Performing length checks now
            //
            // 1. Do the length of all tags match the stream length
            if (tagsLenghts != next.Length)
            {

                    SwfFormatException e = new SwfFormatException("The length of tags (" + tagsLenghts.ToString() + ") does not match the stream size(" + next.Length.ToString() + ").");
                    Log.Error(this, e);
                    throw e;
            }

            // 2. Does the tags lengths do match the header declared length
            if (tagsLenghts != this.CwsSource.Length)
            {
                if (SwfFile.Configuration.HandleHeadSizeIssue == HandleHeadSizeIssueBy.Fix)
                {
                    this.CwsSource.Length = tagsLenghts;
                    Log.Warn(this, "The length of tags (" + tagsLenghts.ToString() + ") does not match the header declared length(" + this.CwsSource.Length.ToString() + "). Stream size will be fixed.");
                }
                else if (SwfFile.Configuration.HandleHeadSizeIssue == HandleHeadSizeIssueBy.RaiseError)
                {
                    SwfFormatException e = new SwfFormatException("The length of tags (" + tagsLenghts.ToString() + ") does not match the header declared length(" + this.CwsSource.Length.ToString() + ").");
                    Log.Error(this, e);
                    throw e;
                }
                else
                {
                    Log.Warn(this, "The length of tags (" + tagsLenghts.ToString() + ") does not match the header declared length(" + this.CwsSource.Length.ToString() + "). Stream size will be fixed.");
                }

            }

            // 3. If stream and header length match has already been checked in FWSFile class

            // 4. Has the stream been consumed completely
            if (next.Position != next.Length)
            {
                if (SwfFile.Configuration.HandleStreamOversize == HandleStreamOversizeBy.Resize)
                {
                    this.FixIncorrectStreamSize(next, next.Position);
                    Log.Warn(this, "Trailing garbage after END tag detected. Position 0x" + input.Position.ToString("X08") + ", Length " + input.Length.ToString() + ". Dumping Trailing Garbage.");
                }
                else if (SwfFile.Configuration.HandleStreamOversize == HandleStreamOversizeBy.Ignore)
                {
                    Log.Warn(this, "Trailing garbage after END tag detected. Position 0x" + input.Position.ToString("X08") + ", Length " + input.Length.ToString());
                }
                else
                {
                    SwfFormatException e = new SwfFormatException("Trailing garbage after END tag detected. Position 0x" + input.Position.ToString("X08") + ", Length " + input.Length.ToString());
                    Log.Error(this, e);
                }

            }

            #endregion

            #region Producing tag handlers

            TagHandlers = new List<Recurity.Swf.TagHandler.AbstractTagHandler>();
            for (int i = 0; i < tags.Count; i++)
            {
                //
                // Only accept tag types that are documented by Adobe
                //
                if (!tags[i].IsTagTypeKnown)
                {
                    string msg = "Tag type " + ((UInt16)tags[i].TagType).ToString("d") + " not known/documented";

                    if (SwfFile.Configuration.AllowUnknownTagTypes)
                    {
                        Log.Warn(this, msg);
                    }
                    else
                    {
                        SwfFormatException e = new SwfFormatException(msg);
                        Log.Error(this, e);
                        throw e;
                    }
                }

                //
                // The factory automatically fires .Read() on the produced class. Therefore,
                // we catch Exceptions here (Stream too short) and convert them to SwfFormatExceptions
                //
                try
                {
                    TagHandlers.Add(TagHandlerFactory.Create(tags[i], this, next));

                    // Fire TagProduced event
                    if (null != TagProduced)//If a handler is attached
                        TagProduced(this, new TagHandlerProducedEventArgs(tags[i].TagType, (Int64)tags.Count, (Int64)i));
                }
                catch (Exception e)
                {
                    SwfFormatException swfE = new SwfFormatException("Tag handler #" + i + " (" + tags[i].TagTypeName + ") failed parsing: " + e.Message);
                    throw swfE;
                }

                if (tags[i].TagType.Equals(TagTypes.ST_GLYPHNAMES) || tags[i].TagType.Equals(TagTypes.ST_REFLEX))
                {
                    //this.CWSSource._GeneratorSoftware = "SwfTools";
                }

                //
                // Verify the required Version of each Tag against the header declared
                // Version.
                // It may be considered to make failing this test fatal.
                //
                if (TagHandlers[i].MinimumVersionRequired > this.Version)
                {
                    Log.Warn(this, "Tag " + (tags[i].IsTagTypeKnown ? tags[i].TagTypeName : tags[i].TagType.ToString()) +
                        " requires Swf version " + TagHandlers[i].MinimumVersionRequired.ToString() +
                        ", header declares " + this.Version.ToString());
                }
            }
            #endregion

            return next;
        }