Ejemplo n.º 1
0
        // This constructor is used when creating XmlTextReaderImpl reader via "XmlReader.Create(..)"
        private XmlTextReaderImpl( XmlResolver resolver, XmlReaderSettings settings, XmlParserContext context ) {

#if ASYNC
            useAsync = settings.Async;
#endif

            v1Compat = false;
            outerReader = this;

            xmlContext = new XmlContext();        

            // create or get nametable and namespace manager from XmlParserContext
            XmlNameTable nt = settings.NameTable;
            if ( context == null ) {
                if ( nt == null ) {
                    nt = new NameTable();
                    Debug.Assert( nameTableFromSettings == false );
                }
                else {
                    nameTableFromSettings = true;
                }
                nameTable = nt;
                namespaceManager = new XmlNamespaceManager( nt );
            }
            else {
                SetupFromParserContext( context, settings );
                nt = nameTable;
            }

            nt.Add( string.Empty );
            Xml = nt.Add( "xml" );
            XmlNs = nt.Add( "xmlns" );

            xmlResolver = resolver;

            Debug.Assert( index == 0 );

            nodes = new NodeData[ NodesInitialSize ];
            nodes[0] = new NodeData();
            curNode = nodes[0];

            stringBuilder = new BufferBuilder();

#if !SILVERLIGHT 
            // Needed only for XmlTextReader (reporting of entities)
            entityHandling = EntityHandling.ExpandEntities;

            xmlResolverIsSet = settings.IsXmlResolverSet;
#endif
            
            whitespaceHandling = ( settings.IgnoreWhitespace ) ? WhitespaceHandling.Significant : WhitespaceHandling.All;
            normalize = true;
            ignorePIs = settings.IgnoreProcessingInstructions;
            ignoreComments = settings.IgnoreComments;
            checkCharacters = settings.CheckCharacters;
            lineNumberOffset = settings.LineNumberOffset;
            linePositionOffset = settings.LinePositionOffset;
            ps.lineNo = lineNumberOffset + 1;
            ps.lineStartPos = - linePositionOffset - 1;
            curNode.SetLineInfo( ps.LineNo - 1, ps.LinePos - 1 );
            dtdProcessing = settings.DtdProcessing;
            maxCharactersInDocument = settings.MaxCharactersInDocument;
            maxCharactersFromEntities = settings.MaxCharactersFromEntities;

            charactersInDocument = 0;
            charactersFromEntities = 0;

            fragmentParserContext = context;

            parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl;
            nextParsingFunction = ParsingFunction.DocumentContent;

            switch ( settings.ConformanceLevel ) { 
                case ConformanceLevel.Auto:
                    fragmentType = XmlNodeType.None;
#if !SILVERLIGHT // Needed only for XmlTextReader
                    fragment = true;
#endif
                    break;
                case ConformanceLevel.Fragment:
                    fragmentType = XmlNodeType.Element;
#if !SILVERLIGHT // Needed only for XmlTextReader
                    fragment = true;
#endif
                    break;
                case ConformanceLevel.Document:
                    fragmentType = XmlNodeType.Document;
                    break;
                default:
                    Debug.Assert( false );
                    goto case ConformanceLevel.Document;
            }
        }
Ejemplo n.º 2
0
        private int EatWhitespaces( BufferBuilder sb ) {
            int pos = ps.charPos;
            int wsCount = 0;
            char[] chars = ps.chars;

            for (;;) {
                for (;;) {
                    switch ( chars[pos] ) {
                        case (char)0xA:
                            pos++;
                            OnNewLine( pos );
                            continue;
                        case (char)0xD:
                            if ( chars[pos+1] == (char)0xA ) {
                                int tmp1 = pos - ps.charPos;
                                if ( sb != null && !ps.eolNormalized ) {
                                    if ( tmp1 > 0 ) {
                                        sb.Append( chars, ps.charPos, tmp1 );
                                        wsCount += tmp1;
                                    }
                                    ps.charPos = pos + 1;
                                }
                                pos += 2;
                            }
                            else if ( pos+1 < ps.charsUsed || ps.isEof ) {
                                if ( !ps.eolNormalized ) {
                                    chars[pos] = (char)0xA;             // EOL normalization of 0xD
                                }
                                pos++;
                            }
                            else {
                                goto ReadData;
                            }
                            OnNewLine( pos );
                            continue;
                        case (char)0x9:
                        case (char)0x20:
                            pos++;
                            continue;
                        default:
                            if ( pos == ps.charsUsed ) {
                                goto ReadData;
                            }
                            else {
                                int tmp2 = pos - ps.charPos;
                                if ( tmp2 > 0 ) {
                                    if ( sb != null  ) {
                                        sb.Append( ps.chars, ps.charPos, tmp2 );
                                    }
                                    ps.charPos = pos;
                                    wsCount += tmp2;
                                }
                                return wsCount;
                            }
                    }
                }

            ReadData:
                int tmp3 = pos - ps.charPos;
                if ( tmp3 > 0 ) {
                    if ( sb != null  ) {
                        sb.Append( ps.chars, ps.charPos, tmp3 );
                    }
                    ps.charPos = pos;
                    wsCount += tmp3;
                }

                if ( ReadData() == 0 ) {
                    if ( ps.charsUsed - ps.charPos == 0 ) {
                        return wsCount;
                    }
                    if ( ps.chars[ps.charPos] != (char)0xD ) {
                        Debug.Assert( false, "We should never get to this point." );
                        Throw( Res.Xml_UnexpectedEOF1 );
                    }
                    Debug.Assert( ps.isEof );
                }
                pos = ps.charPos;
                chars = ps.chars;
            }
        }
Ejemplo n.º 3
0
 internal int DtdParserProxy_ParseNamedCharRef( bool expand, BufferBuilder internalSubsetBuilder ) {
     return this.ParseNamedCharRef( expand, internalSubsetBuilder );
 }
Ejemplo n.º 4
0
        internal void DtdParserProxy_ParseComment( BufferBuilder sb ) {
            Debug.Assert( parsingMode == ParsingMode.Full );

            try {
                if ( sb == null ) {
                    ParsingMode savedParsingMode = parsingMode;
                    parsingMode = ParsingMode.SkipNode;
                    ParseCDataOrComment( XmlNodeType.Comment );
                    parsingMode = savedParsingMode;
                }
                else {
                    NodeData originalCurNode = curNode;

                    curNode = AddNode( index + attrCount + 1, index );
                    ParseCDataOrComment( XmlNodeType.Comment );
                    curNode.CopyTo( 0, sb );

                    curNode = originalCurNode;
                }
            }
            catch ( XmlException e ) {
#if !SILVERLIGHT
                if ( e.ResString == Res.Xml_UnexpectedEOF && ps.entity != null ) {
                    SendValidationEvent( XmlSeverityType.Error, Res.Sch_ParEntityRefNesting, null, ps.LineNo, ps.LinePos );
                }   
                else {
                    throw;
                }
#else
                throw e;
#endif
            }
        }
Ejemplo n.º 5
0
        internal void DtdParserProxy_ParseComment(BufferBuilder sb)
        {
            Debug.Assert(_parsingMode == ParsingMode.Full);

            try
            {
                if (sb == null)
                {
                    ParsingMode savedParsingMode = _parsingMode;
                    _parsingMode = ParsingMode.SkipNode;
                    ParseCDataOrComment(XmlNodeType.Comment);
                    _parsingMode = savedParsingMode;
                }
                else
                {
                    NodeData originalCurNode = _curNode;

                    _curNode = AddNode(_index + _attrCount + 1, _index);
                    ParseCDataOrComment(XmlNodeType.Comment);
                    _curNode.CopyTo(0, sb);

                    _curNode = originalCurNode;
                }
            }
            catch (XmlException e)
            {
                throw e;
            }
        }
Ejemplo n.º 6
0
        private async Task ParseInDocumentDtdAsync( bool saveInternalSubset ) {
            LoadParsingBuffer();

            scanningFunction = ScanningFunction.QName;
            nextScaningFunction = ScanningFunction.Doctype1;

            // doctype name
            if ( await GetTokenAsync( false ).ConfigureAwait(false) != Token.QName ) {
                OnUnexpectedError();
            }   
            schemaInfo.DocTypeName = GetNameQualified( true );

            // SYSTEM or PUBLIC id
            Token token = await GetTokenAsync( false ).ConfigureAwait(false);
            if ( token == Token.SYSTEM || token == Token.PUBLIC ) {

                var tuple_0 = await ParseExternalIdAsync( token,  Token.DOCTYPE).ConfigureAwait(false);
                publicId = tuple_0.Item1;
                systemId = tuple_0.Item2;

                token = await GetTokenAsync( false).ConfigureAwait(false);
            }

            switch ( token ) {
                case Token.LeftBracket:
                    if ( saveInternalSubset ) {
                        SaveParsingBuffer(); // this will cause saving the internal subset right from the point after '['
                        internalSubsetValueSb = new BufferBuilder();
                    }
                    await ParseInternalSubsetAsync().ConfigureAwait(false);
                    break;
                case Token.GreaterThan:
                    break;
                default:
                    OnUnexpectedError();
                    break;
            }
            SaveParsingBuffer();

            if ( systemId != null && systemId.Length > 0 ) {
                await ParseExternalSubsetAsync().ConfigureAwait(false);
            }
        }
Ejemplo n.º 7
0
//
// Initialization methods
//

        private void Initialize(IDtdParserAdapter readerAdapter) {
            Debug.Assert(readerAdapter != null);
            this.readerAdapter = readerAdapter;
#if !SILVERLIGHT
            this.readerAdapterWithValidation = readerAdapter as IDtdParserAdapterWithValidation;
#endif

            nameTable = readerAdapter.NameTable;

#if !SILVERLIGHT
            IDtdParserAdapterWithValidation raWithValidation = readerAdapter as IDtdParserAdapterWithValidation;
            if (raWithValidation != null) {
                this.validate = raWithValidation.DtdValidation;
            }
            IDtdParserAdapterV1 raV1 = readerAdapter as IDtdParserAdapterV1;
            if (raV1 != null) {
                v1Compat = raV1.V1CompatibilityMode;
                this.normalize = raV1.Normalization;
                this.supportNamespaces = raV1.Namespaces;
            }
#endif

            schemaInfo = new SchemaInfo();
#if !SILVERLIGHT
            schemaInfo.SchemaType = SchemaType.DTD;
#endif

            stringBuilder = new BufferBuilder();

            Uri baseUri = readerAdapter.BaseUri;
            if (baseUri != null) {
                documentBaseUri = baseUri.ToString();
            }

            freeFloatingDtd = false;
        }
Ejemplo n.º 8
0
 void IDtdParserAdapter.ParseComment(BufferBuilder sb)
 {
     reader.DtdParserProxy_ParseComment(sb);
 }
 Task< int > IDtdParserAdapter.ParseNamedCharRefAsync( bool expand, BufferBuilder internalSubsetBuilder ) { 
     return reader.DtdParserProxy_ParseNamedCharRefAsync( expand, internalSubsetBuilder ); 
 }
 Task IDtdParserAdapter.ParseCommentAsync( BufferBuilder sb ) { 
     return reader.DtdParserProxy_ParseCommentAsync( sb ); 
 }
 Task IDtdParserAdapter.ParseCommentAsync(BufferBuilder sb)
 {
     return(reader.DtdParserProxy_ParseCommentAsync(sb));
 }
 Task <int> IDtdParserAdapter.ParseNamedCharRefAsync(bool expand, BufferBuilder internalSubsetBuilder)
 {
     return(reader.DtdParserProxy_ParseNamedCharRefAsync(expand, internalSubsetBuilder));
 }
 Task <int> IDtdParserAdapter.ParseNumericCharRefAsync(BufferBuilder internalSubsetBuilder)
 {
     return(reader.DtdParserProxy_ParseNumericCharRefAsync(internalSubsetBuilder));
 }
Ejemplo n.º 14
0
        // Parses numeric character entity reference (e.g. &#32; &#x20;).
        // Returns -2 if more data is needed in the buffer
        // Otherwise 
        //      - replaces the last one or two character of the entity reference (';' and the character before) with the referenced 
        //        character or surrogates pair (if expand == true)
        //      - returns position of the end of the character reference, that is of the character next to the original ';'
        private int ParseNumericCharRefInline( int startPos, bool expand, BufferBuilder internalSubsetBuilder, out int charCount, out EntityType entityType ) {
            Debug.Assert( ps.chars[startPos] == '&' && ps.chars[startPos + 1] == '#' );

            int val;
            int pos;
            char[] chars;

            val = 0;
            string badDigitExceptionString = null;
            chars = ps.chars;
            pos = startPos + 2;
            charCount = 0;
            int digitPos = 0;

            try {
                if ( chars[pos] == 'x' ) {
                    pos++;
                    digitPos = pos;
                    badDigitExceptionString = Res.Xml_BadHexEntity;
                    for (;;) {
                        char ch = chars[pos];
                        if ( ch >= '0' && ch <= '9' )
                            val = checked(val * 16 + ch - '0');
                        else if ( ch >= 'a' && ch <= 'f' )
                            val = checked(val * 16 + 10 + ch - 'a');
                        else if ( ch >= 'A' && ch <= 'F' )
                            val = checked(val * 16 + 10 + ch - 'A');
                        else 
                            break;
                        pos++;
                    }
                    entityType = EntityType.CharacterHex;
                }
                else if ( pos < ps.charsUsed ) {
                    digitPos = pos;
                    badDigitExceptionString = Res.Xml_BadDecimalEntity;
                    while ( chars[pos] >= '0' && chars[pos] <= '9' ) {
                        val = checked(val * 10 + chars[pos] - '0');
                        pos++;
                    }
                    entityType = EntityType.CharacterDec;
                }
                else {
                    // need more data in the buffer
                    entityType = EntityType.Skipped;
                    return -2;
                }
            }
            catch (OverflowException e) {
                ps.charPos = pos;
                entityType = EntityType.Skipped;
                Throw(Res.Xml_CharEntityOverflow, (string)null, e);
            }
                
            if ( chars[pos] != ';' || digitPos == pos) {
                if ( pos == ps.charsUsed ) {
                    // need more data in the buffer
                    return -2;
                }
                else {
                    Throw( pos, badDigitExceptionString );
                }
            }

            // simple character
            if ( val <= char.MaxValue ) {
                char ch = (char)val;
                if ( !xmlCharType.IsCharData(ch) &&
                     ( ( v1Compat && normalize ) || (!v1Compat && checkCharacters ) ) ) {
                    Throw((ps.chars[startPos + 2] == 'x') ? startPos + 3 : startPos + 2, Res.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(ch, '\0'));
                }

                if ( expand ) {
                    if ( internalSubsetBuilder != null ) {
                        internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos + 1 );
                    }
                    chars[pos] = ch;
                }
                charCount = 1;
                return pos + 1;
            }
            // surrogate
            else {
                char low, high;
                XmlCharType.SplitSurrogateChar(val, out low, out high);

                if ( normalize ) {
                    if ( XmlCharType.IsHighSurrogate( high ) ) {
                        if ( XmlCharType.IsLowSurrogate( low ) ) {
                            goto Return;
                        }
                    }
                    Throw((ps.chars[startPos + 2] == 'x') ? startPos + 3 : startPos + 2, Res.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(high, low));
                }

            Return:
                Debug.Assert( pos > 0 );
                if ( expand ) {
                    if ( internalSubsetBuilder != null ) {
                        internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos + 1 );
                    }
                    chars[pos-1] = (char)high;
                    chars[pos] = (char)low;
                }
                charCount = 2;
                return pos + 1;
            }
        }
Ejemplo n.º 15
0
        private void ParseSubset() {
            int startTagEntityId;
            for (;;) {
                Token token = GetToken( false );
                startTagEntityId = currentEntityId;
                switch ( token ) {
                    case Token.AttlistDecl:
                        ParseAttlistDecl();
                        break;

                    case Token.ElementDecl:
                        ParseElementDecl();
                        break;

                    case Token.EntityDecl:
                        ParseEntityDecl();
                        break;

                    case Token.NotationDecl:
                        ParseNotationDecl();
                        break;

                    case Token.Comment:
                        ParseComment();
                        break;

                    case Token.PI:
                        ParsePI();
                        break;

                    case Token.CondSectionStart:
                        if ( ParsingInternalSubset ) {
                            Throw( curPos - 3, Res.Xml_InvalidConditionalSection ); // 3==strlen("<![")
                        }
                        ParseCondSection();
                        startTagEntityId = currentEntityId;
                        break;
                    case Token.CondSectionEnd:
                        if ( condSectionDepth > 0 ) {
                            condSectionDepth--;
#if !SILVERLIGHT
                            if ( validate && currentEntityId != condSectionEntityIds[condSectionDepth] ) {
                                SendValidationEvent( curPos, XmlSeverityType.Error, Res.Sch_ParEntityRefNesting, string.Empty );
                            }
#endif
                        }
                        else {  
                            Throw( curPos - 3, Res.Xml_UnexpectedCDataEnd );
                        }
                        break;
                    case Token.RightBracket:
                        if ( ParsingInternalSubset ) {
                            if ( condSectionDepth != 0 ) {
                                Throw( curPos, Res.Xml_UnclosedConditionalSection );
                            }
                            // append the rest to internal subset value but not the closing ']'
                            if ( internalSubsetValueSb != null ) {
                                Debug.Assert( curPos > 0 && chars[curPos-1] == ']' );
                                SaveParsingBuffer( curPos - 1 );
                                schemaInfo.InternalDtdSubset = internalSubsetValueSb.ToString();
                                internalSubsetValueSb = null;
                            }
                            // check '>'
                            if ( GetToken( false ) != Token.GreaterThan ) {
                                ThrowUnexpectedToken( curPos, ">" );
                            }
#if DEBUG
                            // check entity nesting
                            Debug.Assert( readerAdapter.EntityStackLength == 0 || 
                                          ( freeFloatingDtd && readerAdapter.EntityStackLength == 1 ) );
#endif
                        }
                        else {
                            Throw( curPos, Res.Xml_ExpectDtdMarkup );
                        }
                        return;
                    case Token.Eof:
                        if ( ParsingInternalSubset && !freeFloatingDtd ) {
                            Throw( curPos, Res.Xml_IncompleteDtdContent );
                        }
                        if ( condSectionDepth != 0 ) {
                            Throw( curPos, Res.Xml_UnclosedConditionalSection );
                        }
                        return;
                    default:
                        Debug.Assert( false );
                        break;
                }

                Debug.Assert( scanningFunction == ScanningFunction.SubsetContent );

                if ( currentEntityId != startTagEntityId ) {
#if SILVERLIGHT
                    Throw(curPos, Res.Sch_ParEntityRefNesting);
#else
                    if ( validate ) {
                        SendValidationEvent( curPos, XmlSeverityType.Error, Res.Sch_ParEntityRefNesting, string.Empty );
                    }
                    else {
                        if ( !v1Compat ) {
                            Throw( curPos, Res.Sch_ParEntityRefNesting );
                        }
                    }
#endif
                }
            }
        }
Ejemplo n.º 16
0
        // Parses named character entity reference (&amp; &apos; &lt; &gt; &quot;).
        // Returns -1 if the reference is not a character entity reference.
        // Returns -2 if more data is needed in the buffer
        // Otherwise 
        //      - replaces the last character of the entity reference (';') with the referenced character (if expand == true)
        //      - returns position of the end of the character reference, that is of the character next to the original ';'
        private int ParseNamedCharRefInline( int startPos, bool expand, BufferBuilder internalSubsetBuilder ) {
            Debug.Assert( startPos < ps.charsUsed );
            Debug.Assert( ps.chars[startPos] == '&' );
            Debug.Assert( ps.chars[startPos + 1] != '#' );

            int pos = startPos + 1;
            char[] chars = ps.chars;
            char ch;

            switch ( chars[pos] ) {
                // &apos; or &amp; 
                case 'a':
                    pos++;
                    // &amp;
                    if ( chars[pos] == 'm' ) {
                        if ( ps.charsUsed - pos >= 3 ) {
                            if ( chars[pos+1] == 'p' && chars[pos+2] == ';' ) {
                                pos += 3;
                                ch = '&';
                                goto FoundCharRef;
                            }
                            else {
                                return -1;
                            }
                        }
                    }
                    // &apos;
                    else if ( chars[pos] == 'p' ) {
                        if ( ps.charsUsed - pos >= 4 ) {
                            if ( chars[pos+1] == 'o' && chars[pos+2] == 's' &&
                                    chars[pos+3] == ';' ) {
                                pos += 4;
                                ch = '\'';
                                goto FoundCharRef;
                            }
                            else {
                                return -1;
                            }
                        }
                    }
                    else if ( pos < ps.charsUsed ) {
                        return -1;
                    }
                    break;
                // &guot;
                case 'q':
                    if ( ps.charsUsed - pos >= 5 ) {
                        if ( chars[pos+1] == 'u' && chars[pos+2] == 'o' &&
                                chars[pos+3] == 't' && chars[pos+4] == ';' ) {
                            pos += 5;
                            ch = '"';
                            goto FoundCharRef;
                        }
                        else {
                            return -1;
                        }
                    }
                    break;
                // &lt;
                case 'l':
                    if ( ps.charsUsed - pos >= 3 ) {
                        if ( chars[pos+1] == 't' && chars[pos+2] == ';' ) {
                            pos += 3;
                            ch = '<';
                            goto FoundCharRef;
                        }
                        else {
                            return -1;
                        }
                    }
                    break;
                // &gt;
                case 'g':
                    if ( ps.charsUsed - pos >= 3 ) {
                        if ( chars[pos+1] == 't' && chars[pos+2] == ';' ) {
                            pos += 3;
                            ch = '>';
                            goto FoundCharRef;
                        }
                        else {
                            return -1;
                        }
                    }
                    break;
                default:
                    return -1;
            }

            // need more data in the buffer
            return -2;

        FoundCharRef:
            Debug.Assert( pos > 0 );
            if ( expand ) {
                if ( internalSubsetBuilder != null ) {
                    internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos );
                }
                ps.chars[pos-1] = ch;
            }
            return pos;
        }
Ejemplo n.º 17
0
        // Parses processing instruction; if piInDtdStringBuilder != null, the processing instruction is in DTD and
        // it will be saved in the passed string builder (target, whitespace & value).
        private async Task<bool> ParsePIAsync(BufferBuilder piInDtdStringBuilder)
        {
            if (_parsingMode == ParsingMode.Full)
            {
                _curNode.SetLineInfo(_ps.LineNo, _ps.LinePos);
            }

            Debug.Assert(_stringBuilder.Length == 0);

            // parse target name
            int nameEndPos = await ParseNameAsync().ConfigureAwait(false);
            string target = _nameTable.Add(_ps.chars, _ps.charPos, nameEndPos - _ps.charPos);

            if (string.Equals(target, "xml", StringComparison.OrdinalIgnoreCase))
            {
                Throw(target.Equals("xml") ? SR.Xml_XmlDeclNotFirst : SR.Xml_InvalidPIName, target);
            }
            _ps.charPos = nameEndPos;

            if (piInDtdStringBuilder == null)
            {
                if (!_ignorePIs && _parsingMode == ParsingMode.Full)
                {
                    _curNode.SetNamedNode(XmlNodeType.ProcessingInstruction, target);
                }
            }
            else
            {
                piInDtdStringBuilder.Append(target);
            }

            // check mandatory whitespace
            char ch = _ps.chars[_ps.charPos];
            Debug.Assert(_ps.charPos < _ps.charsUsed);
            if (await EatWhitespacesAsync(piInDtdStringBuilder).ConfigureAwait(false) == 0)
            {
                if (_ps.charsUsed - _ps.charPos < 2)
                {
                    await ReadDataAsync().ConfigureAwait(false);
                }
                if (ch != '?' || _ps.chars[_ps.charPos + 1] != '>')
                {
                    Throw(SR.Xml_BadNameChar, XmlException.BuildCharExceptionArgs(_ps.chars, _ps.charsUsed, _ps.charPos));
                }
            }

            // scan processing instruction value
            int startPos, endPos;

            var tuple_18 = await ParsePIValueAsync().ConfigureAwait(false);
            startPos = tuple_18.Item1;
            endPos = tuple_18.Item2;

            if (tuple_18.Item3)
            {
                if (piInDtdStringBuilder == null)
                {
                    if (_ignorePIs)
                    {
                        return false;
                    }
                    if (_parsingMode == ParsingMode.Full)
                    {
                        _curNode.SetValue(_ps.chars, startPos, endPos - startPos);
                    }
                }
                else
                {
                    piInDtdStringBuilder.Append(_ps.chars, startPos, endPos - startPos);
                }
            }
            else
            {
                BufferBuilder sb;
                if (piInDtdStringBuilder == null)
                {
                    if (_ignorePIs || _parsingMode != ParsingMode.Full)
                    {
                        ValueTuple<int, int, bool> tuple_19;
                        do
                        {
                            tuple_19 = await ParsePIValueAsync().ConfigureAwait(false);
                            startPos = tuple_19.Item1;
                            endPos = tuple_19.Item2;
                        } while (!tuple_19.Item3);

                        return false;
                    }
                    sb = _stringBuilder;
                    Debug.Assert(_stringBuilder.Length == 0);
                }
                else
                {
                    sb = piInDtdStringBuilder;
                }

                ValueTuple<int, int, bool> tuple_20;

                do
                {
                    sb.Append(_ps.chars, startPos, endPos - startPos);

                    tuple_20 = await ParsePIValueAsync().ConfigureAwait(false);
                    startPos = tuple_20.Item1;
                    endPos = tuple_20.Item2;
                } while (!tuple_20.Item3);

                sb.Append(_ps.chars, startPos, endPos - startPos);

                if (piInDtdStringBuilder == null)
                {
                    _curNode.SetValue(_stringBuilder.ToString());
                    _stringBuilder.Length = 0;
                }
            }
            return true;
        }
Ejemplo n.º 18
0
        private void ParseSubset()
        {
            int startTagEntityId;
            for (; ;)
            {
                Token token = GetToken(false);
                startTagEntityId = _currentEntityId;
                switch (token)
                {
                    case Token.AttlistDecl:
                        ParseAttlistDecl();
                        break;

                    case Token.ElementDecl:
                        ParseElementDecl();
                        break;

                    case Token.EntityDecl:
                        ParseEntityDecl();
                        break;

                    case Token.NotationDecl:
                        ParseNotationDecl();
                        break;

                    case Token.Comment:
                        ParseComment();
                        break;

                    case Token.PI:
                        ParsePI();
                        break;

                    case Token.CondSectionStart:
                        if (ParsingInternalSubset)
                        {
                            Throw(_curPos - 3, SR.Xml_InvalidConditionalSection); // 3==strlen("<![")
                        }
                        ParseCondSection();
                        startTagEntityId = _currentEntityId;
                        break;
                    case Token.CondSectionEnd:
                        if (_condSectionDepth > 0)
                        {
                            _condSectionDepth--;
                        }
                        else
                        {
                            Throw(_curPos - 3, SR.Xml_UnexpectedCDataEnd);
                        }
                        break;
                    case Token.RightBracket:
                        if (ParsingInternalSubset)
                        {
                            if (_condSectionDepth != 0)
                            {
                                Throw(_curPos, SR.Xml_UnclosedConditionalSection);
                            }
                            // append the rest to internal subset value but not the closing ']'
                            if (_internalSubsetValueSb != null)
                            {
                                Debug.Assert(_curPos > 0 && _chars[_curPos - 1] == ']');
                                SaveParsingBuffer(_curPos - 1);
                                _schemaInfo.InternalDtdSubset = _internalSubsetValueSb.ToString();
                                _internalSubsetValueSb = null;
                            }
                            // check '>'
                            if (GetToken(false) != Token.GreaterThan)
                            {
                                ThrowUnexpectedToken(_curPos, ">");
                            }
#if DEBUG
                            // check entity nesting
                            Debug.Assert(_readerAdapter.EntityStackLength == 0 ||
                                          (_freeFloatingDtd && _readerAdapter.EntityStackLength == 1));
#endif
                        }
                        else
                        {
                            Throw(_curPos, SR.Xml_ExpectDtdMarkup);
                        }
                        return;
                    case Token.Eof:
                        if (ParsingInternalSubset && !_freeFloatingDtd)
                        {
                            Throw(_curPos, SR.Xml_IncompleteDtdContent);
                        }
                        if (_condSectionDepth != 0)
                        {
                            Throw(_curPos, SR.Xml_UnclosedConditionalSection);
                        }
                        return;
                    default:
                        Debug.Assert(false);
                        break;
                }

                Debug.Assert(_scanningFunction == ScanningFunction.SubsetContent);

                if (_currentEntityId != startTagEntityId)
                {
                    Throw(_curPos, SR.Sch_ParEntityRefNesting);
                }
            }
        }
Ejemplo n.º 19
0
        // Parses numeric character entity reference (e.g. &#32; &#x20;).
        //      - replaces the last one or two character of the entity reference (';' and the character before) with the referenced 
        //        character or surrogates pair (if expand == true)
        //      - returns position of the end of the character reference, that is of the character next to the original ';'
        //      - if (expand == true) then ps.charPos is changed to point to the replaced character

        private async Task<ValueTuple<EntityType, int>> ParseNumericCharRefAsync(bool expand, BufferBuilder internalSubsetBuilder)
        {
            EntityType entityType;

            for (; ;)
            {
                int newPos;
                int charCount;
                switch (newPos = ParseNumericCharRefInline(_ps.charPos, expand, internalSubsetBuilder, out charCount, out entityType))
                {
                    case -2:
                        // read new characters in the buffer
                        if (await ReadDataAsync().ConfigureAwait(false) == 0)
                        {
                            Throw(SR.Xml_UnexpectedEOF);
                        }
                        Debug.Assert(_ps.chars[_ps.charPos] == '&');
                        continue;
                    default:
                        if (expand)
                        {
                            _ps.charPos = newPos - charCount;
                        }

                        return new ValueTuple<EntityType, int>(entityType, newPos);
                }
            }
        }
Ejemplo n.º 20
0
        //
        // Constructors
        //


        // This constructor is used when creating XmlTextReaderImpl reader via "XmlReader.Create(..)"
        private XmlTextReaderImpl(XmlResolver resolver, XmlReaderSettings settings, XmlParserContext context)
        {
            _useAsync = settings.Async;
            _v1Compat = false;
            _outerReader = this;

            _xmlContext = new XmlContext();

            // create or get nametable and namespace manager from XmlParserContext
            XmlNameTable nt = settings.NameTable;
            if (context == null)
            {
                if (nt == null)
                {
                    nt = new NameTable();
                    Debug.Assert(_nameTableFromSettings == false);
                }
                else
                {
                    _nameTableFromSettings = true;
                }
                _nameTable = nt;
                _namespaceManager = new XmlNamespaceManager(nt);
            }
            else
            {
                SetupFromParserContext(context, settings);
                nt = _nameTable;
            }

            nt.Add(string.Empty);
            _xml = nt.Add("xml");
            _xmlNs = nt.Add("xmlns");

            _xmlResolver = resolver;

            Debug.Assert(_index == 0);

            _nodes = new NodeData[NodesInitialSize];
            _nodes[0] = new NodeData();
            _curNode = _nodes[0];

            _stringBuilder = new BufferBuilder();


            _whitespaceHandling = (settings.IgnoreWhitespace) ? WhitespaceHandling.Significant : WhitespaceHandling.All;
            _normalize = true;
            _ignorePIs = settings.IgnoreProcessingInstructions;
            _ignoreComments = settings.IgnoreComments;
            _checkCharacters = settings.CheckCharacters;
            _lineNumberOffset = settings.LineNumberOffset;
            _linePositionOffset = settings.LinePositionOffset;
            _ps.lineNo = _lineNumberOffset + 1;
            _ps.lineStartPos = -_linePositionOffset - 1;
            _curNode.SetLineInfo(_ps.LineNo - 1, _ps.LinePos - 1);
            _dtdProcessing = settings.DtdProcessing;
            _maxCharactersInDocument = settings.MaxCharactersInDocument;
            _maxCharactersFromEntities = settings.MaxCharactersFromEntities;

            _charactersInDocument = 0;
            _charactersFromEntities = 0;

            _fragmentParserContext = context;

            _parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl;
            _nextParsingFunction = ParsingFunction.DocumentContent;

            switch (settings.ConformanceLevel)
            {
                case ConformanceLevel.Auto:
                    _fragmentType = XmlNodeType.None;
                    break;
                case ConformanceLevel.Fragment:
                    _fragmentType = XmlNodeType.Element;
                    break;
                case ConformanceLevel.Document:
                    _fragmentType = XmlNodeType.Document;
                    break;
                default:
                    Debug.Assert(false);
                    goto case ConformanceLevel.Document;
            }
        }
Ejemplo n.º 21
0
 // Parses named character entity reference (&amp; &apos; &lt; &gt; &quot;).
 // Returns -1 if the reference is not a character entity reference.
 // Otherwise 
 //      - replaces the last character of the entity reference (';') with the referenced character (if expand == true)
 //      - returns position of the end of the character reference, that is of the character next to the original ';'
 //      - if (expand == true) then ps.charPos is changed to point to the replaced character
 private async Task<int> ParseNamedCharRefAsync(bool expand, BufferBuilder internalSubsetBuilder)
 {
     for (; ;)
     {
         int newPos;
         switch (newPos = ParseNamedCharRefInline(_ps.charPos, expand, internalSubsetBuilder))
         {
             case -1:
                 return -1;
             case -2:
                 // read new characters in the buffer
                 if (await ReadDataAsync().ConfigureAwait(false) == 0)
                 {
                     return -1;
                 }
                 Debug.Assert(_ps.chars[_ps.charPos] == '&');
                 continue;
             default:
                 if (expand)
                 {
                     _ps.charPos = newPos - 1;
                 }
                 return newPos;
         }
     }
 }
Ejemplo n.º 22
0
 internal int DtdParserProxy_ParseNumericCharRef( BufferBuilder internalSubsetBuilder ) {
     EntityType entType;
     return this.ParseNumericCharRef( true, internalSubsetBuilder, out entType );
 }
Ejemplo n.º 23
0
        internal async Task<int> DtdParserProxy_ParseNumericCharRefAsync(BufferBuilder internalSubsetBuilder)
        {
            CheckAsyncCall();

            var tuple_1 = await this.ParseNumericCharRefAsync(true, internalSubsetBuilder).ConfigureAwait(false);
            return tuple_1.Item2;
        }
Ejemplo n.º 24
0
 internal void DtdParserProxy_ParsePI( BufferBuilder sb ) {
     if ( sb == null ) {
         ParsingMode pm = parsingMode;
         parsingMode = ParsingMode.SkipNode;
         ParsePI( null );
         parsingMode = pm;
     }
     else {
         ParsePI( sb );
     }
 }
Ejemplo n.º 25
0
 internal Task<int> DtdParserProxy_ParseNamedCharRefAsync(bool expand, BufferBuilder internalSubsetBuilder)
 {
     CheckAsyncCall();
     return this.ParseNamedCharRefAsync(expand, internalSubsetBuilder);
 }
Ejemplo n.º 26
0
        // Initializes a new instance of the XmlTextReaderImpl class with the specified XmlNameTable.
        // This constructor is used when creating XmlTextReaderImpl for V1 XmlTextReader
        internal XmlTextReaderImpl( XmlNameTable nt ) {
            Debug.Assert( nt != null );

            v1Compat = true;
            outerReader = this;

            nameTable = nt;
            nt.Add( string.Empty );

            xmlResolver = new XmlUrlResolver();

            Xml = nt.Add( "xml" );
            XmlNs = nt.Add( "xmlns" );

            Debug.Assert( index == 0 );
            nodes = new NodeData[ NodesInitialSize ];
            nodes[0] = new NodeData();
            curNode = nodes[0];

            stringBuilder = new BufferBuilder();
            xmlContext = new XmlContext();

            parsingFunction = ParsingFunction.SwitchToInteractiveXmlDecl;
            nextParsingFunction = ParsingFunction.DocumentContent;

            entityHandling = EntityHandling.ExpandCharEntities;
            whitespaceHandling = WhitespaceHandling.All;
            closeInput = true;

            maxCharactersInDocument = 0;
            // Breaking change: entity expansion is enabled, but limit it to 10,000,000 chars (like XLinq)
            maxCharactersFromEntities = (long)1e7;
            charactersInDocument = 0;
            charactersFromEntities = 0;

            ps.lineNo = 1;
            ps.lineStartPos = -1;
        }
Ejemplo n.º 27
0
 internal async Task DtdParserProxy_ParsePIAsync(BufferBuilder sb)
 {
     CheckAsyncCall();
     if (sb == null)
     {
         ParsingMode pm = _parsingMode;
         _parsingMode = ParsingMode.SkipNode;
         await ParsePIAsync(null).ConfigureAwait(false);
         _parsingMode = pm;
     }
     else
     {
         await ParsePIAsync(sb).ConfigureAwait(false);
     }
 }
Ejemplo n.º 28
0
        // Parses processing instruction; if piInDtdStringBuilder != null, the processing instruction is in DTD and
        // it will be saved in the passed string builder (target, whitespace & value).
        private bool ParsePI( BufferBuilder piInDtdStringBuilder ) {
            if ( parsingMode == ParsingMode.Full ) {
                curNode.SetLineInfo( ps.LineNo, ps.LinePos );
            }

            Debug.Assert( stringBuilder.Length == 0 );

            // parse target name
            int nameEndPos = ParseName();
            string target = nameTable.Add( ps.chars, ps.charPos, nameEndPos - ps.charPos );

            if ( string.Compare( target, "xml", StringComparison.OrdinalIgnoreCase ) == 0 ) {
                Throw( target.Equals( "xml" ) ? Res.Xml_XmlDeclNotFirst : Res.Xml_InvalidPIName, target );
            }
            ps.charPos = nameEndPos;

            if ( piInDtdStringBuilder == null ) {
                if ( !ignorePIs && parsingMode == ParsingMode.Full ) {
                    curNode.SetNamedNode( XmlNodeType.ProcessingInstruction, target );
                }
            }
            else {
                piInDtdStringBuilder.Append( target );
            }

            // check mandatory whitespace
            char ch = ps.chars[ps.charPos];
            Debug.Assert( ps.charPos < ps.charsUsed );
            if ( EatWhitespaces( piInDtdStringBuilder ) == 0 ) {
                if ( ps.charsUsed - ps.charPos < 2 ) {
                    ReadData();
                }
                if ( ch != '?' || ps.chars[ps.charPos+1] != '>' ) {
                    Throw( Res.Xml_BadNameChar, XmlException.BuildCharExceptionArgs( ps.chars, ps.charsUsed, ps.charPos ) );
                }
            }

            // scan processing instruction value
            int startPos, endPos;
            if ( ParsePIValue( out startPos, out endPos ) ) {
                if ( piInDtdStringBuilder == null ) {
                    if ( ignorePIs ) {
                        return false;
                    }
                    if ( parsingMode == ParsingMode.Full ) {
                        curNode.SetValue( ps.chars, startPos, endPos - startPos );
                    }
                }
                else {
                    piInDtdStringBuilder.Append( ps.chars, startPos, endPos - startPos );
                }
            }
            else {
                BufferBuilder sb;
                if ( piInDtdStringBuilder == null ) {
                    if ( ignorePIs || parsingMode != ParsingMode.Full ) {
                        while ( !ParsePIValue( out startPos, out endPos ) );
                        return false;
                    }
                    sb = stringBuilder;
                    Debug.Assert( stringBuilder.Length == 0 );
                }
                else {
                    sb = piInDtdStringBuilder;
                }

                do {
                    sb.Append( ps.chars, startPos, endPos - startPos );
                } while ( !ParsePIValue( out startPos, out endPos ) );
                sb.Append( ps.chars, startPos, endPos - startPos );

                if ( piInDtdStringBuilder == null ) {
                    curNode.SetValue( stringBuilder.ToString() );
                    stringBuilder.Length = 0;
                }
            }
            return true;
        }
Ejemplo n.º 29
0
        internal async Task DtdParserProxy_ParseCommentAsync(BufferBuilder sb)
        {
            CheckAsyncCall();
            Debug.Assert(_parsingMode == ParsingMode.Full);

            try
            {
                if (sb == null)
                {
                    ParsingMode savedParsingMode = _parsingMode;
                    _parsingMode = ParsingMode.SkipNode;
                    await ParseCDataOrCommentAsync(XmlNodeType.Comment).ConfigureAwait(false);
                    _parsingMode = savedParsingMode;
                }
                else
                {
                    NodeData originalCurNode = _curNode;

                    _curNode = AddNode(_index + _attrCount + 1, _index);
                    await ParseCDataOrCommentAsync(XmlNodeType.Comment).ConfigureAwait(false);
                    _curNode.CopyTo(0, sb);

                    _curNode = originalCurNode;
                }
            }
            catch (XmlException e)
            {
                throw e;
            }
        }
Ejemplo n.º 30
0
 // Parses numeric character entity reference (e.g. &#32; &#x20;).
 //      - replaces the last one or two character of the entity reference (';' and the character before) with the referenced 
 //        character or surrogates pair (if expand == true)
 //      - returns position of the end of the character reference, that is of the character next to the original ';'
 //      - if (expand == true) then ps.charPos is changed to point to the replaced character
 private int ParseNumericCharRef( bool expand, BufferBuilder internalSubsetBuilder, out EntityType entityType ) {
     for (;;) {
         int newPos;
         int charCount;
         switch ( newPos = ParseNumericCharRefInline( ps.charPos, expand, internalSubsetBuilder, out charCount, out entityType ) ) {
             case -2:
                 // read new characters in the buffer
                 if ( ReadData() == 0 ) {
                     Throw( Res.Xml_UnexpectedEOF );
                 }
                 Debug.Assert( ps.chars[ps.charPos] == '&' );
                 continue;
             default:
                 if ( expand ) {
                     ps.charPos = newPos - charCount;
                 }
                 return newPos;
         }
     }
 }
Ejemplo n.º 31
0
        //
        // Initialization methods
        //

        private void Initialize(IDtdParserAdapter readerAdapter)
        {
            Debug.Assert(readerAdapter != null);
            _readerAdapter = readerAdapter;

            _nameTable = readerAdapter.NameTable;


            _schemaInfo = new SchemaInfo();

            _stringBuilder = new BufferBuilder();

            Uri baseUri = readerAdapter.BaseUri;
            if (baseUri != null)
            {
                _documentBaseUri = baseUri.ToString();
            }

            _freeFloatingDtd = false;
        }
Ejemplo n.º 32
0
 // Parses named character entity reference (&amp; &apos; &lt; &gt; &quot;).
 // Returns -1 if the reference is not a character entity reference.
 // Otherwise 
 //      - replaces the last character of the entity reference (';') with the referenced character (if expand == true)
 //      - returns position of the end of the character reference, that is of the character next to the original ';'
 //      - if (expand == true) then ps.charPos is changed to point to the replaced character
 private int ParseNamedCharRef( bool expand, BufferBuilder internalSubsetBuilder ) {
     for (;;) {
         int newPos;
         switch ( newPos = ParseNamedCharRefInline( ps.charPos, expand, internalSubsetBuilder ) ) {
             case -1:
                 return -1;
             case -2:
                 // read new characters in the buffer
                 if ( ReadData() == 0 ) {
                     return -1;
                 }
                 Debug.Assert( ps.chars[ps.charPos] == '&' );
                 continue;
             default:
                 if ( expand ) {
                     ps.charPos = newPos - 1;
                 }
                 return newPos;
         }
     }
 }
Ejemplo n.º 33
0
        private void ParseInDocumentDtd(bool saveInternalSubset)
        {
            LoadParsingBuffer();

            _scanningFunction = ScanningFunction.QName;
            _nextScaningFunction = ScanningFunction.Doctype1;

            // doctype name
            if (GetToken(false) != Token.QName)
            {
                OnUnexpectedError();
            }
            _schemaInfo.DocTypeName = GetNameQualified(true);

            // SYSTEM or PUBLIC id
            Token token = GetToken(false);
            if (token == Token.SYSTEM || token == Token.PUBLIC)
            {
                ParseExternalId(token, Token.DOCTYPE, out _publicId, out _systemId);

                token = GetToken(false);
            }

            switch (token)
            {
                case Token.LeftBracket:
                    if (saveInternalSubset)
                    {
                        SaveParsingBuffer(); // this will cause saving the internal subset right from the point after '['
                        _internalSubsetValueSb = new BufferBuilder();
                    }
                    ParseInternalSubset();
                    break;
                case Token.GreaterThan:
                    break;
                default:
                    OnUnexpectedError();
                    break;
            }
            SaveParsingBuffer();

            if (_systemId != null && _systemId.Length > 0)
            {
                ParseExternalSubset();
            }
        }
Ejemplo n.º 34
0
        internal string InternalReadContentAsString()
        {
            string value = string.Empty;
            BufferBuilder sb = null;
            do
            {
                switch (this.NodeType)
                {
                    case XmlNodeType.Attribute:
                        return this.Value;
                    case XmlNodeType.Text:
                    case XmlNodeType.Whitespace:
                    case XmlNodeType.SignificantWhitespace:
                    case XmlNodeType.CDATA:
                        // merge text content
                        if (value.Length == 0)
                        {
                            value = this.Value;
                        }
                        else
                        {
                            if (sb == null)
                            {
                                sb = new BufferBuilder();
                                sb.Append(value);
                            }
                            sb.Append(this.Value);
                        }
                        break;
                    case XmlNodeType.ProcessingInstruction:
                    case XmlNodeType.Comment:
                    case XmlNodeType.EndEntity:
                        // skip comments, pis and end entity nodes
                        break;
                    case XmlNodeType.EntityReference:
                        if (this.CanResolveEntity)
                        {
                            this.ResolveEntity();
                            break;
                        }
                        goto default;
                    case XmlNodeType.EndElement:
                    default:
                        goto ReturnContent;
                }
            } while ((this.AttributeCount != 0) ? this.ReadAttributeValue() : this.Read());

        ReturnContent:
            return (sb == null) ? value : sb.ToString();
        }
Ejemplo n.º 35
0
 void IDtdParserAdapter.ParsePI(BufferBuilder sb)
 {
     reader.DtdParserProxy_ParsePI(sb);
 }