Esempio n. 1
0
  /**
   * This method notifies of the start of an entity. The document entity has the pseudo-name of
   * "[xml]" the DTD has the pseudo-name of "[dtd]" parameter entity names start with '%'; and
   * general entities are just specified by their name.
   *
   * @param name The name of the entity.
   * @param identifier The resource identifier.
   * @param encoding The auto-detected IANA encoding name of the entity stream. This value will be
   *     null in those situations where the entity encoding is not auto-detected (e.g. internal
   *     entities or a document entity that is parsed from a java.io.Reader).
   * @throws XNIException Thrown by handler to signal an error.
   */
  public void startEntity(
      String name, XMLResourceIdentifier identifier, String encoding, Augmentations augs)
      throws XNIException {

    // keep track of the entity depth
    fEntityDepth++;
    // must reset entity scanner
    fEntityScanner = fEntityManager.getEntityScanner();
    fEntityStore = fEntityManager.getEntityStore();
  } // startEntity(String,XMLResourceIdentifier,String)
Esempio n. 2
0
  /**
   * @param componentManager The component manager.
   * @throws SAXException Throws exception if required features and properties cannot be found.
   */
  public void reset(XMLComponentManager componentManager) throws XMLConfigurationException {

    fParserSettings = componentManager.getFeature(PARSER_SETTINGS, true);

    if (!fParserSettings) {
      // parser settings have not been changed
      init();
      return;
    }

    // Xerces properties
    fSymbolTable = (SymbolTable) componentManager.getProperty(SYMBOL_TABLE);
    fErrorReporter = (XMLErrorReporter) componentManager.getProperty(ERROR_REPORTER);
    fEntityManager = (XMLEntityManager) componentManager.getProperty(ENTITY_MANAGER);
    fSecurityManager = (XMLSecurityManager) componentManager.getProperty(SECURITY_MANAGER);

    // this step is extra because we have separated the storage of entity
    fEntityStore = fEntityManager.getEntityStore();

    // sax features
    fValidation = componentManager.getFeature(VALIDATION, false);
    fNamespaces = componentManager.getFeature(NAMESPACES, true);
    fNotifyCharRefs = componentManager.getFeature(NOTIFY_CHAR_REFS, false);

    init();
  } // reset(XMLComponentManager)
Esempio n. 3
0
  public void reset(PropertyManager propertyManager) {
    init();
    // Xerces properties
    fSymbolTable =
        (SymbolTable)
            propertyManager.getProperty(
                Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY);

    fErrorReporter =
        (XMLErrorReporter)
            propertyManager.getProperty(
                Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);

    fEntityManager = (XMLEntityManager) propertyManager.getProperty(ENTITY_MANAGER);
    fEntityStore = fEntityManager.getEntityStore();
    fEntityScanner = (XMLEntityScanner) fEntityManager.getEntityScanner();
    // fEntityManager.reset();
    // DTD preparsing defaults:
    fValidation = false;
    fNotifyCharRefs = false;
  }
Esempio n. 4
0
  /**
   * Scans an attribute value and normalizes whitespace converting all whitespace characters to
   * space characters.
   *
   * <p>[10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
   *
   * @param value The XMLString to fill in with the value.
   * @param nonNormalizedValue The XMLString to fill in with the non-normalized value.
   * @param atName The name of the attribute being parsed (for error msgs).
   * @param checkEntities true if undeclared entities should be reported as VC violation, false if
   *     undeclared entities should be reported as WFC violation.
   * @param eleName The name of element to which this attribute belongs.
   *     <p><strong>Note:</strong> This method uses fStringBuffer2, anything in it at the time of
   *     calling is lost.
   */
  protected void scanAttributeValue(
      XMLString value,
      XMLString nonNormalizedValue,
      String atName,
      boolean checkEntities,
      String eleName)
      throws IOException, XNIException {
    // quote
    int quote = fEntityScanner.peekChar();
    if (quote != '\'' && quote != '"') {
      reportFatalError("OpenQuoteExpected", new Object[] {eleName, atName});
    }

    fEntityScanner.scanChar();
    int entityDepth = fEntityDepth;

    int c = fEntityScanner.scanLiteral(quote, value);
    if (DEBUG_ATTR_NORMALIZATION) {
      System.out.println("** scanLiteral -> \"" + value.toString() + "\"");
    }
    fStringBuffer2.clear();
    fStringBuffer2.append(value);
    normalizeWhitespace(value);
    if (DEBUG_ATTR_NORMALIZATION) {
      System.out.println("** normalizeWhitespace -> \"" + value.toString() + "\"");
    }
    if (c != quote) {
      fScanningAttribute = true;
      fStringBuffer.clear();
      do {
        fStringBuffer.append(value);
        if (DEBUG_ATTR_NORMALIZATION) {
          System.out.println("** value2: \"" + fStringBuffer.toString() + "\"");
        }
        if (c == '&') {
          fEntityScanner.skipChar('&');
          if (entityDepth == fEntityDepth) {
            fStringBuffer2.append('&');
          }
          if (fEntityScanner.skipChar('#')) {
            if (entityDepth == fEntityDepth) {
              fStringBuffer2.append('#');
            }
            int ch = scanCharReferenceValue(fStringBuffer, fStringBuffer2);
            if (ch != -1) {
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** value3: \"" + fStringBuffer.toString() + "\"");
              }
            }
          } else {
            String entityName = fEntityScanner.scanName();
            if (entityName == null) {
              reportFatalError("NameRequiredInReference", null);
            } else if (entityDepth == fEntityDepth) {
              fStringBuffer2.append(entityName);
            }
            if (!fEntityScanner.skipChar(';')) {
              reportFatalError("SemicolonRequiredInReference", new Object[] {entityName});
            } else if (entityDepth == fEntityDepth) {
              fStringBuffer2.append(';');
            }
            if (entityName == fAmpSymbol) {
              fStringBuffer.append('&');
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** value5: \"" + fStringBuffer.toString() + "\"");
              }
            } else if (entityName == fAposSymbol) {
              fStringBuffer.append('\'');
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** value7: \"" + fStringBuffer.toString() + "\"");
              }
            } else if (entityName == fLtSymbol) {
              fStringBuffer.append('<');
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** value9: \"" + fStringBuffer.toString() + "\"");
              }
            } else if (entityName == fGtSymbol) {
              fStringBuffer.append('>');
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** valueB: \"" + fStringBuffer.toString() + "\"");
              }
            } else if (entityName == fQuotSymbol) {
              fStringBuffer.append('"');
              if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** valueD: \"" + fStringBuffer.toString() + "\"");
              }
            } else {
              if (fEntityManager.isExternalEntity(entityName)) {
                reportFatalError("ReferenceToExternalEntity", new Object[] {entityName});
              } else {
                if (!fEntityManager.isDeclaredEntity(entityName)) {
                  // WFC & VC: Entity Declared
                  if (checkEntities) {
                    if (fValidation) {
                      fErrorReporter.reportError(
                          XMLMessageFormatter.XML_DOMAIN,
                          "EntityNotDeclared",
                          new Object[] {entityName},
                          XMLErrorReporter.SEVERITY_ERROR);
                    }
                  } else {
                    reportFatalError("EntityNotDeclared", new Object[] {entityName});
                  }
                }
                fEntityManager.startEntity(entityName, true);
              }
            }
          }
        } else if (c == '<') {
          reportFatalError("LessthanInAttValue", new Object[] {eleName, atName});
          fEntityScanner.scanChar();
          if (entityDepth == fEntityDepth) {
            fStringBuffer2.append((char) c);
          }
        } else if (c == '%' || c == ']') {
          fEntityScanner.scanChar();
          fStringBuffer.append((char) c);
          if (entityDepth == fEntityDepth) {
            fStringBuffer2.append((char) c);
          }
          if (DEBUG_ATTR_NORMALIZATION) {
            System.out.println("** valueF: \"" + fStringBuffer.toString() + "\"");
          }
        } else if (c == '\n' || c == '\r') {
          fEntityScanner.scanChar();
          fStringBuffer.append(' ');
          if (entityDepth == fEntityDepth) {
            fStringBuffer2.append('\n');
          }
        } else if (c != -1 && XMLChar.isHighSurrogate(c)) {
          fStringBuffer3.clear();
          if (scanSurrogates(fStringBuffer3)) {
            fStringBuffer.append(fStringBuffer3);
            if (entityDepth == fEntityDepth) {
              fStringBuffer2.append(fStringBuffer3);
            }
            if (DEBUG_ATTR_NORMALIZATION) {
              System.out.println("** valueI: \"" + fStringBuffer.toString() + "\"");
            }
          }
        } else if (c != -1 && isInvalidLiteral(c)) {
          reportFatalError(
              "InvalidCharInAttValue", new Object[] {eleName, atName, Integer.toString(c, 16)});
          fEntityScanner.scanChar();
          if (entityDepth == fEntityDepth) {
            fStringBuffer2.append((char) c);
          }
        }
        c = fEntityScanner.scanLiteral(quote, value);
        if (entityDepth == fEntityDepth) {
          fStringBuffer2.append(value);
        }
        normalizeWhitespace(value);
      } while (c != quote || entityDepth != fEntityDepth);
      fStringBuffer.append(value);
      if (DEBUG_ATTR_NORMALIZATION) {
        System.out.println("** valueN: \"" + fStringBuffer.toString() + "\"");
      }
      value.setValues(fStringBuffer);
      fScanningAttribute = false;
    }
    nonNormalizedValue.setValues(fStringBuffer2);

    // quote
    int cquote = fEntityScanner.scanChar();
    if (cquote != quote) {
      reportFatalError("CloseQuoteExpected", new Object[] {eleName, atName});
    }
  } // scanAttributeValue()
Esempio n. 5
0
  /**
   * Scans a pseudo attribute.
   *
   * @param scanningTextDecl True if scanning this pseudo-attribute for a TextDecl; false if
   *     scanning XMLDecl. This flag is needed to report the correct type of error.
   * @param value The string to fill in with the attribute value.
   * @return The name of the attribute
   *     <p><strong>Note:</strong> This method uses fStringBuffer2, anything in it at the time of
   *     calling is lost.
   */
  public String scanPseudoAttribute(boolean scanningTextDecl, XMLString value)
      throws IOException, XNIException {

    // REVISIT: This method is used for generic scanning of
    // pseudo attributes, but since there are only three such
    // attributes: version, encoding, and standalone there are
    // for performant ways of scanning them. Every decl must
    // have a version, and in TextDecls this version must
    // be followed by an encoding declaration. Also the
    // methods we invoke on the scanners allow non-ASCII
    // characters to be parsed in the decls, but since
    // we don't even know what the actual encoding of the
    // document is until we scan the encoding declaration
    // you cannot reliably read any characters outside
    // of the ASCII range here. -- mrglavas
    String name = fEntityScanner.scanName();
    XMLEntityManager.print(fEntityManager.getCurrentEntity());
    if (name == null) {
      reportFatalError("PseudoAttrNameExpected", null);
    }
    fEntityScanner.skipDeclSpaces();
    if (!fEntityScanner.skipChar('=')) {
      reportFatalError(
          scanningTextDecl ? "EqRequiredInTextDecl" : "EqRequiredInXMLDecl", new Object[] {name});
    }
    fEntityScanner.skipDeclSpaces();
    int quote = fEntityScanner.peekChar();
    if (quote != '\'' && quote != '"') {
      reportFatalError(
          scanningTextDecl ? "QuoteRequiredInTextDecl" : "QuoteRequiredInXMLDecl",
          new Object[] {name});
    }
    fEntityScanner.scanChar();
    int c = fEntityScanner.scanLiteral(quote, value);
    if (c != quote) {
      fStringBuffer2.clear();
      do {
        fStringBuffer2.append(value);
        if (c != -1) {
          if (c == '&' || c == '%' || c == '<' || c == ']') {
            fStringBuffer2.append((char) fEntityScanner.scanChar());
          }
          // REVISIT: Even if you could reliably read non-ASCII chars
          // why bother scanning for surrogates here? Only ASCII chars
          // match the productions in XMLDecls and TextDecls. -- mrglavas
          else if (XMLChar.isHighSurrogate(c)) {
            scanSurrogates(fStringBuffer2);
          } else if (isInvalidLiteral(c)) {
            String key = scanningTextDecl ? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl";
            reportFatalError(key, new Object[] {Integer.toString(c, 16)});
            fEntityScanner.scanChar();
          }
        }
        c = fEntityScanner.scanLiteral(quote, value);
      } while (c != quote);
      fStringBuffer2.append(value);
      value.setValues(fStringBuffer2);
    }
    if (!fEntityScanner.skipChar(quote)) {
      reportFatalError(
          scanningTextDecl ? "CloseQuoteMissingInTextDecl" : "CloseQuoteMissingInXMLDecl",
          new Object[] {name});
    }

    // return
    return name;
  } // scanPseudoAttribute(XMLString):String
Esempio n. 6
0
  /**
   * Scans an XML or text declaration.
   *
   * <p>
   *
   * <pre>
   * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
   * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
   * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
   * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
   * [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
   *                 | ('"' ('yes' | 'no') '"'))
   *
   * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
   * </pre>
   *
   * @param scanningTextDecl True if a text declaration is to be scanned instead of an XML
   *     declaration.
   * @param pseudoAttributeValues An array of size 3 to return the version, encoding and standalone
   *     pseudo attribute values (in that order).
   *     <p><strong>Note:</strong> This method uses fString, anything in it at the time of calling
   *     is lost.
   */
  protected void scanXMLDeclOrTextDecl(boolean scanningTextDecl, String[] pseudoAttributeValues)
      throws IOException, XNIException {

    // pseudo-attribute values
    String version = null;
    String encoding = null;
    String standalone = null;

    // scan pseudo-attributes
    final int STATE_VERSION = 0;
    final int STATE_ENCODING = 1;
    final int STATE_STANDALONE = 2;
    final int STATE_DONE = 3;
    int state = STATE_VERSION;

    boolean dataFoundForTarget = false;
    boolean sawSpace = fEntityScanner.skipDeclSpaces();
    // since pseudoattributes are *not* attributes,
    // their quotes don't need to be preserved in external parameter entities.
    // the XMLEntityScanner#scanLiteral method will continue to
    // emit -1 in such cases when it finds a quote; this is
    // fine for other methods that parse scanned entities,
    // but not for the scanning of pseudoattributes.  So,
    // temporarily, we must mark the current entity as not being "literal"
    XMLEntityManager.ScannedEntity currEnt = fEntityManager.getCurrentEntity();
    boolean currLiteral = currEnt.literal;
    currEnt.literal = false;
    while (fEntityScanner.peekChar() != '?') {
      dataFoundForTarget = true;
      String name = scanPseudoAttribute(scanningTextDecl, fString);
      switch (state) {
        case STATE_VERSION:
          {
            if (name == fVersionSymbol) {
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeVersionInTextDecl"
                        : "SpaceRequiredBeforeVersionInXMLDecl",
                    null);
              }
              version = fString.toString();
              state = STATE_ENCODING;
              if (!versionSupported(version)) {
                reportFatalError(getVersionNotSupportedKey(), new Object[] {version});
              }
            } else if (name == fEncodingSymbol) {
              if (!scanningTextDecl) {
                reportFatalError("VersionInfoRequired", null);
              }
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeEncodingInTextDecl"
                        : "SpaceRequiredBeforeEncodingInXMLDecl",
                    null);
              }
              encoding = fString.toString();
              state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE;
            } else {
              if (scanningTextDecl) {
                reportFatalError("EncodingDeclRequired", null);
              } else {
                reportFatalError("VersionInfoRequired", null);
              }
            }
            break;
          }
        case STATE_ENCODING:
          {
            if (name == fEncodingSymbol) {
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeEncodingInTextDecl"
                        : "SpaceRequiredBeforeEncodingInXMLDecl",
                    null);
              }
              encoding = fString.toString();
              state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE;
              // TODO: check encoding name; set encoding on
              //       entity scanner
            } else if (!scanningTextDecl && name == fStandaloneSymbol) {
              if (!sawSpace) {
                reportFatalError("SpaceRequiredBeforeStandalone", null);
              }
              standalone = fString.toString();
              state = STATE_DONE;
              if (!standalone.equals("yes") && !standalone.equals("no")) {
                reportFatalError("SDDeclInvalid", new Object[] {standalone});
              }
            } else {
              reportFatalError("EncodingDeclRequired", null);
            }
            break;
          }
        case STATE_STANDALONE:
          {
            if (name == fStandaloneSymbol) {
              if (!sawSpace) {
                reportFatalError("SpaceRequiredBeforeStandalone", null);
              }
              standalone = fString.toString();
              state = STATE_DONE;
              if (!standalone.equals("yes") && !standalone.equals("no")) {
                reportFatalError("SDDeclInvalid", new Object[] {standalone});
              }
            } else {
              reportFatalError("EncodingDeclRequired", null);
            }
            break;
          }
        default:
          {
            reportFatalError("NoMorePseudoAttributes", null);
          }
      }
      sawSpace = fEntityScanner.skipDeclSpaces();
    }
    // restore original literal value
    if (currLiteral) currEnt.literal = true;
    // REVISIT: should we remove this error reporting?
    if (scanningTextDecl && state != STATE_DONE) {
      reportFatalError("MorePseudoAttributes", null);
    }

    // If there is no data in the xml or text decl then we fail to report error
    // for version or encoding info above.
    if (scanningTextDecl) {
      if (!dataFoundForTarget && encoding == null) {
        reportFatalError("EncodingDeclRequired", null);
      }
    } else {
      if (!dataFoundForTarget && version == null) {
        reportFatalError("VersionInfoRequired", null);
      }
    }

    // end
    if (!fEntityScanner.skipChar('?')) {
      reportFatalError("XMLDeclUnterminated", null);
    }
    if (!fEntityScanner.skipChar('>')) {
      reportFatalError("XMLDeclUnterminated", null);
    }

    // fill in return array
    pseudoAttributeValues[0] = version;
    pseudoAttributeValues[1] = encoding;
    pseudoAttributeValues[2] = standalone;
  } // scanXMLDeclOrTextDecl(boolean)
Esempio n. 7
0
  /**
   * Scans an XML or text declaration.
   *
   * <p>
   *
   * <pre>
   * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
   * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
   * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
   * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
   * [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
   *                 | ('"' ('yes' | 'no') '"'))
   *
   * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
   * </pre>
   *
   * @param scanningTextDecl True if a text declaration is to be scanned instead of an XML
   *     declaration.
   * @param pseudoAttributeValues An array of size 3 to return the version, encoding and standalone
   *     pseudo attribute values (in that order).
   *     <p><strong>Note:</strong> This method uses fString, anything in it at the time of calling
   *     is lost.
   */
  protected void scanXMLDeclOrTextDecl(boolean scanningTextDecl, String[] pseudoAttributeValues)
      throws IOException, XNIException {

    // pseudo-attribute values
    String version = null;
    String encoding = null;
    String standalone = null;

    // scan pseudo-attributes
    final int STATE_VERSION = 0;
    final int STATE_ENCODING = 1;
    final int STATE_STANDALONE = 2;
    final int STATE_DONE = 3;
    int state = STATE_VERSION;

    boolean dataFoundForTarget = false;
    boolean sawSpace = fEntityScanner.skipSpaces();
    while (fEntityScanner.peekChar() != '?') {
      dataFoundForTarget = true;
      String name = scanPseudoAttribute(scanningTextDecl, fString);
      switch (state) {
        case STATE_VERSION:
          {
            if (name.equals(fVersionSymbol)) {
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeVersionInTextDecl"
                        : "SpaceRequiredBeforeVersionInXMLDecl",
                    null);
              }
              version = fString.toString();
              state = STATE_ENCODING;
              if (!versionSupported(version)) {
                reportFatalError("VersionNotSupported", new Object[] {version});
              }

              if (version.equals("1.1")) {
                Entity.ScannedEntity top = fEntityManager.getTopLevelEntity();
                if (top != null && (top.version == null || top.version.equals("1.0"))) {
                  reportFatalError("VersionMismatch", null);
                }
                fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
              }

            } else if (name.equals(fEncodingSymbol)) {
              if (!scanningTextDecl) {
                reportFatalError("VersionInfoRequired", null);
              }
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeEncodingInTextDecl"
                        : "SpaceRequiredBeforeEncodingInXMLDecl",
                    null);
              }
              encoding = fString.toString();
              state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE;
            } else {
              if (scanningTextDecl) {
                reportFatalError("EncodingDeclRequired", null);
              } else {
                reportFatalError("VersionInfoRequired", null);
              }
            }
            break;
          }
        case STATE_ENCODING:
          {
            if (name.equals(fEncodingSymbol)) {
              if (!sawSpace) {
                reportFatalError(
                    scanningTextDecl
                        ? "SpaceRequiredBeforeEncodingInTextDecl"
                        : "SpaceRequiredBeforeEncodingInXMLDecl",
                    null);
              }
              encoding = fString.toString();
              state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE;
              // TODO: check encoding name; set encoding on
              //       entity scanner
            } else if (!scanningTextDecl && name.equals(fStandaloneSymbol)) {
              if (!sawSpace) {
                reportFatalError("SpaceRequiredBeforeStandalone", null);
              }
              standalone = fString.toString();
              state = STATE_DONE;
              if (!standalone.equals("yes") && !standalone.equals("no")) {
                reportFatalError("SDDeclInvalid", new Object[] {standalone});
              }
            } else {
              reportFatalError("EncodingDeclRequired", null);
            }
            break;
          }
        case STATE_STANDALONE:
          {
            if (name.equals(fStandaloneSymbol)) {
              if (!sawSpace) {
                reportFatalError("SpaceRequiredBeforeStandalone", null);
              }
              standalone = fString.toString();
              state = STATE_DONE;
              if (!standalone.equals("yes") && !standalone.equals("no")) {
                reportFatalError("SDDeclInvalid", new Object[] {standalone});
              }
            } else {
              reportFatalError("EncodingDeclRequired", null);
            }
            break;
          }
        default:
          {
            reportFatalError("NoMorePseudoAttributes", null);
          }
      }
      sawSpace = fEntityScanner.skipSpaces();
    }
    // REVISIT: should we remove this error reporting?
    if (scanningTextDecl && state != STATE_DONE) {
      reportFatalError("MorePseudoAttributes", null);
    }

    // If there is no data in the xml or text decl then we fail to report error
    // for version or encoding info above.
    if (scanningTextDecl) {
      if (!dataFoundForTarget && encoding == null) {
        reportFatalError("EncodingDeclRequired", null);
      }
    } else {
      if (!dataFoundForTarget && version == null) {
        reportFatalError("VersionInfoRequired", null);
      }
    }

    // end
    if (!fEntityScanner.skipChar('?')) {
      reportFatalError("XMLDeclUnterminated", null);
    }
    if (!fEntityScanner.skipChar('>')) {
      reportFatalError("XMLDeclUnterminated", null);
    }

    // fill in return array
    pseudoAttributeValues[0] = version;
    pseudoAttributeValues[1] = encoding;
    pseudoAttributeValues[2] = standalone;
  } // scanXMLDeclOrTextDecl(boolean)