Exemplo n.º 1
0
        /// <summary>
        /// Auxiliary function of IPersistFile.Load.
        /// </summary>
        /// <returns>
        /// <value>A MemoryStream of the package file or a FileStream if the file is too big.</value>
        /// </returns>
        /// <remarks>
        /// <para>Use this method to load a package file completely to a memory buffer.
        /// After loading the file we can close the file, thus we can release the file
        /// lock quickly. However, there is a size limit on the file. If the
        /// file is too big (greater than _maxMemoryStreamBuffer), we cannot allow
        /// this method to consume too much memory. So we simply return the fileStream.</para>
        /// <para>Mode, access and sharing have already been checked or adjusted and can be assumed
        /// to be compatible with the goal of reading from the file.</para>
        /// </remarks>
        private static Stream FileToStream(
            string filePath,
            FileMode fileMode,
            FileAccess fileAccess,
            FileShare fileSharing,
            long maxMemoryStream)
        {
            FileInfo fi        = new FileInfo(filePath);
            long     byteCount = fi.Length;
            Stream   s         = new FileStream(filePath, fileMode, fileAccess, fileSharing);

            // There is a size limit of the file that we allow to be uploaded to a
            // memory stream. If the file size is bigger than the limit, simply return the fileStream.
            if (byteCount < maxMemoryStream)
            {
                // unchecked cast is safe because _maxMemoryStreamBuffer is less than Int32.Max
                MemoryStream ms = new MemoryStream(unchecked ((int)byteCount));
                using (s)
                {
                    PackagingUtilities.CopyStream(s, ms, byteCount, 0x1000);
                }
                s = ms;
            }

            return(s);
        }
Exemplo n.º 2
0
            //------------------------------------------------------
            //
            //  Protected Methods
            //
            //------------------------------------------------------
            protected override void Dispose(bool disposing)
            {
                if (!_disposed)
                {
                    if (disposing)
                    {
                        // Non-standard pattern - call base.Dispose() first.
                        // This is required because the base class is a stream and we cannot
                        // delete the underlying file storage before it has a chance to close
                        // and release it.
                        base.Dispose(disposing);

                        if (_path != null)
                        {
                            PackagingUtilities.DeleteIsolatedStorageFile(_path);
                            _path = null;
                        }

                        //Decrement the count of files
                        _folder.DecRef();
                        _folder = null;
                        GC.SuppressFinalize(this);
                    }
                    _disposed = true;
                }
            }
        /// <summary>
        /// Parse the DigestMethod tag
        /// </summary>
        /// <param name="reader"></param>
        private static string ParseDigestAlgorithmTag(XmlReader reader)
        {
            // verify namespace and lack of attributes
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) > 1 ||
                String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0 ||
                reader.Depth != 3)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            // get the Algorithm attribute
            string hashAlgorithm = null;

            if (reader.HasAttributes)
            {
                hashAlgorithm = reader.GetAttribute(XTable.Get(XTable.ID.AlgorithmAttrName));
            }

            if (hashAlgorithm == null || hashAlgorithm.Length == 0)
            {
                throw new XmlException(SR.Get(SRID.UnsupportedHashAlgorithm));
            }

            return(hashAlgorithm);
        }
Exemplo n.º 4
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        /// <summary>
        /// Certificate to associate with this Certificate Part
        /// </summary>
        /// <value></value>
        /// <exception cref="FileFormatException">stream is too large</exception>
        internal X509Certificate2 GetCertificate()
        {
            // lazy init
            if (_certificate == null)
            {
                // obtain from the part
                using (Stream s = _part.GetStream())
                {
                    if (s.Length > 0)
                    {
                        // throw if stream is beyond any reasonable length
                        if (s.Length > _maximumCertificateStreamLength)
                        {
                            throw new FileFormatException(SR.CorruptedData);
                        }

                        // X509Certificate constructor desires a byte array
                        Byte[] byteArray = new Byte[s.Length];
                        PackagingUtilities.ReliableRead(s, byteArray, 0, (int)s.Length);
                        _certificate = new X509Certificate2(byteArray);
                    }
                }
            }
            return(_certificate);
        }
        private void SwitchModeIfNecessary()
        {
            if (_isolatedStorageMode)
            {
                Debug.Assert(_memoryStreamList.Count == 0); // it must be empty in isolated storage mode

                // if we are in isolated storage mode we need to check the Low Water Mark crossing
                if (_isolatedStorageStream.Length < _lowWaterMark)
                {
                    if (_isolatedStorageStream.Length > 0)
                    {
                        //build memory stream
                        MemoryStreamBlock newMemStreamBlock = new MemoryStreamBlock
                                                                  (_trackingMemoryStreamFactory.Create((int)_isolatedStorageStream.Length),
                                                                  0);

                        //copy data from iso storage to memory stream
                        _isolatedStorageStream.Seek(0, SeekOrigin.Begin);
                        newMemStreamBlock.Stream.Seek(0, SeekOrigin.Begin);
                        PackagingUtilities.CopyStream(_isolatedStorageStream, newMemStreamBlock.Stream,
                                                      Int64.MaxValue /*bytes to copy*/,
                                                      0x80000 /*512K buffer size */);

                        Debug.Assert(newMemStreamBlock.Stream.Length > 0);
                        _memoryStreamList.Add(newMemStreamBlock);
                    }

                    //switch mode
                    _isolatedStorageMode = false;

                    // release isolated storage disk space by setting its length to 0
                    // This way we don't have to re-open the isolated storage again if the memory consumption
                    //  goes above the High Water Mark
                    _isolatedStorageStream.SetLength(0);
                    _isolatedStorageStream.Flush();
                }
            }
            else
            {
                // if we are in Memory Stream mode we need to check the High Water Mark crossing
                if (_trackingMemoryStreamFactory.CurrentMemoryConsumption > _highWaterMark)
                {
                    //copy data to isolated storage
                    EnsureIsolatedStoreStream();
                    CopyMemoryBlocksToStream(_isolatedStorageStream);

                    //switch mode
                    _isolatedStorageMode = true;

                    //release memory stream resources
                    foreach (MemoryStreamBlock memStreamBlock in _memoryStreamList)
                    {
                        // this will report the appropriate Memory usage back to the  ITrackingMemoryStreamFactory
                        memStreamBlock.Stream.Close();
                    }
                    _memoryStreamList.Clear();
                }
            }
        }
 private void EnsureIsolatedStoreStream()
 {
     if (_isolatedStorageStream == null)
     {
         _isolatedStorageStream = PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(
             3, out _isolatedStorageStreamFileName);
     }
 }
Exemplo n.º 7
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region Stream Methods
        /// <summary>
        /// Return the bytes requested from the container
        /// </summary>
        /// <param name="buffer">destination buffer</param>
        /// <param name="offset">offset to write into that buffer</param>
        /// <param name="count">how many bytes requested</param>
        /// <returns>how many bytes were written into <paramref name="buffer" />.</returns>
        /// <remarks>
        /// The underlying stream, expected to be an IsolatedStorageFileStream,
        /// is trusted to leave the IO position unchanged in case of an exception.
        /// </remarks>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            return(_tempStream.Read(buffer, offset, count));
        }
Exemplo n.º 8
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Return the bytes requested.
        /// </summary>
        /// <param name="buffer">Destination buffer.</param>
        /// <param name="offset">
        /// The zero-based byte offset in buffer at which to begin storing the data read
        /// from the current stream.
        /// </param>
        /// <param name="count">How many bytes requested.</param>
        /// <returns>How many bytes were written into buffer.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckClosed();

            // Check arguments.
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // Leave capability and FileAccess checks up to the underlying stream(s).

            // Reading 0 bytes is a no-op.
            if (count == 0)
            {
                return(0);
            }

            int pieceNumber    = GetCurrentPieceNumber();
            int totalBytesRead = 0;

            Stream pieceStream = _dir.GetStream(pieceNumber);

            checked
            {
                //Seek to the correct location in the underlying stream for the current piece
                pieceStream.Seek(_currentOffset - _dir.GetStartOffset(pieceNumber), SeekOrigin.Begin);

                while (totalBytesRead < count)
                {
                    int numBytesRead = pieceStream.Read(
                        buffer,
                        offset + totalBytesRead,
                        count - totalBytesRead);

                    // End of the current stream: try to move to the next stream.
                    if (numBytesRead == 0)
                    {
                        if (_dir.IsLastPiece(pieceNumber))
                        {
                            break;
                        }

                        ++pieceNumber;
                        Invariant.Assert(_dir.GetStartOffset(pieceNumber) == _currentOffset + totalBytesRead);

                        pieceStream = _dir.GetStream(pieceNumber);

                        //Seek inorder to set the correct pointer for the next piece stream
                        pieceStream.Seek(0, SeekOrigin.Begin);
                    }

                    totalBytesRead += numBytesRead;
                }

                // Advance current position now we know the operation completed successfully.
                _currentOffset += totalBytesRead;
            }

            return(totalBytesRead);
        }
        /// <summary>
        /// Parse the Relationship-specific Transform
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="partUri"></param>
        /// <param name="relationshipSelectors">may be allocated but will never be empty</param>
        private static void ParseRelationshipsTransform(XmlReader reader, Uri partUri, ref List <PackageRelationshipSelector> relationshipSelectors)
        {
            Uri owningPartUri = PackUriHelper.GetSourcePartUriFromRelationshipPartUri(partUri);

            // find all of the Relationship tags of form:
            //      <RelationshipReference SourceId="abc123" />
            // or
            //      <RelationshipsGroupReference SourceType="reference-type-of-the-week" />
            while (reader.Read() && (reader.MoveToContent() == XmlNodeType.Element) &&
                   reader.Depth == 5)
            {
                // both types have no children, a single required attribute and belong to the OPC namespace
                if (reader.IsEmptyElement &&
                    PackagingUtilities.GetNonXmlnsAttributeCount(reader) == 1 &&
                    (String.CompareOrdinal(reader.NamespaceURI, XTable.Get(XTable.ID.OpcSignatureNamespace)) == 0))
                {
                    // <RelationshipReference>?
                    if (String.CompareOrdinal(reader.LocalName, XTable.Get(XTable.ID.RelationshipReferenceTagName)) == 0)
                    {
                        // RelationshipReference tags are legal and these must be empty with a single SourceId attribute
                        // get the SourceId attribute
                        string id = reader.GetAttribute(XTable.Get(XTable.ID.SourceIdAttrName));
                        if (id != null && id.Length > 0)
                        {
                            if (relationshipSelectors == null)
                            {
                                relationshipSelectors = new List <PackageRelationshipSelector>();
                            }

                            // we found a legal SourceId so create a selector and continue searching
                            relationshipSelectors.Add(new PackageRelationshipSelector(owningPartUri, PackageRelationshipSelectorType.Id, id));
                            continue;
                        }
                    }   // <RelationshipsGroupReference>?
                    else if ((String.CompareOrdinal(reader.LocalName, XTable.Get(XTable.ID.RelationshipsGroupReferenceTagName)) == 0))
                    {
                        // RelationshipsGroupReference tags must be empty with a single SourceType attribute
                        string type = reader.GetAttribute(XTable.Get(XTable.ID.SourceTypeAttrName));
                        if (type != null && type.Length > 0)
                        {
                            // lazy init
                            if (relationshipSelectors == null)
                            {
                                relationshipSelectors = new List <PackageRelationshipSelector>();
                            }

                            // got a legal SourceType attribute
                            relationshipSelectors.Add(new PackageRelationshipSelector(owningPartUri, PackageRelationshipSelectorType.Type, type));
                            continue;
                        }
                    }
                }

                // if we get to here, we have not found a legal tag so we throw
                throw new XmlException(SR.Get(SRID.UnexpectedXmlTag, reader.LocalName));
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Write
        /// </summary>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);

            // no-op
            if (count == 0)
            {
                return;
            }

            _tempStream.Write(buffer, offset, count);
            _dirty = true;
        }
        // Token: 0x06006CB1 RID: 27825 RVA: 0x001F44D8 File Offset: 0x001F26D8
        private static Stream FileToStream(string filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileSharing, long maxMemoryStream)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            long     length   = fileInfo.Length;
            Stream   stream   = new FileStream(filePath, fileMode, fileAccess, fileSharing);

            if (length < maxMemoryStream)
            {
                MemoryStream memoryStream = new MemoryStream((int)length);
                using (stream)
                {
                    PackagingUtilities.CopyStream(stream, memoryStream, length, 4096);
                }
                stream = memoryStream;
            }
            return(stream);
        }
 //------------------------------------------------------
 //
 //  Internal Methods
 //
 //------------------------------------------------------
 /// <summary>
 /// WriteToStream(Stream stream) writes the sparse Memory stream to the Stream provided as parameter
 /// starting at the current position in the stream
 /// </summary>
 internal void WriteToStream(Stream stream)
 {
     checked
     {
         if (_isolatedStorageMode)
         {
             _isolatedStorageStream.Seek(0, SeekOrigin.Begin);
             PackagingUtilities.CopyStream(_isolatedStorageStream, stream,
                                           Int64.MaxValue /*bytes to copy*/,
                                           0x80000 /*512K buffer size */);
         }
         else
         {
             CopyMemoryBlocksToStream(stream);
         }
     }
 }
        /// <summary>
        /// Parse the DigestValue tag
        /// </summary>
        /// <param name="reader"></param>
        private static string ParseDigestValueTag(XmlReader reader)
        {
            Debug.Assert(reader != null);

            // verify namespace and lack of attributes
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) > 0 ||
                String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0 ||
                reader.Depth != 3)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            // there are no legal attributes and the only content must be text
            if (reader.HasAttributes || (reader.Read() && reader.MoveToContent() != XmlNodeType.Text))
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            // get the Value
            return(reader.ReadString());
        }
Exemplo n.º 14
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Return the bytes requested.
        /// </summary>
        /// <param name="buffer">Destination buffer.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
        /// <param name="count">How many bytes requested.</param>
        /// <returns>How many bytes were written into buffer.</returns>
        public unsafe override int Read(byte[] buffer, int offset, int count)
        {
            ThrowIfStreamDisposed();

            // Check arguments.
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // Reading 0 bytes is a no-op.
            if (count == 0)
            {
                return(0);
            }

            // Prepare location of return value and call the COM object.
            int    bytesRead;
            IntPtr pBytesRead = new IntPtr(&bytesRead);

            // Prepare to restore position in case the read fails.
            long positionBeforeReadAttempt = this.Position;

            try
            {
                // Pin the array wrt GC while using an address in it.
                fixed(byte *bufferPointer = &buffer[offset])
                {
                    _oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead);
                }
            }
            catch (COMException comException)
            {
                this.Position = positionBeforeReadAttempt;
                throw new IOException("Read", comException);
            }
            catch (IOException ioException)
            {
                this.Position = positionBeforeReadAttempt;
                throw new IOException("Read", ioException);
            }
            return(bytesRead);
        }
        override public void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();
#if DEBUG
            DebugAssertConsistentArrayStructure();
#endif

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);

            Debug.Assert(_currentStreamPosition >= 0);

            if (count == 0)
            {
                return;
            }

            checked
            {
                if (_isolatedStorageMode)
                {
                    lock (PackagingUtilities.IsolatedStorageFileLock)
                    {
                        _isolatedStorageStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
                        _isolatedStorageStream.Write(buffer, offset, count);
                    }
                    _currentStreamPosition += count;
                }
                else
                {
                    WriteAndCollapseBlocks(buffer, offset, count);
                }
                _currentStreamLength = Math.Max(_currentStreamLength, _currentStreamPosition);
            }

            // this can potentially affect memory consumption
            SwitchModeIfNecessary();
#if DEBUG
            DebugAssertConsistentArrayStructure();
#endif
        }
        // Token: 0x06006C85 RID: 27781 RVA: 0x001F3B74 File Offset: 0x001F1D74
        public unsafe override int Read(byte[] buffer, int offset, int count)
        {
            this.ThrowIfStreamDisposed();
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
            if (count == 0)
            {
                return(0);
            }
            int    result;
            IntPtr refToNumBytesRead = new IntPtr((void *)(&result));
            long   position          = this.Position;

            try
            {
                try
                {
                    fixed(byte *ptr = &buffer[offset])
                    {
                        this._oleStream.Read(new IntPtr((void *)ptr), count, refToNumBytesRead);
                    }
                }
                finally
                {
                    byte *ptr = null;
                }
            }
            catch (COMException innerException)
            {
                this.Position = position;
                throw new IOException("Read", innerException);
            }
            catch (IOException innerException2)
            {
                this.Position = position;
                throw new IOException("Read", innerException2);
            }
            return(result);
        }
        /// <summary>
        /// Get the part uri and it's content type from the current Reference tag
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="contentType">contentType extracted from the query portion of the Uri</param>
        /// <returns>PackagePart uri and contentType</returns>
        private static Uri ParsePartUri(XmlReader reader, out ContentType contentType)
        {
            // should be a relative Package uri with a query portion that contains the ContentType
            contentType = ContentType.Empty;
            Uri partUri = null;

            // must be one and only one attribute
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) == 1)
            {
                string uriAttrValue = reader.GetAttribute(XTable.Get(XTable.ID.UriAttrName));
                if (uriAttrValue != null)
                {
                    partUri = ParsePartUriAttribute(uriAttrValue, out contentType);
                }
            }

            // will be null if we had no success
            if (partUri == null)
            {
                throw new XmlException(SR.Get(SRID.RequiredXmlAttributeMissing, XTable.Get(XTable.ID.UriAttrName)));
            }

            return(partUri);
        }
Exemplo n.º 18
0
        // Deserialize properties part.
        private void ParseCorePropertyPart(PackagePart part)
        {
            Stream stream = part.GetStream(FileMode.Open, FileAccess.Read);

            // Create a reader that uses _nameTable so as to use the set of tag literals
            // in effect as a set of atomic identifiers.
            XmlTextReader reader = new XmlTextReader(stream, _nameTable);

            //Prohibit DTD from the markup as per the OPC spec
            reader.ProhibitDtd = true;

            //This method expects the reader to be in ReadState.Initial.
            //It will make the first read call.
            PackagingUtilities.PerformInitailReadAndVerifyEncoding(reader);

            //Note: After the previous method call the reader should be at the first tag in the markup.
            //MoveToContent - Skips over the following - ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace
            //If the reader is currently at a content node then this function call is a no-op
            if (reader.MoveToContent() != XmlNodeType.Element ||
                (object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.PackageCorePropertiesNamespace) ||
                (object)reader.LocalName != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.CoreProperties))
            {
                throw new XmlException(SR.Get(SRID.CorePropertiesElementExpected),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            // The schema is closed and defines no attributes on the root element.
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) != 0)
            {
                throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            // Iterate through property elements until EOF. Note the proper closing of all
            // open tags is checked by the reader itself.
            // This loop deals only with depth-1 start tags. Handling of element content
            // is delegated to dedicated functions.
            int attributesCount;

            while (reader.Read() && reader.MoveToContent() != XmlNodeType.None)
            {
                // Ignore end-tags. We check element errors on opening tags.
                if (reader.NodeType == XmlNodeType.EndElement)
                {
                    continue;
                }

                // Any content markup that is not an element here is unexpected.
                if (reader.NodeType != XmlNodeType.Element)
                {
                    throw new XmlException(SR.Get(SRID.PropertyStartTagExpected),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                // Any element below the root should open at level 1 exclusively.
                if (reader.Depth != 1)
                {
                    throw new XmlException(SR.Get(SRID.NoStructuredContentInsideProperties),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                attributesCount = PackagingUtilities.GetNonXmlnsAttributeCount(reader);

                // Property elements can occur in any order (xsd:all).
                object         localName      = reader.LocalName;
                PackageXmlEnum xmlStringIndex = PackageXmlStringTable.GetEnumOf(localName);
                String         valueType      = PackageXmlStringTable.GetValueType(xmlStringIndex);

                if (Array.IndexOf(_validProperties, xmlStringIndex) == -1)  // An unexpected element is an error.
                {
                    throw new XmlException(
                              SR.Get(SRID.InvalidPropertyNameInCorePropertiesPart, reader.LocalName),
                              null, reader.LineNumber, reader.LinePosition);
                }

                // Any element not in the valid core properties namespace is unexpected.
                // The following is an object comparison, not a string comparison.
                if ((object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlStringTable.GetXmlNamespace(xmlStringIndex)))
                {
                    throw new XmlException(SR.Get(SRID.UnknownNamespaceInCorePropertiesPart),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                if (String.CompareOrdinal(valueType, "String") == 0)
                {
                    // The schema is closed and defines no attributes on this type of element.
                    if (attributesCount != 0)
                    {
                        throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                               null, reader.LineNumber, reader.LinePosition);
                    }

                    RecordNewBinding(xmlStringIndex, GetStringData(reader), true /*initializing*/, reader);
                }
                else if (String.CompareOrdinal(valueType, "DateTime") == 0)
                {
                    int allowedAttributeCount = (object)reader.NamespaceURI ==
                                                PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace)
                                                    ? 1 : 0;

                    // The schema is closed and defines no attributes on this type of element.
                    if (attributesCount != allowedAttributeCount)
                    {
                        throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                               null, reader.LineNumber, reader.LinePosition);
                    }

                    if (allowedAttributeCount != 0)
                    {
                        ValidateXsiType(reader,
                                        PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace),
                                        _w3cdtf);
                    }

                    RecordNewBinding(xmlStringIndex, GetDateData(reader), true /*initializing*/, reader);
                }
                else  // An unexpected element is an error.
                {
                    Invariant.Assert(false, "Unknown value type for properties");
                }
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Parse PackageRelationship Stream
        /// </summary>
        /// <param name="part">relationship part</param>
        /// <exception cref="XmlException">Thrown if XML is malformed</exception>
        private void ParseRelationshipPart(PackagePart part)
        {
            //We can safely open the stream as FileAccess.Read, as this code
            //should only be invoked if the Package has been opened in Read or ReadWrite mode.
            Debug.Assert(_package.FileOpenAccess == FileAccess.Read || _package.FileOpenAccess == FileAccess.ReadWrite,
                         "This method should only be called when FileAccess is Read or ReadWrite");

            using (Stream s = part.GetStream(FileMode.Open, FileAccess.Read))
            {
                // load from the relationship part associated with the given part
                using (XmlTextReader baseReader = new XmlTextReader(s))
                {
                    baseReader.WhitespaceHandling = WhitespaceHandling.None;

                    //Prohibit DTD from the markup as per the OPC spec
                    baseReader.ProhibitDtd = true;

                    using (XmlCompatibilityReader reader = new XmlCompatibilityReader(baseReader, RelationshipKnownNamespaces))
                    {
                        //This method expects the reader to be in ReadState.Initial.
                        //It will make the first read call.
                        PackagingUtilities.PerformInitailReadAndVerifyEncoding(baseReader);

                        //Note: After the previous method call the reader should be at the first tag in the markup.
                        //MoveToContent - Skips over the following - ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace
                        //If the reader is currently at a content node then this function call is a no-op
                        reader.MoveToContent();

                        // look for our tag and namespace pair - throw if other elements are encountered
                        // Make sure that the current node read is an Element
                        if (reader.NodeType == XmlNodeType.Element &&
                            (reader.Depth == 0) &&
                            (String.CompareOrdinal(RelationshipsTagName, reader.LocalName) == 0) &&
                            (String.CompareOrdinal(PackagingUtilities.RelationshipNamespaceUri, reader.NamespaceURI) == 0))
                        {
                            ThrowIfXmlBaseAttributeIsPresent(reader);

                            //There should be a namespace Attribute present at this level.
                            //Also any other attribute on the <Relationships> tag is an error including xml: and xsi: attributes
                            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) > 0)
                            {
                                throw new XmlException(SR.Get(SRID.RelationshipsTagHasExtraAttributes), null, reader.LineNumber, reader.LinePosition);
                            }

                            // start tag encountered for Relationships
                            // now parse individual Relationship tags
                            while (reader.Read())
                            {
                                //Skips over the following - ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace
                                //If the reader is currently at a content node then this function call is a no-op
                                reader.MoveToContent();

                                //If MoveToContent() takes us to the end of the content
                                if (reader.NodeType == XmlNodeType.None)
                                {
                                    continue;
                                }

                                if (reader.NodeType == XmlNodeType.Element &&
                                    (reader.Depth == 1) &&
                                    (String.CompareOrdinal(RelationshipTagName, reader.LocalName) == 0) &&
                                    (String.CompareOrdinal(PackagingUtilities.RelationshipNamespaceUri, reader.NamespaceURI) == 0))
                                {
                                    ThrowIfXmlBaseAttributeIsPresent(reader);

                                    int expectedAttributesCount = 3;

                                    string targetModeAttributeValue = reader.GetAttribute(TargetModeAttributeName);
                                    if (targetModeAttributeValue != null)
                                    {
                                        expectedAttributesCount++;
                                    }

                                    //check if there are expected number of attributes.
                                    //Also any other attribute on the <Relationship> tag is an error including xml: and xsi: attributes
                                    if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributesCount)
                                    {
                                        ProcessRelationshipAttributes(reader);

                                        //Skip the EndElement for Relationship
                                        if (!reader.IsEmptyElement)
                                        {
                                            ProcessEndElementForRelationshipTag(reader);
                                        }
                                    }
                                    else
                                    {
                                        throw new XmlException(SR.Get(SRID.RelationshipTagDoesntMatchSchema), null, reader.LineNumber, reader.LinePosition);
                                    }
                                }
                                else
                                if (!(String.CompareOrdinal(RelationshipsTagName, reader.LocalName) == 0 && (reader.NodeType == XmlNodeType.EndElement)))
                                {
                                    throw new XmlException(SR.Get(SRID.UnknownTagEncountered), null, reader.LineNumber, reader.LinePosition);
                                }
                            }
                        }
                        else
                        {
                            throw new XmlException(SR.Get(SRID.ExpectedRelationshipsElementTag), null, reader.LineNumber, reader.LinePosition);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Parses Transforms tag
        /// </summary>
        /// <param name="reader">node to parse</param>
        /// <param name="partUri">Part Uri for the part owning the relationships</param>
        /// <param name="relationshipSelectors">allocates and returns a list of
        /// PackageRelationshipSelectors if Relationship transform</param>
        /// <returns>ordered list of Transform names</returns>
        private static List <String> ParseTransformsTag(XmlReader reader, Uri partUri, ref List <PackageRelationshipSelector> relationshipSelectors)
        {
            // # reference that signs multiple PackageRelationships
            // <Reference URI="/shared/_rels/image.jpg.rels?ContentType=image/jpg">
            //      <Transforms>
            //          <Transform Algorithm="http://schemas.openxmlformats.org/package/2006/RelationshipTransform">
            //              <RelationshipReference SourceId="1" />
            //              <RelationshipReference SourceId="2" />
            //              <RelationshipReference SourceId="8" />
            //          </Transform>
            //          <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
            //      </Transforms>
            //      <DigestMethod Algorithm="sha1" />
            //      <DigestValue>... </DigestValue>
            // </Reference>

            // verify lack of attributes
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) != 0)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            List <String> transforms = null;
            bool          relationshipTransformFound = false;
            int           transformsCountWhenRelationshipTransformFound = 0;

            // Look for transforms.
            // There are currently only 3 legal transforms which can be arranged in any
            // combination.
            while (reader.Read() && (reader.MoveToContent() == XmlNodeType.Element))
            {
                String transformName = null;

                // at this level, all tags must be Transform tags
                if (reader.Depth != 4 ||
                    String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0 ||
                    String.CompareOrdinal(reader.LocalName, XTable.Get(XTable.ID.TransformTagName)) != 0)
                {
                    throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
                }

                // inspect the Algorithm attribute to determine the type of transform
                if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) == 1)
                {
                    transformName = reader.GetAttribute(XTable.Get(XTable.ID.AlgorithmAttrName));
                }

                // legal transform name?
                if ((transformName != null) && (transformName.Length > 0))
                {
                    // what type of transform?
                    if (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0)
                    {
                        if (!relationshipTransformFound)
                        {
                            // relationship transform
                            ParseRelationshipsTransform(reader, partUri, ref relationshipSelectors);

                            if (transforms == null)
                            {
                                transforms = new List <String>();
                            }

                            transforms.Add(transformName);

                            relationshipTransformFound = true;
                            transformsCountWhenRelationshipTransformFound = transforms.Count;
                            continue;   // success
                        }
                        else
                        {
                            throw new XmlException(SR.Get(SRID.MultipleRelationshipTransformsFound));
                        }
                    }
                    else
                    {
                        // non-Relationship transform should have no children
                        if (reader.IsEmptyElement)
                        {
                            if (transforms == null)
                            {
                                transforms = new List <String>();
                            }

                            if (XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform(transformName))
                            {
                                transforms.Add(transformName); // return it
                                continue;                      // success
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.Get(SRID.UnsupportedTransformAlgorithm));
                            }
                        }
                    }
                }
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            if (transforms.Count == 0)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            //If we found another transform after the Relationship transform, it will be validated earlier
            //in this method to make sure that its a supported xml canonicalization algorithm and so we can
            //simplify this test condition - As per the OPC spec - Relationship transform must be followed
            //by a canonicalization algorithm.
            if (relationshipTransformFound && (transforms.Count == transformsCountWhenRelationshipTransformFound))
            {
                throw new XmlException(SR.Get(SRID.RelationshipTransformNotFollowedByCanonicalizationTransform));
            }

            return(transforms);
        }
Exemplo n.º 21
0
        //-----------------------------------------------------------------------------
        //
        // Private Methods
        //
        //-----------------------------------------------------------------------------

        /// <summary>
        /// Parse the SignatureTime tag
        /// </summary>
        /// <param name="reader">NodeReader positioned at the SignatureProperty tag</param>
        /// <param name="timeFormat">format found</param>
        /// <exception cref="XmlException">illegal format</exception>
        /// <returns>signing time</returns>
        private static DateTime ParseSignatureTimeTag(XmlReader reader, out String timeFormat)
        {
            //There are no attributes on all the three tags that we parse in this method
            //<SignatureTime>, <Format>, <Value>
            int expectedAttributeCount = 0;

            string opcSignatureNameSpace = XTable.Get(XTable.ID.OpcSignatureNamespace);
            string signaturePropertyTag  = XTable.Get(XTable.ID.SignaturePropertyTagName);
            string signatureTimeTag      = XTable.Get(XTable.ID.SignatureTimeTagName);
            string timeValueTagName      = XTable.Get(XTable.ID.SignatureTimeValueTagName);
            string timeFormatTagName     = XTable.Get(XTable.ID.SignatureTimeFormatTagName);

            // <SignatureTime> must be one of <Format> or <Time>
            timeFormat = null;
            string timeValue = null;

            //Look for <SignatureTime> Tag
            if (reader.Read() &&
                reader.MoveToContent() == XmlNodeType.Element &&
                (String.CompareOrdinal(reader.NamespaceURI, opcSignatureNameSpace) == 0) &&
                (String.CompareOrdinal(reader.LocalName, signatureTimeTag) == 0) &&
                reader.Depth == 3 &&
                PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributeCount)
            {
                while (reader.Read())
                {
                    if (String.CompareOrdinal(reader.NamespaceURI, opcSignatureNameSpace) == 0 &&
                        reader.MoveToContent() == XmlNodeType.Element &&
                        reader.Depth == 4)
                    {
                        // which tag do we have?
                        if ((String.CompareOrdinal(reader.LocalName, timeValueTagName) == 0) &&
                            PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributeCount)
                        {
                            if (timeValue == null &&
                                reader.Read() &&
                                reader.MoveToContent() == XmlNodeType.Text &&
                                reader.Depth == 5)
                            {
                                //After reading the content, the reader progresses to the next element.
                                //So after this method is called, the reader is positioned at the
                                //EndElement corresponding to Value tag - </Value>
                                // Note: ReadContentAsString will return String.Empty but never null
                                timeValue = reader.ReadContentAsString();
                                Debug.Assert(reader.NodeType == XmlNodeType.EndElement);
                            }
                            else
                            {
                                //This would happen if we found more than one Value tags or if there
                                //are other nested elements of if they are of a different XmlNodeType type
                                throw new XmlException(SR.PackageSignatureCorruption);
                            }
                        }
                        else if ((String.CompareOrdinal(reader.LocalName, timeFormatTagName) == 0) &&
                                 PackagingUtilities.GetNonXmlnsAttributeCount(reader) == expectedAttributeCount)
                        {
                            if (timeFormat == null &&
                                reader.Read() &&
                                reader.MoveToContent() == XmlNodeType.Text &&
                                reader.Depth == 5)
                            {
                                //After reading the content, the reader progresses to the next element.
                                //So after this method is called, the reader is positioned at the
                                //EndElement corresponding to Format tag - </Format>
                                // Note: ReadContentAsString will return String.Empty but never null
                                timeFormat = reader.ReadContentAsString();
                                Debug.Assert(reader.NodeType == XmlNodeType.EndElement);
                            }
                            else
                            {
                                //This would happen if we found more than one Format tags or if there
                                //are other nested elements of if they are of a different XmlNodeType type
                                throw new XmlException(SR.PackageSignatureCorruption);
                            }
                        }
                        else
                        {
                            //If we encounter any tag other than <Format> or <Time> nested within the <SignatureTime> tag
                            throw new XmlException(SR.PackageSignatureCorruption);
                        }
                    }
                    else
                    //If we have encountered the end tag for the <SignatureTime> tag
                    //then we are done parsing the tag, and we can stop the parsing.
                    if (String.CompareOrdinal(signatureTimeTag, reader.LocalName) == 0 &&
                        (reader.NodeType == XmlNodeType.EndElement))
                    {
                        //We must find a  </SignatureProperty> tag at this point,
                        //else it could be that there are more SignatureTime or
                        //other tags nested here and that is an error.
                        if (reader.Read() &&
                            reader.MoveToContent() == XmlNodeType.EndElement &&
                            String.CompareOrdinal(signaturePropertyTag, reader.LocalName) == 0)
                        {
                            break;
                        }
                        else
                        {
                            throw new XmlException(SR.PackageSignatureCorruption);
                        }
                    }
                    else
                    {
                        // if we do not find the nested elements as expected
                        throw new XmlException(SR.PackageSignatureCorruption);
                    }
                }
            }
            else
            {
                throw new XmlException(SR.Format(SR.RequiredTagNotFound, signatureTimeTag));
            }


            // generate an equivalent DateTime object
            if (timeValue != null && timeFormat != null)
            {
                return(XmlFormattedTimeToDateTime(timeValue, timeFormat));
            }
            else
            {
                throw new XmlException(SR.PackageSignatureCorruption);
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Write. Distribute the bytes to write across several contiguous streams if needed.
        /// </summary>
        /// <remarks>
        /// Zip streams can be assumed seekable so the length will be available for chaining
        /// pieces.
        /// </remarks>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckClosed();

            // Check arguments.
            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);

            // No check for FileAccess and stream capability (CanWrite). This is the responsibility
            // of the underlying stream(s).

            // A no-op if zero bytes to write.
            if (count == 0)
            {
                return;
            }

            // Write into piece streams, preserving all lengths in non-terminal pieces.
            int    totalBytesWritten = 0;
            int    pieceNumber       = GetCurrentPieceNumber();
            Stream pieceStream       = _dir.GetStream(pieceNumber);

            checked
            {
                //Seek to the correct location in the underlying stream for the current piece
                pieceStream.Seek(_currentOffset - _dir.GetStartOffset(pieceNumber), SeekOrigin.Begin);

                while (totalBytesWritten < count)
                {
                    // Compute the number of bytes to write into pieceStream.
                    int numBytesToWriteInCurrentPiece = count - totalBytesWritten;
                    if (!_dir.IsLastPiece(pieceNumber))
                    {
                        // The write should not change the length of an intermediate piece.
                        long currentPosition = _currentOffset + totalBytesWritten;
                        long maxPosition     = _dir.GetStartOffset(pieceNumber + 1) - 1;
                        if (numBytesToWriteInCurrentPiece > (maxPosition - currentPosition + 1))
                        {
                            // Cast from long to cast is safe in so far as *count*, which is the
                            // absolute max for all byte counts, is a positive int.
                            numBytesToWriteInCurrentPiece = checked ((int)(maxPosition - currentPosition + 1));
                        }
                    }

                    // Do the write.
                    pieceStream.Write(buffer, offset + totalBytesWritten, numBytesToWriteInCurrentPiece);

                    // Update the tally.
                    totalBytesWritten += numBytesToWriteInCurrentPiece;

                    // If there is more data to write, get the next piece stream
                    if (!_dir.IsLastPiece(pieceNumber) && totalBytesWritten < count)
                    {
                        // The next write, should involve the next piece.
                        ++pieceNumber;

                        pieceStream = _dir.GetStream(pieceNumber);

                        //Seek inorder to set the correct pointer for the next piece stream
                        pieceStream.Seek(0, SeekOrigin.Begin);
                    }
                }

                // Now we know the operation has completed, the current position can be updated.
                Invariant.Assert(totalBytesWritten == count);
                _currentOffset += totalBytesWritten;
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Write
        /// </summary>
        /// <remarks>Note that zero length write to deflate stream actually results in a stream containing 2 bytes.  This is
        /// required to maintain compatibility with the standard.</remarks>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);

            // no-op
            if (count == 0)
            {
                return;
            }

            checked
            {
                switch (_mode)
                {
                case Mode.Start:                 // enter WritePassThrough mode if possible
                {
                    // Special case: If stream has existing content, we need to go straight
                    // to Emulation mode otherwise we'll potentially destroy existing data.
                    // Don't bother entering WritePassThroughMode if position is non-zero because
                    // we'll just enter emulation later.
                    if (_position == 0 && IsDeflateStreamEmpty(_baseStream))
                    {
                        ChangeMode(Mode.WritePassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }
                    break;
                }

                case Mode.WritePassThrough:     // continue in Write mode
                case Mode.Emulation:            // continue to read from existing emulation stream
                {
                    break;
                }

                case Mode.ReadPassThrough:      // enter Emulation mode
                {
                    ChangeMode(Mode.Emulation); break;
                }

                default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
                }

                _current.Write(buffer, offset, count);

                _position += count;
            }

            // keep track of the current length in case someone asks for it
            if (_mode == Mode.WritePassThrough)
            {
                CachedLength = _position;
            }

            _dirtyForFlushing = true;
            _dirtyForClosing  = true;
        }
Exemplo n.º 24
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region Stream Methods
        /// <summary>
        /// Return the bytes requested from the container
        /// </summary>
        /// <param name="buffer">destination buffer</param>
        /// <param name="offset">offset to write into that buffer</param>
        /// <param name="count">how many bytes requested</param>
        /// <returns>how many bytes were written into <paramref name="buffer" />.</returns>
        /// <remarks>
        /// The underlying stream, expected to be a DeflateStream or a CompressEmulationStream,
        /// is in charge of leaving the IO position unchanged in case of an exception.
        /// </remarks>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // no-op
            if (count == 0)
            {
                return(0);
            }

            checked     // catch any integer overflows
            {
                switch (_mode)
                {
                case Mode.Start:
                {
                    // skip to the correct logical position if necessary (DeflateStream starts at position zero)
                    if (_position == 0)
                    {
                        // enter ReadPassThrough mode if it is efficient
                        ChangeMode(Mode.ReadPassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }

                    break;
                }

                case Mode.ReadPassThrough:      // continue in ReadPassThrough mode
                case Mode.Emulation:            // continue to read from existing emulation stream
                {
                    break;
                }

                case Mode.WritePassThrough:     // enter Emulation mode
                {
                    // optimization - if they are trying to jump back to the start to read, simply jump to ReadPassThrough mode
                    if (_position == 0)
                    {
                        ChangeMode(Mode.ReadPassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }
                    break;
                }

                default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
                }

                // we might be in Start mode now if we are beyond the end of stream - just return zero
                if (_current == null)
                {
                    return(0);
                }

                int bytesRead = _current.Read(buffer, offset, count);

                // optimization for ReadPassThrough mode - we actually know the length because we ran out of bytes
                if (_mode == Mode.ReadPassThrough && bytesRead == 0)
                {
                    // possible first chance to set and verify length from header against real data length
                    UpdateUncompressedDataLength(_position);

                    // since we've exhausted the deflateStream, discard it to reduce working set
                    ChangeMode(Mode.Start);
                }

                // Stream contract - don't update position until we are certain that no exceptions have occurred
                _position += bytesRead;

                return(bytesRead);
            }
        }
        override public int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            Debug.Assert(_currentStreamPosition >= 0);

            if (count == 0)
            {
                return(0);
            }

            if (_currentStreamLength <= _currentStreamPosition)
            {
                // we are past the end of the stream so let's just return 0
                return(0);
            }

            // No need to use checked{} since _currentStreamLength > _currentStreamPosition
            int bytesToRead = (int)Math.Min((long)count, _currentStreamLength - _currentStreamPosition);

            checked
            {
                Debug.Assert(bytesToRead > 0);

                int bytesRead;  // how much data we actually were able to read
                if (_isolatedStorageMode)
                {
                    lock (PackagingUtilities.IsolatedStorageFileLock)
                    {
                        _isolatedStorageStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
                        bytesRead = _isolatedStorageStream.Read(buffer, offset, bytesToRead);
                    }
                }
                else
                {
                    // let's reset data to 0 first, so that gaps will be filled with 0s
                    // this is required for consistent behavior between the read calls used by the CRC Calculator
                    // and the WriteToStream calls used by the Flush/Save routines
                    Array.Clear(buffer, offset, bytesToRead);

                    int index = _memoryStreamList.BinarySearch(GetSearchBlockForOffset(_currentStreamPosition));
                    if (index < 0) // the head of new write block does not overlap with any existing blocks
                    // ~startIndex represents the insertion position
                    {
                        index = ~index;
                    }

                    for ( ; index < _memoryStreamList.Count; ++index)
                    {
                        MemoryStreamBlock memStreamBlock = _memoryStreamList[index];
                        long overlapBlockOffset;
                        long overlapBlockSize;
                        // let's check for overlap and fill up appropriate data
                        PackagingUtilities.CalculateOverlap(memStreamBlock.Offset, (int)memStreamBlock.Stream.Length,
                                                            _currentStreamPosition, bytesToRead,
                                                            out overlapBlockOffset, out overlapBlockSize);
                        if (overlapBlockSize > 0)
                        {
                            // we got an overlap let's copy data over to the target buffer
                            // _currentStreamPosition is not updated in this foreach loop; it will be updated later
                            Array.Copy(memStreamBlock.Stream.GetBuffer(), (int)(overlapBlockOffset - memStreamBlock.Offset),
                                       buffer, (int)(offset + overlapBlockOffset - _currentStreamPosition),
                                       (int)overlapBlockSize);
                        }
                        else
                        {
                            break;
                        }
                    }
                    // for memory stream case we get as much as we asked for
                    bytesRead = bytesToRead;
                }

                _currentStreamPosition += bytesRead;

                return(bytesRead);
            }
        }