< prev index next >

src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -134,47 +134,53 @@
 
     }
     ////////////////////////////////////////////////////////////////////
     // Validate while parsing
     ////////////////////////////////////////////////////////////////////
-    static final String ALLOWED_ELEMENTS = "properties, comment, entry";
+    static final String ALLOWED_ELEMENTS = "comment, entry";
     static final String ALLOWED_COMMENT = "comment";
     ////////////////////////////////////////////////////////////////////
     // Handler methods
     ////////////////////////////////////////////////////////////////////
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
+    boolean sawRoot = false; // whether a valid root element exists
     boolean sawComment = false;
     boolean validEntry = false;
-    int rootElem = 0;
     String key;
     String rootElm;
 
     @Override
     public void startElement(String uri, String localName, String qName, Attributes attributes)
         throws SAXException
     {
-        if (rootElem < 2) {
-            rootElem++;
+        if (sawRoot) {
+            if (!ALLOWED_ELEMENTS.contains(qName)) {
+                fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
         }
-
+        } else {
+            // check whether the root has been declared in the DTD
         if (rootElm == null) {
             fatalError(new SAXParseException("An XML properties document must contain"
                     + " the DOCTYPE declaration as defined by java.util.Properties.", null));
         }
 
-        if (rootElem == 1 && !rootElm.equals(qName)) {
+            // check whether the element name matches the declaration
+            if (!rootElm.equals(qName)) {
             fatalError(new SAXParseException("Document root element \"" + qName
                     + "\", must match DOCTYPE root \"" + rootElm + "\"", null));
         }
-        if (!ALLOWED_ELEMENTS.contains(qName)) {
-            fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
+
+            // this is a valid root element
+            sawRoot = true;
         }
+
         if (qName.equals(ELEMENT_ENTRY)) {
             validEntry = true;
             key = attributes.getValue(ATTR_KEY);
             if (key == null) {
-                fatalError(new SAXParseException("Attribute \"key\" is required and must be specified for element type \"entry\"", null));
+                fatalError(new SAXParseException("Attribute \"key\" is required and " +
+                    "must be specified for element type \"entry\"", null));
             }
         } else if (qName.equals(ALLOWED_COMMENT)) {
             if (sawComment) {
                 fatalError(new SAXParseException("Only one comment element may be allowed. "
                         + "The content of element type \"properties\" must match \"(comment?,entry*)\"", null));

@@ -190,35 +196,29 @@
         }
     }
 
     @Override
     public void endElement(String uri, String localName, String qName) throws SAXException {
-        if (!ALLOWED_ELEMENTS.contains(qName)) {
-            fatalError(new SAXParseException("Element: " + qName + " is invalid, must match  \"(comment?,entry*)\".", null));
+        if (!ALLOWED_ELEMENTS.contains(qName) && !ELEMENT_ROOT.equals(qName)) {
+            fatalError(new SAXParseException("Element: " + qName +
+                " is invalid, must match  \"(comment?,entry*)\".", null));
         }
 
         if (validEntry) {
             properties.setProperty(key, buf.toString());
             buf.delete(0, buf.length());
             validEntry = false;
         }
     }
 
     @Override
-    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
-        rootElm = name;
-    }
-
-    @Override
     public InputSource resolveEntity(String pubid, String sysid)
             throws SAXException, IOException {
         {
             if (sysid.equals(PROPS_DTD_URI)) {
-                InputSource is;
-                is = new InputSource(new StringReader(PROPS_DTD));
-                is.setSystemId(PROPS_DTD_URI);
-                return is;
+                // The properties DTD is known to the handler, no need to parse it
+                return null;
             }
             throw new SAXException("Invalid system identifier: " + sysid);
         }
     }
 

@@ -234,6 +234,26 @@
 
     @Override
     public void warning(SAXParseException x) throws SAXException {
         throw x;
     }
+
+    // SAX2 extension from DTDHandler
+
+    @Override
+    public void startDTD (String name, String publicId, String systemId) throws SAXException
+    {
+        if (!ELEMENT_ROOT.equals(name) || !PROPS_DTD_URI.equals(systemId)) {
+            fatalError(new SAXParseException("An XML properties document must contain"
+                + " the DOCTYPE declaration as defined by java.util.Properties.", null));
+        }
+        rootElm = name;
+    }
+
+    @Override
+    public void startInternalSub () throws SAXException
+    {
+        fatalError(new SAXParseException("Internal DTD subset is not allowed. " +
+            "The Properties XML document must have the following DOCTYPE declaration: \n" +
+            PROPS_DTD_DECL, null));
+    }
 }
< prev index next >