diff options
Diffstat (limited to 'src/com/sun')
16 files changed, 257 insertions, 191 deletions
diff --git a/src/com/sun/org/apache/xalan/internal/Version.java b/src/com/sun/org/apache/xalan/internal/Version.java index be9c19d..ff778c8 100644 --- a/src/com/sun/org/apache/xalan/internal/Version.java +++ b/src/com/sun/org/apache/xalan/internal/Version.java @@ -121,7 +121,7 @@ public class Version */ public static int getMaintenanceVersionNum() { - return 0; + return 2; } /** diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java index 8cad427..6e91b75 100644 --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java @@ -100,20 +100,19 @@ final class FunctionAvailableCall extends FunctionCall { * the specified method is found in the specifed class. */ private boolean hasMethods() { - LiteralExpr arg = (LiteralExpr)_arg; // Get the class name from the namespace uri String className = getClassNameFromUri(_namespaceOfFunct); // Get the method name from the argument to function-available String methodName = null; - int colonIndex = _nameOfFunct.indexOf(":"); + int colonIndex = _nameOfFunct.indexOf(':'); if (colonIndex > 0) { String functionName = _nameOfFunct.substring(colonIndex+1); int lastDotIndex = functionName.lastIndexOf('.'); if (lastDotIndex > 0) { methodName = functionName.substring(lastDotIndex+1); - if (className != null && !className.equals("")) + if (className != null && className.length() != 0) className = className + "." + functionName.substring(0, lastDotIndex); else className = functionName.substring(0, lastDotIndex); diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java index f7309e5..9b40267 100644 --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java @@ -65,7 +65,7 @@ final class Sort extends Instruction implements Closure { private AttributeValue _order; private AttributeValue _caseOrder; private AttributeValue _dataType; - private String _lang; // bug! see 26869 + private AttributeValue _lang; // bug! see 26869, see XALANJ-2546 private String _className = null; private ArrayList<VariableRefBase> _closureVars = null; @@ -153,13 +153,11 @@ final class Sort extends Instruction implements Closure { } _dataType = AttributeValue.create(this, val, parser); - _lang = getAttribute("lang"); // bug! see 26869 - // val = getAttribute("lang"); - // _lang = AttributeValue.create(this, val, parser); + val = getAttribute("lang"); + _lang = AttributeValue.create(this, val, parser); // Get the case order; default is language dependant - val = getAttribute("case-order"); - _caseOrder = AttributeValue.create(this, val, parser); - + val = getAttribute("case-order"); + _caseOrder = AttributeValue.create(this, val, parser); } /** @@ -178,6 +176,7 @@ final class Sort extends Instruction implements Closure { _order.typeCheck(stable); _caseOrder.typeCheck(stable); _dataType.typeCheck(stable); + _lang.typeCheck(stable); return Type.Void; } @@ -195,16 +194,14 @@ final class Sort extends Instruction implements Closure { _order.translate(classGen, methodGen); } - public void translateCaseOrder(ClassGenerator classGen, + public void translateCaseOrder(ClassGenerator classGen, MethodGenerator methodGen) { - _caseOrder.translate(classGen, methodGen); + _caseOrder.translate(classGen, methodGen); } public void translateLang(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); - il.append(new PUSH(cpg, _lang)); // bug! see 26869 + _lang.translate(classGen, methodGen); } /** diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java b/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java index cb50cf5..e92574c 100644 --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java @@ -570,7 +570,7 @@ public class AdaptiveResultTreeImpl extends SimpleResultTreeImpl if (_openElementName != null) { int index; - if ((index =_openElementName.indexOf(":")) < 0) + if ((index =_openElementName.indexOf(':')) < 0) _dom.startElement(null, _openElementName, _openElementName, _attributes); else { String uri =_dom.getNamespaceURI(_openElementName.substring(0,index)); @@ -682,7 +682,7 @@ public class AdaptiveResultTreeImpl extends SimpleResultTreeImpl public void addAttribute(String qName, String value) { // "prefix:localpart" or "localpart" - int colonpos = qName.indexOf(":"); + int colonpos = qName.indexOf(':'); String uri = EMPTY_STRING; String localName = qName; if (colonpos >0) diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java index 804b154..57feec3 100644 --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java @@ -1421,8 +1421,8 @@ public final class BasisLibrary { * This method should only be invoked if the name attribute is an AVT */ public static void checkAttribQName(String name) { - final int firstOccur = name.indexOf(":"); - final int lastOccur = name.lastIndexOf(":"); + final int firstOccur = name.indexOf(':'); + final int lastOccur = name.lastIndexOf(':'); final String localName = name.substring(lastOccur + 1); if (firstOccur > 0) { diff --git a/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java b/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java index 58fae69..7ed1d8b 100644 --- a/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java @@ -359,7 +359,7 @@ public abstract class DTMDefaultBase implements DTM while (low <= high) { - int mid = (low + high) / 2; + int mid = (low + high) >>> 1; int c = list[mid]; if (c > value) diff --git a/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java index a68ec6d..633d0e9 100644 --- a/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java +++ b/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 2001-2004 The Apache Software Foundation. @@ -43,6 +42,7 @@ import org.xml.sax.SAXException; * because it is used from another package. * * @xsl.usage internal + * @LastModified: Sept 2018 */ public final class ToHTMLStream extends ToStream { @@ -1021,7 +1021,7 @@ public final class ToHTMLStream extends ToStream String name, String value, ElemDesc elemDesc) - throws IOException + throws IOException, SAXException { writer.write(' '); @@ -1345,7 +1345,7 @@ public final class ToHTMLStream extends ToStream */ public void writeAttrString( final java.io.Writer writer, String string, String encoding) - throws IOException + throws IOException, SAXException { final int end = string.length(); if (end > m_attrBuff.length) @@ -1397,13 +1397,16 @@ public final class ToHTMLStream extends ToStream } else { - if (Encodings.isHighUTF16Surrogate(ch)) + if (Encodings.isHighUTF16Surrogate(ch) || + Encodings.isLowUTF16Surrogate(ch)) { - - writeUTF16Surrogate(ch, chars, i, end); - i++; // two input characters processed - // this increments by one and the for() - // loop itself increments by another one. + if (writeUTF16Surrogate(ch, chars, i, end) >= 0) { + // move the index if the low surrogate is consumed + // as writeUTF16Surrogate has written the pair + if (Encodings.isHighUTF16Surrogate(ch)) { + i++; + } + } } // The next is kind of a hack to keep from escaping in the case diff --git a/src/com/sun/org/apache/xml/internal/serializer/ToStream.java b/src/com/sun/org/apache/xml/internal/serializer/ToStream.java index 2301763..b4da7bb 100644 --- a/src/com/sun/org/apache/xml/internal/serializer/ToStream.java +++ b/src/com/sun/org/apache/xml/internal/serializer/ToStream.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 2001-2004 The Apache Software Foundation. @@ -51,6 +50,7 @@ import org.xml.sax.SAXException; * serializers (xml, html, text ...) that write output to a stream. * * @xsl.usage internal + * @LastModified: Sept 2018 */ abstract public class ToStream extends SerializerBase { @@ -200,6 +200,7 @@ abstract public class ToStream extends SerializerBase */ private boolean m_expandDTDEntities = true; + private char m_highSurrogate = 0; /** * Default constructor @@ -947,45 +948,46 @@ abstract public class ToStream extends SerializerBase * @param ch Character array. * @param i position Where the surrogate was detected. * @param end The end index of the significant characters. - * @return 0 if the pair of characters was written out as-is, - * the unicode code point of the character represented by - * the surrogate pair if an entity reference with that value - * was written out. + * @return the status of writing a surrogate pair. + * -1 -- nothing is written + * 0 -- the pair is written as-is + * code point -- the pair is written as an entity reference * * @throws IOException * @throws org.xml.sax.SAXException if invalid UTF-16 surrogate detected. */ protected int writeUTF16Surrogate(char c, char ch[], int i, int end) - throws IOException + throws IOException, SAXException { - int codePoint = 0; + int status = -1; if (i + 1 >= end) { - throw new IOException( - Utils.messages.createMessage( - MsgKey.ER_INVALID_UTF16_SURROGATE, - new Object[] { Integer.toHexString((int) c)})); + m_highSurrogate = c; + return status; + } + + char high, low; + if (m_highSurrogate == 0) { + high = c; + low = ch[i+1]; + status = 0; + } else { + high = m_highSurrogate; + low = c; + m_highSurrogate = 0; } - final char high = c; - final char low = ch[i+1]; if (!Encodings.isLowUTF16Surrogate(low)) { - throw new IOException( - Utils.messages.createMessage( - MsgKey.ER_INVALID_UTF16_SURROGATE, - new Object[] { - Integer.toHexString((int) c) - + " " - + Integer.toHexString(low)})); + throwIOE(high, low); } final java.io.Writer writer = m_writer; // If we make it to here we have a valid high, low surrogate pair - if (m_encodingInfo.isInEncoding(c,low)) { + if (m_encodingInfo.isInEncoding(high,low)) { // If the character formed by the surrogate pair // is in the encoding, so just write it out - writer.write(ch,i,2); + writer.write(new char[]{high, low}, 0, 2); } else { // Don't know what to do with this char, it is @@ -993,24 +995,16 @@ abstract public class ToStream extends SerializerBase // a surrogate pair, so write out as an entity ref final String encoding = getEncoding(); if (encoding != null) { - /* The output encoding is known, - * so somthing is wrong. - */ - codePoint = Encodings.toCodePoint(high, low); - // not in the encoding, so write out a character reference - writer.write('&'); - writer.write('#'); - writer.write(Integer.toString(codePoint)); - writer.write(';'); + status = writeCharRef(writer, high, low); } else { /* The output encoding is not known, * so just write it out as-is. */ - writer.write(ch, i, 2); + writer.write(new char[]{high, low}, 0, 2); } } // non-zero only if character reference was written out. - return codePoint; + return status; } /** @@ -1100,32 +1094,7 @@ abstract public class ToStream extends SerializerBase } else if (isCData && (!escapingNotNeeded(c))) { - // if (i != 0) - if (m_cdataTagOpen) - closeCDATA(); - - // This needs to go into a function... - if (Encodings.isHighUTF16Surrogate(c)) - { - writeUTF16Surrogate(c, ch, i, end); - i++ ; // process two input characters - } - else - { - writer.write("&#"); - - String intStr = Integer.toString((int) c); - - writer.write(intStr); - writer.write(';'); - } - - // if ((i != 0) && (i < (end - 1))) - // if (!m_cdataTagOpen && (i < (end - 1))) - // { - // writer.write(CDATA_DELIMITER_OPEN); - // m_cdataTagOpen = true; - // } + i = handleEscaping(writer, c, ch, i, end); } else if ( isCData @@ -1149,29 +1118,44 @@ abstract public class ToStream extends SerializerBase } writer.write(c); } - - // This needs to go into a function... - else if (Encodings.isHighUTF16Surrogate(c)) - { - if (m_cdataTagOpen) - closeCDATA(); - writeUTF16Surrogate(c, ch, i, end); - i++; // process two input characters + else { + i = handleEscaping(writer, c, ch, i, end); } - else - { - if (m_cdataTagOpen) - closeCDATA(); - writer.write("&#"); + } + } - String intStr = Integer.toString((int) c); + } - writer.write(intStr); - writer.write(';'); + /** + * Handles escaping, writes either with a surrogate pair or a character + * reference. + * + * @param c the current char + * @param ch the character array + * @param i the current position + * @param end the end index of the array + * @return the next index + * + * @throws IOException + * @throws org.xml.sax.SAXException if invalid UTF-16 surrogate detected. + */ + private int handleEscaping(Writer writer, char c, char ch[], int i, int end) + throws IOException, SAXException { + if (Encodings.isHighUTF16Surrogate(c) || Encodings.isLowUTF16Surrogate(c)) + { + if (writeUTF16Surrogate(c, ch, i, end) >= 0) { + // move the index if the low surrogate is consumed + // as writeUTF16Surrogate has written the pair + if (Encodings.isHighUTF16Surrogate(c)) { + i++ ; } } } - + else + { + writeCharRef(writer, c); + } + return i; } /** @@ -1242,7 +1226,7 @@ abstract public class ToStream extends SerializerBase } m_ispreserve = true; - if (shouldIndent()) + if (!m_cdataTagOpen && shouldIndent()) indent(); boolean writeCDataBrackets = @@ -1564,7 +1548,7 @@ abstract public class ToStream extends SerializerBase int i, char ch, int lastDirty, - boolean fromTextNode) throws IOException + boolean fromTextNode) throws IOException, SAXException { int startClean = lastDirty + 1; // if we have some clean characters accumulated @@ -1643,54 +1627,41 @@ abstract public class ToStream extends SerializerBase int len, boolean fromTextNode, boolean escLF) - throws IOException + throws IOException, SAXException { int pos = accumDefaultEntity(writer, ch, i, chars, len, fromTextNode, escLF); if (i == pos) { + if (m_highSurrogate != 0) { + if (!(Encodings.isLowUTF16Surrogate(ch))) { + throwIOE(m_highSurrogate, ch); + } + writeCharRef(writer, m_highSurrogate, ch); + m_highSurrogate = 0; + return ++pos; + } + if (Encodings.isHighUTF16Surrogate(ch)) { - - // Should be the UTF-16 low surrogate of the hig/low pair. - char next; - // Unicode code point formed from the high/low pair. - int codePoint = 0; - if (i + 1 >= len) { - throw new IOException( - Utils.messages.createMessage( - MsgKey.ER_INVALID_UTF16_SURROGATE, - new Object[] { Integer.toHexString(ch)})); - //"Invalid UTF-16 surrogate detected: " - - //+Integer.toHexString(ch)+ " ?"); + // save for the next read + m_highSurrogate = ch; + pos++; } else { - next = chars[++i]; + // the next should be the UTF-16 low surrogate of the hig/low pair. + char next = chars[++i]; if (!(Encodings.isLowUTF16Surrogate(next))) - throw new IOException( - Utils.messages.createMessage( - MsgKey - .ER_INVALID_UTF16_SURROGATE, - new Object[] { - Integer.toHexString(ch) - + " " - + Integer.toHexString(next)})); - //"Invalid UTF-16 surrogate detected: " - - //+Integer.toHexString(ch)+" "+Integer.toHexString(next)); - codePoint = Encodings.toCodePoint(ch,next); - } + throwIOE(ch, next); - writer.write("&#"); - writer.write(Integer.toString(codePoint)); - writer.write(';'); - pos += 2; // count the two characters that went into writing out this entity + writeCharRef(writer, ch, next); + pos += 2; // count the two characters that went into writing out this entity + } } else { @@ -1702,18 +1673,14 @@ abstract public class ToStream extends SerializerBase if (isCharacterInC0orC1Range(ch) || (XMLVERSION11.equals(getVersion()) && isNELorLSEPCharacter(ch))) { - writer.write("&#"); - writer.write(Integer.toString(ch)); - writer.write(';'); + writeCharRef(writer, ch); } else if ((!escapingNotNeeded(ch) || ( (fromTextNode && m_charInfo.isSpecialTextChar(ch)) || (!fromTextNode && m_charInfo.isSpecialAttrChar(ch)))) - && m_elemContext.m_currentElemDepth > 0) + && m_elemContext.m_currentElemDepth > 0) { - writer.write("&#"); - writer.write(Integer.toString(ch)); - writer.write(';'); + writeCharRef(writer, ch); } else { @@ -1727,6 +1694,45 @@ abstract public class ToStream extends SerializerBase } /** + * Writes out a character reference. + * @param writer the writer + * @param c the character + * @throws IOException + */ + private void writeCharRef(Writer writer, char c) throws IOException, SAXException { + if (m_cdataTagOpen) + closeCDATA(); + writer.write("&#"); + writer.write(Integer.toString(c)); + writer.write(';'); + } + + /** + * Writes out a pair of surrogates as a character reference + * @param writer the writer + * @param high the high surrogate + * @param low the low surrogate + * @throws IOException + */ + private int writeCharRef(Writer writer, char high, char low) throws IOException, SAXException { + if (m_cdataTagOpen) + closeCDATA(); + // Unicode code point formed from the high/low pair. + int codePoint = Encodings.toCodePoint(high, low); + writer.write("&#"); + writer.write(Integer.toString(codePoint)); + writer.write(';'); + return codePoint; + } + + private void throwIOE(char ch, char next) throws IOException { + throw new IOException(Utils.messages.createMessage( + MsgKey.ER_INVALID_UTF16_SURROGATE, + new Object[] {Integer.toHexString(ch) + " " + + Integer.toHexString(next)})); + } + + /** * Receive notification of the beginning of an element, although this is a * SAX method additional namespace or attribute information can occur before * or after this call, that is associated with this element. @@ -1962,7 +1968,7 @@ abstract public class ToStream extends SerializerBase Writer writer, String string, String encoding) - throws IOException + throws IOException, SAXException { final int len = string.length(); if (len > m_attrBuff.length) diff --git a/src/com/sun/org/apache/xml/internal/serializer/ToTextStream.java b/src/com/sun/org/apache/xml/internal/serializer/ToTextStream.java index 9e39b89..aecf377 100644 --- a/src/com/sun/org/apache/xml/internal/serializer/ToTextStream.java +++ b/src/com/sun/org/apache/xml/internal/serializer/ToTextStream.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 2001-2004 The Apache Software Foundation. @@ -35,6 +34,7 @@ import org.xml.sax.SAXException; * This class converts SAX or SAX-like calls to a * serialized document for xsl:output method of "text". * @xsl.usage internal + * @LastModified: Sept 2018 */ public final class ToTextStream extends ToStream { @@ -296,23 +296,32 @@ public final class ToTextStream extends ToStream } else if (m_encodingInfo.isInEncoding(c)) { writer.write(c); // one input char processed - } else if (Encodings.isHighUTF16Surrogate(c)) { + } else if (Encodings.isHighUTF16Surrogate(c) || + Encodings.isLowUTF16Surrogate(c)) { final int codePoint = writeUTF16Surrogate(c, ch, i, end); - if (codePoint != 0) { - // I think we can just emit the message, - // not crash and burn. - final String integralValue = Integer.toString(codePoint); - final String msg = Utils.messages.createMessage( - MsgKey.ER_ILLEGAL_CHARACTER, - new Object[] { integralValue, encoding }); - - //Older behavior was to throw the message, - //but newer gentler behavior is to write a message to System.err - //throw new SAXException(msg); - System.err.println(msg); - + if (codePoint >= 0) { + // move the index if the low surrogate is consumed + // as writeUTF16Surrogate has written the pair + if (Encodings.isHighUTF16Surrogate(c)) { + i++; + } + + // printing to the console is not appropriate, but will leave + // it as is for compatibility. + if (codePoint >0) { + // I think we can just emit the message, + // not crash and burn. + final String integralValue = Integer.toString(codePoint); + final String msg = Utils.messages.createMessage( + MsgKey.ER_ILLEGAL_CHARACTER, + new Object[] { integralValue, encoding }); + + //Older behavior was to throw the message, + //but newer gentler behavior is to write a message to System.err + //throw new SAXException(msg); + System.err.println(msg); + } } - i++; // two input chars processed } else { // Don't know what to do with this char, it is // not in the encoding and not a high char in diff --git a/src/com/sun/org/apache/xml/internal/utils/NodeVector.java b/src/com/sun/org/apache/xml/internal/utils/NodeVector.java index 8bba6d5..fd1171d 100644 --- a/src/com/sun/org/apache/xml/internal/utils/NodeVector.java +++ b/src/com/sun/org/apache/xml/internal/utils/NodeVector.java @@ -670,9 +670,9 @@ public class NodeVector implements Serializable, Cloneable /* * Pick a pivot and move it out of the way */ - int pivot = a[(lo + hi) / 2]; - - a[(lo + hi) / 2] = a[hi]; + int mid = (lo + hi) >>> 1; + int pivot = a[mid]; + a[mid] = a[hi]; a[hi] = pivot; while (lo < hi) diff --git a/src/com/sun/org/apache/xpath/internal/XPath.java b/src/com/sun/org/apache/xpath/internal/XPath.java index 1601ae1..2734cc4 100644 --- a/src/com/sun/org/apache/xpath/internal/XPath.java +++ b/src/com/sun/org/apache/xpath/internal/XPath.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2019 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -181,10 +181,12 @@ public class XPath implements Serializable, ExpressionOwner else if (MATCH == type) parser.initMatchPattern(compiler, exprString, prefixResolver); else - throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)})); //"Can not deal with XPath type: " + type); + throw new RuntimeException(XSLMessages.createXPATHMessage( + XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, + new Object[]{Integer.toString(type)})); // System.out.println("----------------"); - Expression expr = compiler.compile(0); + Expression expr = compiler.compileExpression(0); // System.out.println("expr: "+expr); this.setExpression(expr); @@ -236,7 +238,7 @@ public class XPath implements Serializable, ExpressionOwner //"Can not deal with XPath type: " + type); // System.out.println("----------------"); - Expression expr = compiler.compile(0); + Expression expr = compiler.compileExpression(0); // System.out.println("expr: "+expr); this.setExpression(expr); diff --git a/src/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java b/src/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java index 40638e6..bd64a16 100644 --- a/src/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java +++ b/src/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2019 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ public class FilterExprWalker extends AxesWalker m_mustHardReset = true; case OpCodes.OP_GROUP : case OpCodes.OP_VARIABLE : - m_expr = compiler.compile(opPos); + m_expr = compiler.compileExpression(opPos); m_expr.exprSetParent(this); //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof com.sun.org.apache.xalan.internal.templates.FuncKey)) if(m_expr instanceof com.sun.org.apache.xpath.internal.operations.Variable) @@ -85,7 +85,7 @@ public class FilterExprWalker extends AxesWalker } break; default : - m_expr = compiler.compile(opPos + 2); + m_expr = compiler.compileExpression(opPos + 2); m_expr.exprSetParent(this); } // if(m_expr instanceof WalkingIterator) diff --git a/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java b/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java index 2f05535..385eba9 100644 --- a/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java +++ b/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2019 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1007,10 +1007,10 @@ public class WalkerFactory case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : - expr = compiler.compile(opPos); + expr = compiler.compileExpression(opPos); break; default : - expr = compiler.compile(opPos + 2); + expr = compiler.compileExpression(opPos + 2); } axis = Axis.FILTEREDLIST; diff --git a/src/com/sun/org/apache/xpath/internal/compiler/Compiler.java b/src/com/sun/org/apache/xpath/internal/compiler/Compiler.java index fd2fbae..b88b4e8 100644 --- a/src/com/sun/org/apache/xpath/internal/compiler/Compiler.java +++ b/src/com/sun/org/apache/xpath/internal/compiler/Compiler.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 1999-2004 The Apache Software Foundation. @@ -71,9 +70,12 @@ import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; * of operation codes (op map) and then builds from that into an Expression * tree. * @xsl.usage advanced + * @LastModified: May 2019 */ public class Compiler extends OpMap { + // count the number of operations or calls to compileOperation + int countOp; /** * Construct a Compiler object with a specific ErrorListener and @@ -107,15 +109,40 @@ public class Compiler extends OpMap /** * Execute the XPath object from a given opcode position. + * + * Note that this method is added so that when StackOverflowError is caught + * the address space can be freed to this point allowing further activities + * such as reporting the error. + * * @param opPos The current position in the xpath.m_opMap array. * @return The result of the XPath. * * @throws TransformerException if there is a syntax or other error. * @xsl.usage advanced */ - public Expression compile(int opPos) throws TransformerException - { + public Expression compileExpression(int opPos) throws TransformerException + { + try { + countOp = 0; + return compile(opPos); + } catch (StackOverflowError sof) { + error(XPATHErrorResources.ER_COMPILATION_TOO_MANY_OPERATION, new Object[]{countOp}); + } + return null; + } + /** + * This method handles the actual compilation process. It is called from the + * compileExpression method as well as the subsequent processes. See the note + * for compileExpression. + * + * @param opPos The current position in the xpath.m_opMap array. + * @return The result of the XPath. + * + * @throws TransformerException if there is a syntax or other error. + */ + private Expression compile(int opPos) throws TransformerException + { int op = getOp(opPos); Expression expr = null; @@ -211,6 +238,7 @@ public class Compiler extends OpMap private Expression compileOperation(Operation operation, int opPos) throws TransformerException { + ++countOp; int leftPos = getFirstChildPos(opPos); int rightPos = getNextOpPos(leftPos); diff --git a/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java b/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java index 1b55599..bd19dff 100644 --- a/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java +++ b/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 1999-2004 The Apache Software Foundation. @@ -37,6 +36,7 @@ import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; * Tokenizes and parses XPath expressions. This should really be named * XPathParserImpl, and may be renamed in the future. * @xsl.usage general + * @LastModified: May 2019 */ public class XPathParser { @@ -74,6 +74,9 @@ public class XPathParser protected final static int FILTER_MATCH_PRIMARY = 1; protected final static int FILTER_MATCH_PREDICATES = 2; + // counts open predicates + private int countPredicate; + /** * The parser constructor. */ @@ -160,6 +163,9 @@ public class XPathParser } else throw e; + } catch (StackOverflowError sof) { + error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN, + new Object[]{m_token, m_queueMark, countPredicate}); } compiler.shrink(); @@ -193,7 +199,12 @@ public class XPathParser m_ops.setOp(OpMap.MAPINDEX_LENGTH, 2); nextToken(); - Pattern(); + try { + Pattern(); + } catch (StackOverflowError sof) { + error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN, + new Object[]{m_token, m_queueMark, countPredicate}); + } if (null != m_token) { @@ -789,7 +800,7 @@ public class XPathParser */ protected void Expr() throws javax.xml.transform.TransformerException { - OrExpr(); + OrExpr(); } /** @@ -1931,11 +1942,12 @@ public class XPathParser */ protected void Predicate() throws javax.xml.transform.TransformerException { - if (tokenIs('[')) { + countPredicate++; nextToken(); PredicateExpr(); + countPredicate--; consumeExpected(']'); } } diff --git a/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java b/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java index f96561b..ed55af5 100644 --- a/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java +++ b/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright 1999-2005 The Apache Software Foundation. @@ -30,6 +29,7 @@ import java.util.ListResourceBundle; * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced + * @LastModified: May 2019 */ public class XPATHErrorResources extends ListResourceBundle { @@ -147,6 +147,10 @@ public class XPATHErrorResources extends ListResourceBundle "ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG"; public static final String ER_PREDICATE_ILLEGAL_SYNTAX = "ER_PREDICATE_ILLEGAL_SYNTAX"; + public static final String ER_PREDICATE_TOO_MANY_OPEN = + "ER_PREDICATE_TOO_MANY_OPEN"; + public static final String ER_COMPILATION_TOO_MANY_OPERATION = + "ER_COMPILATION_TOO_MANY_OPERATION"; public static final String ER_ILLEGAL_AXIS_NAME = "ER_ILLEGAL_AXIS_NAME"; public static final String ER_UNKNOWN_NODETYPE = "ER_UNKNOWN_NODETYPE"; public static final String ER_PATTERN_LITERAL_NEEDS_BE_QUOTED = @@ -458,6 +462,12 @@ public static final String ER_IGNORABLE_WHITESPACE_NOT_HANDLED = { ER_PREDICATE_ILLEGAL_SYNTAX, "'..[predicate]' or '.[predicate]' is illegal syntax. Use 'self::node()[predicate]' instead."}, + { ER_PREDICATE_TOO_MANY_OPEN, + "Stack overflow while parsing {0} at {1}. Too many open predicates({2})."}, + + { ER_COMPILATION_TOO_MANY_OPERATION, + "Stack overflow while compiling the expression. Too many operations({0})."}, + { ER_ILLEGAL_AXIS_NAME, "illegal axis name: {0}"}, |