8148872: Complete name checking
authorjoehw
Tue, 16 Feb 2016 10:22:22 -0800
changeset 39798 550955727ef7
parent 39678 5bf88dce615f
child 39799 2847de5336f2
8148872: Complete name checking Reviewed-by: dfuchs, lancea, ahgross
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java	Tue Feb 16 10:22:22 2016 -0800
@@ -184,6 +184,7 @@
      * @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.
+     * @param isNSURI The flag indicating whether the content is a namespace URI
      *
      * @return true if the non-normalized and normalized value are the same
      *
@@ -193,7 +194,7 @@
     protected boolean scanAttributeValue(XMLString value,
                                       XMLString nonNormalizedValue,
                                       String atName,
-                                      boolean checkEntities,String eleName)
+                                      boolean checkEntities,String eleName, boolean isNSURI)
         throws IOException, XNIException
     {
         // quote
@@ -205,7 +206,7 @@
         fEntityScanner.scanChar();
         int entityDepth = fEntityDepth;
 
-        int c = fEntityScanner.scanLiteral(quote, value);
+        int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
         if (DEBUG_ATTR_NORMALIZATION) {
             System.out.println("** scanLiteral -> \""
                                + value.toString() + "\"");
@@ -387,7 +388,7 @@
                         fStringBuffer2.append((char)c);
                     }
                 }
-                c = fEntityScanner.scanLiteral(quote, value);
+                c = fEntityScanner.scanLiteral(quote, value, isNSURI);
                 if (entityDepth == fEntityDepth) {
                     fStringBuffer2.append(value);
                 }
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java	Tue Feb 16 10:22:22 2016 -0800
@@ -310,23 +310,11 @@
             return null;
         }
 
+        int length = 0;
         do {
             ch = fCurrentEntity.ch[fCurrentEntity.position];
             if (XML11Char.isXML11Name(ch)) {
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
                     offset = 0;
                     if (load(length, false, false)) {
                         break;
@@ -334,20 +322,7 @@
                 }
             }
             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
                     offset = 0;
                     if (load(length, false, false)) {
                         --fCurrentEntity.position;
@@ -361,20 +336,7 @@
                     --fCurrentEntity.position;
                     break;
                 }
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
                     offset = 0;
                     if (load(length, false, false)) {
                         break;
@@ -387,12 +349,13 @@
         }
         while (true);
 
-        int length = fCurrentEntity.position - offset;
+        length = fCurrentEntity.position - offset;
         fCurrentEntity.columnNumber += length;
 
         // return name
         String symbol = null;
         if (length > 0) {
+            checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
         }
         return symbol;
@@ -641,6 +604,7 @@
         }
 
         int index = -1;
+        int length = 0;
         boolean sawIncompleteSurrogatePair = false;
         do {
             ch = fCurrentEntity.ch[fCurrentEntity.position];
@@ -653,22 +617,7 @@
                     //check prefix before further read
                     checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset);
                 }
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    //check localpart before loading more data
-                    checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1);
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
                     if (index != -1) {
                         index = index - offset;
                     }
@@ -679,20 +628,7 @@
                 }
             }
             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
                     if (index != -1) {
                         index = index - offset;
                     }
@@ -711,20 +647,7 @@
                     --fCurrentEntity.position;
                     break;
                 }
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.ch.length) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.ch.length << 1];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                    }
-                    else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                         fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
                     if (index != -1) {
                         index = index - offset;
                     }
@@ -740,7 +663,7 @@
         }
         while (true);
 
-        int length = fCurrentEntity.position - offset;
+        length = fCurrentEntity.position - offset;
         fCurrentEntity.columnNumber += length;
 
         if (length > 0) {
@@ -945,6 +868,7 @@
      * @param quote   The quote character that signifies the end of the
      *                attribute value data.
      * @param content The content structure to fill.
+     * @param isNSURI a flag indicating whether the content is a Namespace URI
      *
      * @return Returns the next character on the input, if known. This
      *         value may be -1 but this does <em>note</em> designate
@@ -953,7 +877,7 @@
      * @throws IOException  Thrown if i/o error occurs.
      * @throws EOFException Thrown on end of file.
      */
-    public int scanLiteral(int quote, XMLString content)
+    public int scanLiteral(int quote, XMLString content, boolean isNSURI)
         throws IOException {
         // load more characters, if needed
         if (fCurrentEntity.position == fCurrentEntity.count) {
@@ -1054,6 +978,9 @@
         if (fCurrentEntity.isGE) {
             checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length);
         }
+        if (isNSURI) {
+            checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
+        }
         content.setValues(fCurrentEntity.ch, offset, length);
 
         // return next character
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java	Tue Feb 16 10:22:22 2016 -0800
@@ -614,13 +614,20 @@
         //REVISIT: one more case needs to be included: external PE and standalone is no
         boolean isVC = fHasExternalDTD && !fStandalone;
 
-        // REVISIT: it seems that this function should not take attributes, and length
-        scanAttributeValue(
-            this.fTempString,
-            fTempString2,
-            fAttributeQName.rawname,
-            isVC,
-            fCurrentElement.rawname);
+        /**
+         * Determine whether this is a namespace declaration that will be subject
+         * to the name limit check in the scanAttributeValue operation.
+         * Namespace declaration format: xmlns="..." or xmlns:prefix="..."
+         * Note that prefix:xmlns="..." isn't a namespace.
+         */
+        String localpart = fAttributeQName.localpart;
+        String prefix = fAttributeQName.prefix != null
+                ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
+        boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
+                    prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
+
+        scanAttributeValue(this.fTempString, fTempString2, fAttributeQName.rawname,
+            isVC, fCurrentElement.rawname, isNSDecl);
         String value = fTempString.toString();
         attributes.setValue(attrIndex, value);
         attributes.setNonNormalizedValue(attrIndex, fTempString2.toString());
@@ -628,17 +635,7 @@
 
         // record namespace declarations if any.
         if (fBindNamespaces) {
-
-            String localpart = fAttributeQName.localpart;
-            String prefix =
-                fAttributeQName.prefix != null
-                    ? fAttributeQName.prefix
-                    : XMLSymbols.EMPTY_STRING;
-            // when it's of form xmlns="..." or xmlns:prefix="...",
-            // it's a namespace declaration. but prefix:xmlns="..." isn't.
-            if (prefix == XMLSymbols.PREFIX_XMLNS
-                || prefix == XMLSymbols.EMPTY_STRING
-                && localpart == XMLSymbols.PREFIX_XMLNS) {
+            if (isNSDecl) {
                 if (value.length() > fXMLNameLimit) {
                     fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                             "MaxXMLNameLimit",
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java	Tue Feb 16 10:22:22 2016 -0800
@@ -1447,7 +1447,7 @@
             // AttValue
             boolean isVC = !fStandalone  &&  (fSeenExternalDTD || fSeenExternalPE) ;
             scanAttributeValue(defaultVal, nonNormalizedDefaultVal, atName,
-            fAttributes, 0, isVC, elName);
+            fAttributes, 0, isVC, elName, false);
         }
         return defaultType;
 
@@ -1665,7 +1665,7 @@
          }
         fLimitAnalyzer.startEntity(entityName);
 
-        if (fEntityScanner.scanLiteral(quote, fString) != quote) {
+        if (fEntityScanner.scanLiteral(quote, fString, false) != quote) {
             fStringBuffer.clear();
             fStringBuffer2.clear();
             do {
@@ -1749,7 +1749,7 @@
                         fEntityScanner.scanChar();
                     }
                 }
-            } while (fEntityScanner.scanLiteral(quote, fString) != quote);
+            } while (fEntityScanner.scanLiteral(quote, fString, false) != quote);
             fStringBuffer.append(fString);
             fStringBuffer2.append(fString);
             literal = fStringBuffer;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Tue Feb 16 10:22:22 2016 -0800
@@ -1544,9 +1544,8 @@
         //can safely add the attribute later..
         XMLString tmpStr = getString();
 
-        scanAttributeValue(tmpStr, fTempString2,
-                fAttributeQName.rawname, attributes,
-                attIndex, isVC, fCurrentElement.rawname);
+        scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes,
+                attIndex, isVC, fCurrentElement.rawname, false);
 
         // content
         int oldLen = attributes.getLength();
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java	Tue Feb 16 10:22:22 2016 -0800
@@ -682,6 +682,7 @@
 
         // scan name
         int offset = fCurrentEntity.position;
+        int length;
         if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
             if (++fCurrentEntity.position == fCurrentEntity.count) {
                 invokeListeners(1);
@@ -709,20 +710,7 @@
                     vc = XMLChar.isName(c);
                 }
                 if(!vc)break;
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.fBufferSize) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                        fCurrentEntity.fBufferSize *= 2;
-                    } else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
                     offset = 0;
                     if (load(length, false, false)) {
                         break;
@@ -730,12 +718,13 @@
                 }
             }
         }
-        int length = fCurrentEntity.position - offset;
+        length = fCurrentEntity.position - offset;
         fCurrentEntity.columnNumber += length;
 
         // return name
         String symbol;
         if (length > 0) {
+            checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
         } else
             symbol = null;
@@ -811,6 +800,7 @@
             }
             int index = -1;
             boolean vc = false;
+            int length;
             while ( true){
 
                 //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
@@ -829,22 +819,7 @@
                     //check prefix before further read
                     checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset);
                 }
-                if (++fCurrentEntity.position == fCurrentEntity.count) {
-                    int length = fCurrentEntity.position - offset;
-                    //check localpart before loading more data
-                    checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1);
-                    invokeListeners(length);
-                    if (length == fCurrentEntity.fBufferSize) {
-                        // bad luck we have to resize our buffer
-                        char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                tmp, 0, length);
-                        fCurrentEntity.ch = tmp;
-                        fCurrentEntity.fBufferSize *= 2;
-                    } else {
-                        System.arraycopy(fCurrentEntity.ch, offset,
-                                fCurrentEntity.ch, 0, length);
-                    }
+                if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
                     if (index != -1) {
                         index = index - offset;
                     }
@@ -854,7 +829,7 @@
                     }
                 }
             }
-            int length = fCurrentEntity.position - offset;
+            length = fCurrentEntity.position - offset;
             fCurrentEntity.columnNumber += length;
             if (length > 0) {
                 String prefix = null;
@@ -900,6 +875,45 @@
     } // scanQName(QName):boolean
 
     /**
+     * Checks whether the end of the entity buffer has been reached. If yes,
+     * checks against the limit and buffer size before loading more characters.
+     *
+     * @param entity the current entity
+     * @param offset the offset from which the current read was started
+     * @param nameOffset the offset from which the current name starts
+     * @return the length of characters scanned before the end of the buffer,
+     * zero if there is more to be read in the buffer
+     */
+    protected int checkBeforeLoad(Entity.ScannedEntity entity, int offset,
+            int nameOffset) throws IOException {
+        int length = 0;
+        if (++entity.position == entity.count) {
+            length = entity.position - offset;
+            int nameLength = length;
+            if (nameOffset != -1) {
+                nameOffset = nameOffset - offset;
+                nameLength = length - nameOffset - 1;
+            } else {
+                nameOffset = offset;
+            }
+            //check limit before loading more data
+            checkLimit(Limit.MAX_NAME_LIMIT, entity, nameOffset, nameLength);
+            invokeListeners(length);
+            if (length == entity.ch.length) {
+                // bad luck we have to resize our buffer
+                char[] tmp = new char[entity.fBufferSize * 2];
+                System.arraycopy(entity.ch, offset, tmp, 0, length);
+                entity.ch = tmp;
+                entity.fBufferSize *= 2;
+            }
+            else {
+                System.arraycopy(entity.ch, offset, entity.ch, 0, length);
+            }
+        }
+        return length;
+    }
+
+    /**
      * Checks whether the value of the specified Limit exceeds its limit
      *
      * @param limit The Limit to be checked.
@@ -1086,6 +1100,7 @@
      * @param quote   The quote character that signifies the end of the
      *                attribute value data.
      * @param content The content structure to fill.
+     * @param isNSURI a flag indicating whether the content is a Namespace URI
      *
      * @return Returns the next character on the input, if known. This
      *         value may be -1 but this does <em>note</em> designate
@@ -1094,7 +1109,7 @@
      * @throws IOException  Thrown if i/o error occurs.
      * @throws EOFException Thrown on end of file.
      */
-    public int scanLiteral(int quote, XMLString content)
+    public int scanLiteral(int quote, XMLString content, boolean isNSURI)
     throws IOException {
         if (DEBUG_BUFFER) {
             System.out.print("(scanLiteral, '"+(char)quote+"': ");
@@ -1208,6 +1223,9 @@
         if (fCurrentEntity.isGE) {
             checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length);
         }
+        if (isNSURI) {
+            checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
+        }
         content.setValues(fCurrentEntity.ch, offset, length);
 
         // return next character
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java	Tue Feb 16 10:22:22 2016 -0800
@@ -430,23 +430,28 @@
         //since scanAttributeValue doesn't use attIndex parameter therefore we
         //can safely add the attribute later..
         XMLString tmpStr = getString();
-        scanAttributeValue(tmpStr, fTempString2,
-                fAttributeQName.rawname, attributes,
-                attrIndex, isVC, fCurrentElement.rawname);
+
+        /**
+         * Determine whether this is a namespace declaration that will be subject
+         * to the name limit check in the scanAttributeValue operation.
+         * Namespace declaration format: xmlns="..." or xmlns:prefix="..."
+         * Note that prefix:xmlns="..." isn't a namespace.
+         */
+        String localpart = fAttributeQName.localpart;
+        String prefix = fAttributeQName.prefix != null
+                ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
+        boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
+                    prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
+
+        scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes,
+                attrIndex, isVC, fCurrentElement.rawname, isNSDecl);
 
         String value = null;
         //fTempString.toString();
 
         // record namespace declarations if any.
         if (fBindNamespaces) {
-
-            String localpart = fAttributeQName.localpart;
-            String prefix = fAttributeQName.prefix != null
-                    ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
-            // when it's of form xmlns="..." or xmlns:prefix="...",
-            // it's a namespace declaration. but prefix:xmlns="..." isn't.
-            if (prefix == XMLSymbols.PREFIX_XMLNS ||
-                    prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
+            if (isNSDecl) {
                 //check the length of URI
                 if (tmpStr.length > fXMLNameLimit) {
                     fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Wed Jul 05 21:58:29 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Tue Feb 16 10:22:22 2016 -0800
@@ -34,6 +34,7 @@
 import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
 import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.QName;
 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
 import com.sun.org.apache.xerces.internal.xni.XMLString;
@@ -599,7 +600,7 @@
                     : "QuoteRequiredInXMLDecl" , new Object[]{name});
         }
         fEntityScanner.scanChar();
-        int c = fEntityScanner.scanLiteral(quote, value);
+        int c = fEntityScanner.scanLiteral(quote, value, false);
         if (c != quote) {
             fStringBuffer2.clear();
             do {
@@ -617,7 +618,7 @@
                                 fEntityScanner.scanChar();
                     }
                 }
-                c = fEntityScanner.scanLiteral(quote, value);
+                c = fEntityScanner.scanLiteral(quote, value, false);
             } while (c != quote);
             fStringBuffer2.append(value);
             value.setValues(fStringBuffer2);
@@ -811,15 +812,14 @@
      * @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.
+     * @param isNSURI a flag indicating whether the content is a Namespace URI
      *
      * <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,
-            XMLAttributes attributes, int attrIndex,
-            boolean checkEntities, String eleName)
+    protected void scanAttributeValue(XMLString value, XMLString nonNormalizedValue,
+            String atName, XMLAttributes attributes, int attrIndex, boolean checkEntities,
+            String eleName, boolean isNSURI)
             throws IOException, XNIException {
         XMLStringBuffer stringBuffer = null;
         // quote
@@ -831,7 +831,7 @@
         fEntityScanner.scanChar();
         int entityDepth = fEntityDepth;
 
-        int c = fEntityScanner.scanLiteral(quote, value);
+        int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
         if (DEBUG_ATTR_NORMALIZATION) {
             System.out.println("** scanLiteral -> \""
                     + value.toString() + "\"");
@@ -993,7 +993,7 @@
                                 fStringBuffer2.append((char)c);
                             }
                 }
-                c = fEntityScanner.scanLiteral(quote, value);
+                c = fEntityScanner.scanLiteral(quote, value, isNSURI);
                 if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
                     fStringBuffer2.append(value);
                 }
@@ -1066,7 +1066,7 @@
             }
             fEntityScanner.scanChar();
             XMLString ident = fString;
-            if (fEntityScanner.scanLiteral(quote, ident) != quote) {
+            if (fEntityScanner.scanLiteral(quote, ident, false) != quote) {
                 fStringBuffer.clear();
                 do {
                     fStringBuffer.append(ident);
@@ -1077,7 +1077,7 @@
                         reportFatalError("InvalidCharInSystemID",
                             new Object[] {Integer.toString(c, 16)});
                     }
-                } while (fEntityScanner.scanLiteral(quote, ident) != quote);
+                } while (fEntityScanner.scanLiteral(quote, ident, false) != quote);
                 fStringBuffer.append(ident);
                 ident = fStringBuffer;
             }