diff --git a/.hgtags b/.hgtags
index 11724074994..a1a487be0aa 100644
--- a/.hgtags
+++ b/.hgtags
@@ -1029,3 +1029,7 @@ b81aa0cb626746f790f4b6fdcc71d84d00eff136 jdk8u332-b01
7376b980d6b085d5d9061d212f3ad69d239718e6 jdk8u332-b03
f58fc9077d2274b2832bc00ff16d112fe99d9ace jdk8u332-b04
2a92df021686242bb55ecd324b5dee00c45a0a8e jdk8u332-b05
+6d5c4e11830c154190021d6ae134c5f4162ff7cc jdk8u332-b06
+6d526dbc3432fd9f2db19bdcb2f6b5b8799d88f0 jdk8u332-b07
+95b31159fdfd496e521e119aba9ef54acf6b272e jdk8u332-b08
+37aca7715d13acfdc931aab7dbcdd41f9fd4b042 jdk8u332-b09
diff --git a/jaxp/src/com/sun/java_cup/internal/runtime/lr_parser.java b/jaxp/src/com/sun/java_cup/internal/runtime/lr_parser.java
index a94dff88924..517adbf0b14 100644
--- a/jaxp/src/com/sun/java_cup/internal/runtime/lr_parser.java
+++ b/jaxp/src/com/sun/java_cup/internal/runtime/lr_parser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2022, 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
@@ -26,6 +26,8 @@
package com.sun.java_cup.internal.runtime;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.sym;
+import java.util.Arrays;
import java.util.Stack;
/** This class implements a skeleton table driven LR parser. In general,
@@ -134,9 +136,19 @@
* @see com.sun.java_cup.internal.runtime.Symbol
* @see com.sun.java_cup.internal.runtime.virtual_parse_stack
* @author Frank Flannery
+ *
+ * @LastModified: Jan 2022
*/
public abstract class lr_parser {
+ public static final int ID_GROUP = 1;
+ public static final int ID_OPERATOR = 2;
+ public static final int ID_TOTAL_OPERATOR = 3;
+
+ private boolean isLiteral = false;
+ private int grpCount = 0;
+ private int opCount = 0;
+ private int totalOpCount = 0;
/*-----------------------------------------------------------*/
/*--- Constructor(s) ----------------------------------------*/
@@ -355,8 +367,34 @@ public void user_init() throws java.lang.Exception { }
* the "scan with" clause. Do not recycle objects; every call to
* scan() should return a fresh object.
*/
- public Symbol scan() throws java.lang.Exception {
- return getScanner().next_token();
+ public Symbol scan() throws Exception {
+ Symbol s = getScanner().next_token();
+
+ if (s.sym == sym.LPAREN) {
+ if (!isLiteral) {
+ grpCount++;
+ }
+ opCount++; // function
+ isLiteral = false;
+ } else if (contains(sym.OPERATORS, s.sym)) {
+ opCount++;
+ isLiteral = false;
+ }
+
+ if (s.sym == sym.Literal || s.sym == sym.QNAME) {
+ isLiteral = true;
+ }
+
+ return s;
+ }
+
+ private boolean contains(final int[] arr, final int key) {
+ for (int i = 0 ; i < arr.length ; ++i) {
+ if (arr[i] == key) {
+ return true;
+ }
+ }
+ return false;
}
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
@@ -552,6 +590,9 @@ public Symbol parse() throws java.lang.Exception
/* do user initialization */
user_init();
+ isLiteral = false;
+ grpCount = 0;
+ opCount = 0;
/* get the first token */
cur_token = scan();
@@ -630,9 +671,29 @@ else if (act == 0)
}
}
}
+
+ totalOpCount += opCount;
return lhs_sym;
}
+ /**
+ * Returns the count of operators in XPath expressions.
+ *
+ * @param id the ID of the count
+ * @return the count associated with the ID
+ */
+ public int getCount(int id) {
+ switch (id) {
+ case ID_GROUP:
+ return grpCount;
+ case ID_OPERATOR:
+ return opCount;
+ case ID_TOTAL_OPERATOR:
+ return totalOpCount;
+ }
+ return 0;
+ }
+
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
/** Write a debugging message to System.err for the debugging version
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
index 64514945258..f8374931789 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
@@ -175,6 +175,21 @@ public final class XalanConstants {
*/
public static final String JDK_EXTENSION_CLASSLOADER = "jdk.xml.transform.extensionClassLoader";
+ /**
+ * JDK XPath Expression group limit
+ */
+ public static final String XPATH_GROUP_LIMIT = "jdk.xml.xpathExprGrpLimit";
+
+ /**
+ * JDK XPath Expression operators limit
+ */
+ public static final String XPATH_OP_LIMIT = "jdk.xml.xpathExprOpLimit";
+
+ /**
+ * JDK XSL XPath limit or Total Number of Operators Permitted in an XSL Stylesheet
+ */
+ public static final String XPATH_TOTALOP_LIMIT = "jdk.xml.xpathTotalOpLimit";
+
//legacy System Properties
public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
index 08ec875bdb8..342183a9301 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -24,7 +24,7 @@
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
@@ -465,8 +465,10 @@ public SyntaxTreeNode parse(InputSource input) {
XMLSecurityManager securityManager =
(XMLSecurityManager) _xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
- lastProperty = limit.apiProperty();
- reader.setProperty(lastProperty, securityManager.getLimitValueAsString(limit));
+ if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) {
+ lastProperty = limit.apiProperty();
+ reader.setProperty(lastProperty, securityManager.getLimitValueAsString(limit));
+ }
}
if (securityManager.printEntityCountInfo()) {
lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
@@ -1121,6 +1123,9 @@ private SyntaxTreeNode parseTopLevel(SyntaxTreeNode parent, String text,
expression, parent));
}
catch (Exception e) {
+ if (ErrorMsg.XPATH_LIMIT.equals(e.getMessage())) {
+ throw new RuntimeException(ErrorMsg.XPATH_LIMIT);
+ }
if (_xsltc.debug()) e.printStackTrace();
reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR,
expression, parent));
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java
index 8a4fba5b49a..dc54a7ba332 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java
@@ -9,6 +9,10 @@
import java.util.Stack;
import java.util.Vector;
import java.io.StringReader;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import jdk.xml.internal.XMLLimitAnalyzer;
+import jdk.xml.internal.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager.Limit;
import com.sun.java_cup.internal.runtime.*;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
@@ -20,9 +24,12 @@
* CUP v0.11b generated parser.
* This class was generated by CUP v0.11b on Nov 12, 2019.
*
- * @LastModified: Nov 2019
+ * @LastModified: Jan 2022
*/
public class XPathParser extends com.sun.java_cup.internal.runtime.lr_parser {
+ private int grpLimit = 0;
+ private int opLimit = 0;
+ private int totalOpLimit = 0;
/** Default constructor. */
public XPathParser() {
@@ -929,10 +936,19 @@ public int error_sym() {
*/
public SymbolTable _symbolTable;
+ private XMLSecurityManager _xmlSM;
+ private XMLLimitAnalyzer _limitAnalyzer = null;
+
public XPathParser(Parser parser) {
_parser = parser;
_xsltc = parser.getXSLTC();
_symbolTable = parser.getSymbolTable();
+ _xmlSM = (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
+ _limitAnalyzer = new XMLLimitAnalyzer();
+ // no limits if _xmlSM is null
+ grpLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_GROUP_LIMIT) : 0;
+ opLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_OP_LIMIT) : 0;
+ totalOpLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_TOTALOP_LIMIT) : 0;
}
public int getLineNumber() {
@@ -1078,7 +1094,32 @@ public Symbol parse(String expression, int lineNumber) throws Exception {
try {
_expression = expression;
_lineNumber = lineNumber;
- return super.parse();
+ Symbol s = super.parse();
+ int grpCount = getCount(ID_GROUP);
+ int opCount = getCount(ID_OPERATOR);
+ int totalOpCount = getCount(ID_TOTAL_OPERATOR);
+
+ String errCode = null;
+ Object[] params = null;
+ if (grpLimit > 0 && grpCount > grpLimit) {
+ errCode = ErrorMsg.XPATH_GROUP_LIMIT;
+ params = new Object[]{grpCount, grpLimit,
+ _xmlSM.getStateLiteral(Limit.XPATH_GROUP_LIMIT)};
+ } else if (opLimit > 0 && opCount > opLimit) {
+ errCode = ErrorMsg.XPATH_OPERATOR_LIMIT;
+ params = new Object[]{opCount, opLimit,
+ _xmlSM.getStateLiteral(Limit.XPATH_OP_LIMIT)};
+ } else if (totalOpLimit > 0 && totalOpCount > totalOpLimit) {
+ errCode = ErrorMsg.XPATH_TOTAL_OPERATOR_LIMIT;
+ params = new Object[]{totalOpCount, totalOpLimit,
+ _xmlSM.getStateLiteral(Limit.XPATH_TOTALOP_LIMIT)};
+ }
+ if (errCode != null) {
+ _parser.reportError(Constants.FATAL,
+ new ErrorMsg(errCode, lineNumber, params));
+ throw new RuntimeException(ErrorMsg.XPATH_LIMIT);
+ }
+ return s;
} catch (IllegalCharException e) {
ErrorMsg err = new ErrorMsg(ErrorMsg.ILLEGAL_CHAR_ERR,
lineNumber, e.getMessage());
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
index 8b4225eda6a..c49b0432ab4 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,7 +23,6 @@
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
import com.sun.org.apache.xml.internal.dtm.DTM;
@@ -47,6 +46,7 @@
import java.util.jar.Manifest;
import javax.xml.XMLConstants;
import jdk.xml.internal.JdkXmlFeatures;
+import jdk.xml.internal.XMLSecurityManager;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@@ -481,7 +481,10 @@ else if (systemId != null && !systemId.equals("")) {
}
}
catch (Exception e) {
- /*if (_debug)*/ e.printStackTrace();
+ if (_debug) e.printStackTrace();
+ if (ErrorMsg.XPATH_LIMIT.equals(e.getMessage())) {
+ return !_parser.errorsFound();
+ }
_parser.reportError(Constants.FATAL, new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR, e));
}
catch (Error e) {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java
index d64dc3fd046..88244a31ab0 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java
@@ -6,6 +6,8 @@
package com.sun.org.apache.xalan.internal.xsltc.compiler;
+import java.util.Arrays;
+
/** CUP generated class containing symbol constants. */
public class sym {
/* terminals */
@@ -63,4 +65,12 @@ public class sym {
public static final int ATTRIBUTE = 41;
public static final int GT = 19;
public static final int NODE = 31;
+ /*
+ AXES: count once at DCOLON,
+ these axes names are therefore not counted:
+ NAMESPACE, FOLLOWINGSIBLING, CHILD, DESCENDANTORSELF, DESCENDANT
+ , PRECEDINGSIBLING, SELF, ANCESTORORSELF, PRECEDING, ANCESTOROR, PARENT, FOLLOWING, ATTRIBUTE
+ */
+ public static final int[] OPERATORS = {GE, SLASH, ATSIGN, LPAREN, DCOLON,
+ MINUS, STAR, LT, OR, DIV, PLUS, LE, VBAR, MOD, EQ, LBRACK, DOLLAR, NE, GT};
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
index 52f944101dc..8854a01ea0a 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
@@ -24,6 +24,7 @@
/**
* @author Morten Jorgensen
+ * @LastModified: Jan 2022
*/
public class ErrorMessages extends ListResourceBundle {
@@ -1011,12 +1012,22 @@ public Object[][] getContents()
"smaller templates."
},
- {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "When Java security is enabled, " +
- "support for deserializing TemplatesImpl is disabled." +
- "This can be overridden by setting the jdk.xml.enableTemplatesImplDeserialization" +
- " system property to true."}
-
- };
+ {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "When Java security is enabled, "
+ + "support for deserializing TemplatesImpl is disabled. This can be "
+ + "overridden by setting the jdk.xml.enableTemplatesImplDeserialization"
+ + " system property to true."},
+
+ {ErrorMsg.XPATH_GROUP_LIMIT,
+ "JAXP0801001: the compiler encountered an XPath expression containing "
+ + "''{0}'' groups that exceeds the ''{1}'' limit set by ''{2}''."},
+
+ {ErrorMsg.XPATH_OPERATOR_LIMIT,
+ "JAXP0801002: the compiler encountered an XPath expression containing "
+ + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."},
+ {ErrorMsg.XPATH_TOTAL_OPERATOR_LIMIT,
+ "JAXP0801003: the compiler encountered XPath expressions with an accumulated "
+ + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."},
+ };
}
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
index 4192cf2d7e6..365f6c747e5 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
@@ -172,6 +172,11 @@ public final class ErrorMsg {
public static final String DESERIALIZE_TRANSLET_ERR = "DESERIALIZE_TEMPLATES_ERR";
+ public static final String XPATH_LIMIT = "XPATH_LIMIT";
+ public static final String XPATH_GROUP_LIMIT = "XPATH_GROUP_LIMIT";
+ public static final String XPATH_OPERATOR_LIMIT = "XPATH_OPERATOR_LIMIT";
+ public static final String XPATH_TOTAL_OPERATOR_LIMIT = "XPATH_TOTAL_OPERATOR_LIMIT";
+
// All error messages are localized and are stored in resource bundles.
// This array and the following 4 strings are read from that bundle.
private static ResourceBundle _bundle;
@@ -208,7 +213,11 @@ public ErrorMsg(String message, int line) {
public ErrorMsg(String code, int line, Object param) {
_code = code;
_line = line;
- _params = new Object[] { param };
+ if (param instanceof Object[]) {
+ _params = (Object[])param;
+ } else {
+ _params = new Object[] { param };
+ }
}
public ErrorMsg(String code, Object param) {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
index 549a3285eaa..cb596ac71cc 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
@@ -24,7 +24,7 @@
import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
index 3bd46e17dd2..8e783cee0b5 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -24,7 +24,6 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
import com.sun.org.apache.xalan.internal.XalanConstants;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.DOMCache;
@@ -80,6 +79,7 @@
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
+import jdk.xml.internal.XMLSecurityManager;
import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
index 91d8491798e..a54208573fc 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2001-2004 The Apache Software Foundation.
@@ -39,7 +39,7 @@
import javax.xml.transform.stream.StreamSource;
import jdk.xml.internal.JdkXmlFeatures;
import jdk.xml.internal.JdkXmlUtils;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
@@ -118,9 +118,11 @@ public static InputSource getInputSource(XSLTC xsltc, Source source)
(XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
if (securityManager != null) {
for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
- lastProperty = limit.apiProperty();
- reader.setProperty(lastProperty,
- securityManager.getLimitValueAsString(limit));
+ if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) {
+ lastProperty = limit.apiProperty();
+ reader.setProperty(lastProperty,
+ securityManager.getLimitValueAsString(limit));
+ }
}
if (securityManager.printEntityCountInfo()) {
lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java
index 68c3acd3fbb..cac955dd8d8 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java
@@ -58,6 +58,7 @@
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import jdk.xml.internal.JdkXmlUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
@@ -2027,17 +2028,8 @@ public void externalEntityDecl (String name, XMLResourceIdentifier identifier,
else {
fInternalSubset.append (name);
}
- fInternalSubset.append (' ');
- if (publicId != null) {
- fInternalSubset.append ("PUBLIC '");
- fInternalSubset.append (publicId);
- fInternalSubset.append ("' '");
- }
- else {
- fInternalSubset.append ("SYSTEM '");
- }
- fInternalSubset.append (literalSystemId);
- fInternalSubset.append ("'>\n");
+ fInternalSubset.append (JdkXmlUtils.getDTDExternalDecl(publicId, literalSystemId));
+ fInternalSubset.append (">\n");
}
// NOTE: We only know how to create these nodes for the Xerces
@@ -2167,20 +2159,8 @@ public void unparsedEntityDecl (String name, XMLResourceIdentifier identifier,
if (fInternalSubset != null && !fInDTDExternalSubset) {
fInternalSubset.append ("\n");
}
@@ -2247,19 +2227,8 @@ public void notationDecl (String name, XMLResourceIdentifier identifier,
if (fInternalSubset != null && !fInDTDExternalSubset) {
fInternalSubset.append ("\n");
+ fInternalSubset.append (JdkXmlUtils.getDTDExternalDecl(publicId, literalSystemId));
+ fInternalSubset.append (">\n");
}
// NOTE: We only know how to create these nodes for the Xerces
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java
index b3e1fa3d238..255bb04e22e 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java
@@ -32,6 +32,7 @@
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
+import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@@ -44,7 +45,7 @@
* because it is used from another package.
*
* @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2021
*/
public final class ToHTMLStream extends ToStream
{
@@ -680,28 +681,10 @@ protected void startDocumentInternal() throws org.xml.sax.SAXException
final java.io.Writer writer = m_writer;
try
{
- writer.write("');
- outputLineSep();
+ writer.write("');
+ outputLineSep();
}
catch(IOException e)
{
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
index cac28362d0b..76a3c9700f7 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
@@ -57,7 +57,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
- * @LastModified: Apr 2021
+ * @LastModified: July 2021
*/
abstract public class ToStream extends SerializerBase
{
@@ -953,16 +953,8 @@ public void externalEntityDecl(
m_writer.write("");
+ m_writer.write(JdkXmlUtils.getDTDExternalDecl(publicId, systemId));
+ m_writer.write(">");
m_writer.write(m_lineSep, 0, m_lineSepLen);
} catch (IOException e) {
// TODO Auto-generated catch block
@@ -1936,27 +1928,11 @@ void outputDocTypeDecl(String name, boolean closeDecl) throws SAXException
final java.io.Writer writer = m_writer;
writer.write("");
@@ -1964,17 +1940,6 @@ void outputDocTypeDecl(String name, boolean closeDecl) throws SAXException
closeDecl = false; // done closing
}
}
- boolean dothis = false;
- if (dothis)
- {
- // at one point this code seemed right,
- // but not anymore - Brian M.
- if (closeDecl)
- {
- writer.write('>');
- writer.write(m_lineSep, 0, m_lineSepLen);
- }
- }
}
catch (IOException e)
{
@@ -3373,16 +3338,8 @@ public void notationDecl(String name, String pubID, String sysID) throws SAXExce
m_writer.write("");
+ m_writer.write(JdkXmlUtils.getDTDExternalDecl(pubID, sysID));
+ m_writer.write(">");
m_writer.write(m_lineSep, 0, m_lineSepLen);
} catch (IOException e) {
// TODO Auto-generated catch block
@@ -3403,16 +3360,8 @@ public void unparsedEntityDecl(String name, String pubID, String sysID, String n
m_writer.write("");
m_writer.write(m_lineSep, 0, m_lineSepLen);
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
index 39a5e88981a..71a9cf14d63 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 1999-2004 The Apache Software Foundation.
@@ -23,11 +23,11 @@
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import java.util.HashMap;
import javax.xml.XMLConstants;
import jdk.xml.internal.JdkXmlUtils;
+import jdk.xml.internal.XMLSecurityManager;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -133,9 +133,11 @@ public synchronized XMLReader getXMLReader() throws SAXException {
try {
if (_xmlSecurityManager != null) {
for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
- lastProperty = limit.apiProperty();
- reader.setProperty(lastProperty,
- _xmlSecurityManager.getLimitValueAsString(limit));
+ if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) {
+ lastProperty = limit.apiProperty();
+ reader.setProperty(lastProperty,
+ _xmlSecurityManager.getLimitValueAsString(limit));
+ }
}
if (_xmlSecurityManager.printEntityCountInfo()) {
lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/XPath.java b/jaxp/src/com/sun/org/apache/xpath/internal/XPath.java
index 699d464ef0e..2bdfca5e178 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/XPath.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/XPath.java
@@ -28,6 +28,7 @@
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
import com.sun.org.apache.xml.internal.utils.SAXSourceLocator;
import com.sun.org.apache.xpath.internal.compiler.Compiler;
@@ -36,6 +37,7 @@
import com.sun.org.apache.xpath.internal.functions.Function;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
+import jdk.xml.internal.XMLSecurityManager;
/**
* The XPath class wraps an expression object and provides general services
@@ -160,40 +162,11 @@ public String getPatternString()
*
* @throws javax.xml.transform.TransformerException if syntax or other error.
*/
- public XPath(
- String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type,
- ErrorListener errorListener)
- throws javax.xml.transform.TransformerException
+ public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver,
+ int type, ErrorListener errorListener)
+ throws TransformerException
{
- initFunctionTable();
- if(null == errorListener)
- errorListener = new com.sun.org.apache.xml.internal.utils.DefaultErrorHandler();
-
- m_patternString = exprString;
-
- XPathParser parser = new XPathParser(errorListener, locator);
- Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
-
- if (SELECT == type)
- parser.initXPath(compiler, exprString, prefixResolver);
- 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)}));
-
- // System.out.println("----------------");
- Expression expr = compiler.compileExpression(0);
-
- // System.out.println("expr: "+expr);
- this.setExpression(expr);
-
- if((null != locator) && locator instanceof ExpressionNode)
- {
- expr.exprSetParent((ExpressionNode)locator);
- }
-
+ this(exprString, locator, prefixResolver, type, errorListener, null);
}
/**
@@ -207,22 +180,27 @@ else if (MATCH == type)
* namespace URIs.
* @param type one of {@link #SELECT} or {@link #MATCH}.
* @param errorListener The error listener, or null if default should be used.
+ * @param funcTable the function table
+ * @param xmlSecMgr the XML security manager
*
* @throws javax.xml.transform.TransformerException if syntax or other error.
*/
- public XPath(
- String exprString, SourceLocator locator,
- PrefixResolver prefixResolver, int type,
- ErrorListener errorListener, FunctionTable aTable)
- throws javax.xml.transform.TransformerException
+ public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver,
+ int type, ErrorListener errorListener, FunctionTable funcTable,
+ XMLSecurityManager xmlSecMgr)
+ throws TransformerException
{
- m_funcTable = aTable;
+ if (funcTable == null) {
+ initFunctionTable();
+ } else {
+ m_funcTable = funcTable;
+ }
if(null == errorListener)
- errorListener = new com.sun.org.apache.xml.internal.utils.DefaultErrorHandler();
+ errorListener = new DefaultErrorHandler();
m_patternString = exprString;
- XPathParser parser = new XPathParser(errorListener, locator);
+ XPathParser parser = new XPathParser(errorListener, locator, xmlSecMgr);
Compiler compiler = new Compiler(errorListener, locator, m_funcTable);
if (SELECT == type)
@@ -261,13 +239,32 @@ else if (MATCH == type)
*
* @throws javax.xml.transform.TransformerException if syntax or other error.
*/
- public XPath(
- String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type)
- throws javax.xml.transform.TransformerException
+ public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver,
+ int type)
+ throws TransformerException
{
this(exprString, locator, prefixResolver, type, null);
}
+ /**
+ * Constructs an XPath object.
+ *
+ * @param exprString The XPath expression.
+ * @param locator The location of the expression, may be null.
+ * @param prefixResolver A prefix resolver to use to resolve prefixes to
+ * namespace URIs.
+ * @param type one of {@link #SELECT} or {@link #MATCH}.
+ * @param errorListener The error listener, or null if default should be used.
+ * @param funcTable the function table
+ * @throws TransformerException
+ */
+ public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver,
+ int type, ErrorListener errorListener, FunctionTable funcTable)
+ throws TransformerException
+ {
+ this(exprString, locator, prefixResolver, type, errorListener, funcTable, null);
+ }
+
/**
* Construct an XPath object.
*
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Lexer.java b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Lexer.java
index b7206ca5155..c3d57a88ba4 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Lexer.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Lexer.java
@@ -23,8 +23,12 @@
import java.util.Vector;
+import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
+import javax.xml.transform.TransformerException;
+import jdk.xml.internal.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager.Limit;
/**
* This class is in charge of lexical processing of the XPath
@@ -70,6 +74,24 @@ class Lexer
*/
private int m_patternMapSize;
+ // XML security manager
+ XMLSecurityManager m_xmlSecMgr;
+
+ // operator limit
+ private int m_opCountLimit;
+
+ // group limit
+ private int m_grpCountLimit;
+
+ // count of operators
+ private int m_opCount;
+
+ // count of groups
+ private int m_grpCount;
+
+ // indicate whether the current token is a literal
+ private boolean isLiteral = false;
+
/**
* Create a Lexer object.
*
@@ -77,14 +99,22 @@ class Lexer
* @param resolver The prefix resolver for mapping qualified name prefixes
* to namespace URIs.
* @param xpathProcessor The parser that is processing strings to opcodes.
+ * @param xmlSecMgr the XML security manager
*/
Lexer(Compiler compiler, PrefixResolver resolver,
- XPathParser xpathProcessor)
+ XPathParser xpathProcessor, XMLSecurityManager xmlSecMgr)
{
-
m_compiler = compiler;
m_namespaceContext = resolver;
m_processor = xpathProcessor;
+ m_xmlSecMgr = xmlSecMgr;
+ /**
+ * No limits if XML Security Manager is null. Applications using XPath through
+ * the public API always have a XMLSecurityManager. Applications invoking
+ * the internal XPath API shall consider using the public API instead.
+ */
+ m_opCountLimit = (xmlSecMgr != null) ? xmlSecMgr.getLimit(Limit.XPATH_OP_LIMIT) : 0;
+ m_grpCountLimit = (xmlSecMgr != null) ? xmlSecMgr.getLimit(Limit.XPATH_GROUP_LIMIT) : 0;
}
/**
@@ -135,7 +165,7 @@ void tokenize(String pat, Vector targetStrings)
switch (c)
{
- case '\"' :
+ case Token.DQ :
{
if (startSubstring != -1)
{
@@ -170,7 +200,7 @@ void tokenize(String pat, Vector targetStrings)
}
}
break;
- case '\'' :
+ case Token.SQ :
if (startSubstring != -1)
{
isNum = false;
@@ -189,9 +219,9 @@ void tokenize(String pat, Vector targetStrings)
startSubstring = i;
- for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\''); i++);
+ for (i++; (i < nChars) && ((c = pat.charAt(i)) != Token.SQ); i++);
- if (c == '\'' && i < nChars)
+ if (c == Token.SQ && i < nChars)
{
addToTokenQueue(pat.substring(startSubstring, i + 1));
@@ -219,18 +249,24 @@ void tokenize(String pat, Vector targetStrings)
}
else
{
- addToTokenQueue(pat.substring(startSubstring, i));
+ // check operator symbol
+ String s = pat.substring(startSubstring, i);
+ if (Token.contains(s)) {
+ m_opCount++;
+ isLiteral = false;
+ }
+ addToTokenQueue(s);
}
startSubstring = -1;
}
break;
- case '@' :
+ case Token.AT :
isAttrName = true;
// fall-through on purpose
- case '-' :
- if ('-' == c)
+ case Token.MINUS :
+ if (Token.MINUS == c)
{
if (!(isNum || (startSubstring == -1)))
{
@@ -241,22 +277,22 @@ void tokenize(String pat, Vector targetStrings)
}
// fall-through on purpose
- case '(' :
- case '[' :
- case ')' :
- case ']' :
- case '|' :
- case '/' :
- case '*' :
- case '+' :
- case '=' :
- case ',' :
+ case Token.LPAREN :
+ case Token.LBRACK :
+ case Token.RPAREN :
+ case Token.RBRACK :
+ case Token.VBAR :
+ case Token.SLASH :
+ case Token.STAR :
+ case Token.PLUS :
+ case Token.EQ :
+ case Token.COMMA :
case '\\' : // Unused at the moment
case '^' : // Unused at the moment
- case '!' : // Unused at the moment
- case '$' :
- case '<' :
- case '>' :
+ case Token.EM : // Unused at the moment
+ case Token.DOLLAR :
+ case Token.LT :
+ case Token.GT :
if (startSubstring != -1)
{
isNum = false;
@@ -274,11 +310,11 @@ void tokenize(String pat, Vector targetStrings)
startSubstring = -1;
}
- else if (('/' == c) && isStartOfPat)
+ else if ((Token.SLASH == c) && isStartOfPat)
{
isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
}
- else if ('*' == c)
+ else if (Token.STAR == c)
{
isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
isAttrName = false;
@@ -286,7 +322,7 @@ else if ('*' == c)
if (0 == nesting)
{
- if ('|' == c)
+ if (Token.VBAR == c)
{
if (null != targetStrings)
{
@@ -297,18 +333,32 @@ else if ('*' == c)
}
}
- if ((')' == c) || (']' == c))
+ if ((Token.RPAREN == c) || (Token.RBRACK == c))
{
nesting--;
}
- else if (('(' == c) || ('[' == c))
+ else if ((Token.LPAREN == c) || (Token.LBRACK == c))
{
nesting++;
+ if (!isLiteral && (Token.LPAREN == c)) {
+ m_grpCount++;
+ m_opCount++;
+ isLiteral = false;
+ }
+ }
+
+ if ((Token.GT == c || Token.LT == c || Token.EQ == c) && Token.EQ != peekNext(pat, i)) {
+ m_opCount++;
+ isLiteral = false;
+ }
+ else if ((Token.LPAREN != c) && (Token.RPAREN != c) && (Token.RBRACK != c)) {
+ m_opCount++;
+ isLiteral = false;
}
addToTokenQueue(pat.substring(i, i + 1));
break;
- case ':' :
+ case Token.COLON_CHAR:
if (i>0)
{
if (posOfNSSep == (i - 1))
@@ -323,7 +373,7 @@ else if (('(' == c) || ('[' == c))
isAttrName = false;
startSubstring = -1;
posOfNSSep = -1;
-
+ m_opCount++;
addToTokenQueue(pat.substring(i - 1, i + 1));
break;
@@ -336,6 +386,7 @@ else if (('(' == c) || ('[' == c))
// fall through on purpose
default :
+ isLiteral = true;
if (-1 == startSubstring)
{
startSubstring = i;
@@ -346,6 +397,20 @@ else if (isNum)
isNum = Character.isDigit(c);
}
}
+ if (m_grpCountLimit > 0 && m_grpCount > m_grpCountLimit) {
+ throw new TransformerException(XSLMessages.createXPATHMessage(
+ XPATHErrorResources.ER_XPATH_GROUP_LIMIT,
+ new Object[]{Integer.toString(m_grpCount),
+ Integer.toString(m_grpCountLimit),
+ m_xmlSecMgr.getStateLiteral(Limit.XPATH_GROUP_LIMIT)}));
+ }
+ if (m_opCountLimit > 0 && m_opCount > m_opCountLimit) {
+ throw new TransformerException(XSLMessages.createXPATHMessage(
+ XPATHErrorResources.ER_XPATH_OPERATOR_LIMIT,
+ new Object[]{Integer.toString(m_opCount),
+ Integer.toString(m_opCountLimit),
+ m_xmlSecMgr.getStateLiteral(Limit.XPATH_OP_LIMIT)}));
+ }
}
if (startSubstring != -1)
@@ -376,6 +441,19 @@ else if (null != targetStrings)
m_processor.m_queueMark = 0;
}
+ /**
+ * Peeks at the next character without advancing the index.
+ * @param s the input string
+ * @param index the current index
+ * @return the next char
+ */
+ private char peekNext(String s, int index) {
+ if (index >= 0 && index < s.length() - 1) {
+ return s.charAt(index + 1);
+ }
+ return 0;
+ }
+
/**
* Record the current position on the token queue as long as
* this is a top-level element. Must be called before the
@@ -498,7 +576,7 @@ private void recordTokenString(Vector targetStrings)
resetTokenMark(tokPos + 1);
- if (m_processor.lookahead('(', 1))
+ if (m_processor.lookahead(Token.LPAREN, 1))
{
int tok = getKeywordToken(m_processor.m_token);
@@ -528,14 +606,14 @@ private void recordTokenString(Vector targetStrings)
}
else
{
- if (m_processor.tokenIs('@'))
+ if (m_processor.tokenIs(Token.AT))
{
tokPos++;
resetTokenMark(tokPos + 1);
}
- if (m_processor.lookahead(':', 1))
+ if (m_processor.lookahead(Token.COLON_CHAR, 1))
{
tokPos += 2;
}
@@ -564,13 +642,13 @@ private final void addToTokenQueue(String s)
* @param posOfNSSep The position of the namespace seperator (':').
* @param posOfScan The end of the name index.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*
* @return -1 always.
*/
private int mapNSTokens(String pat, int startSubstring, int posOfNSSep,
int posOfScan)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
String prefix = "";
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Token.java b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Token.java
new file mode 100644
index 00000000000..51bb2d689c5
--- /dev/null
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/Token.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022, 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
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xpath.internal.compiler;
+
+import java.util.Arrays;
+
+/**
+ * XPath tokens
+ */
+public final class Token {
+ static final char EM = '!';
+ static final char EQ = '=';
+ static final char LT = '<';
+ static final char GT = '>';
+ static final char PLUS = '+';
+ static final char MINUS = '-';
+ static final char STAR = '*';
+ static final char VBAR = '|';
+ static final char SLASH = '/';
+ static final char LBRACK = '[';
+ static final char RBRACK = ']';
+ static final char LPAREN = '(';
+ static final char RPAREN = ')';
+ static final char COMMA = ',';
+ static final char AT = '@';
+ static final char US = '_';
+ static final char COLON_CHAR = ':';
+ static final char SQ = '\'';
+ static final char DQ = '"';
+ static final char DOLLAR = '$';
+
+ static final String OR = "or";
+ static final String AND = "and";
+ static final String DIV = "div";
+ static final String MOD = "mod";
+ static final String QUO = "quo";
+ static final String DOT = ".";
+ static final String DDOT = "..";
+ static final String DCOLON = "::";
+ static final String ATTR = "attribute";
+ static final String CHILD = "child";
+
+ static final String[] OPERATORS = {OR, AND, DIV, MOD, QUO,
+ DDOT, DCOLON, ATTR, CHILD};
+
+ public static boolean contains(String str) {
+ for (String op : OPERATORS) {
+ if (op.equals(str)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Token() {
+ //to prevent instantiation
+ }
+}
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java
index e72588a4c4c..64eac0ed33f 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/compiler/XPathParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,9 +20,6 @@
package com.sun.org.apache.xpath.internal.compiler;
-import javax.xml.transform.ErrorListener;
-import javax.xml.transform.TransformerException;
-
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
import com.sun.org.apache.xpath.internal.XPathProcessorException;
@@ -30,12 +27,18 @@
import com.sun.org.apache.xpath.internal.objects.XNumber;
import com.sun.org.apache.xpath.internal.objects.XString;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
+import java.util.Objects;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import jdk.xml.internal.XMLSecurityManager;
+import jdk.xml.internal.XMLSecurityManager.Limit;
/**
* Tokenizes and parses XPath expressions. This should really be named
* XPathParserImpl, and may be renamed in the future.
* @xsl.usage general
- * @LastModified: May 2019
+ * @LastModified: Jan 2022
*/
public class XPathParser
{
@@ -76,13 +79,18 @@ public class XPathParser
// counts open predicates
private int countPredicate;
+ // XML security manager
+ XMLSecurityManager m_xmlSecMgr;
+
/**
* The parser constructor.
*/
- public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocator sourceLocator)
+ public XPathParser(ErrorListener errorListener, SourceLocator sourceLocator,
+ XMLSecurityManager xmlSecMgr)
{
m_errorListener = errorListener;
m_sourceLocator = sourceLocator;
+ m_xmlSecMgr = xmlSecMgr;
}
/**
@@ -100,18 +108,18 @@ public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocato
* @param namespaceContext An object that is able to resolve prefixes in
* the XPath to namespaces.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
public void initXPath(
Compiler compiler, String expression, PrefixResolver namespaceContext)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
m_ops = compiler;
m_namespaceContext = namespaceContext;
m_functionTable = compiler.getFunctionTable();
- Lexer lexer = new Lexer(compiler, namespaceContext, this);
+ Lexer lexer = new Lexer(compiler, namespaceContext, this, m_xmlSecMgr);
lexer.tokenize(expression);
@@ -179,18 +187,18 @@ public void initXPath(
* @param namespaceContext An object that is able to resolve prefixes in
* the XPath to namespaces.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
public void initMatchPattern(
Compiler compiler, String expression, PrefixResolver namespaceContext)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
m_ops = compiler;
m_namespaceContext = namespaceContext;
m_functionTable = compiler.getFunctionTable();
- Lexer lexer = new Lexer(compiler, namespaceContext, this);
+ Lexer lexer = new Lexer(compiler, namespaceContext, this, m_xmlSecMgr);
lexer.tokenize(expression);
@@ -383,9 +391,9 @@ private final boolean lookbehindHasToken(int n)
if ((m_queueMark - n) > 0)
{
String lookbehind = (String) m_ops.m_tokenQueue.elementAt(m_queueMark - (n - 1));
- char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);
+ char c0 = (lookbehind == null) ? Token.VBAR : lookbehind.charAt(0);
- hasToken = (c0 == '|') ? false : true;
+ hasToken = (c0 == Token.VBAR) ? false : true;
}
else
{
@@ -497,10 +505,10 @@ private final void prevToken()
*
* @param expected The string to be expected.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
private final void consumeExpected(String expected)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
if (tokenIs(expected))
@@ -525,10 +533,10 @@ private final void consumeExpected(String expected)
*
* @param expected the character to be expected.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
private final void consumeExpected(char expected)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
if (tokenIs(expected))
@@ -795,9 +803,9 @@ void appendOp(int length, int op)
* Expr ::= OrExpr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Expr() throws javax.xml.transform.TransformerException
+ protected void Expr() throws TransformerException
{
OrExpr();
}
@@ -809,16 +817,16 @@ protected void Expr() throws javax.xml.transform.TransformerException
* | OrExpr 'or' AndExpr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void OrExpr() throws javax.xml.transform.TransformerException
+ protected void OrExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
AndExpr();
- if ((null != m_token) && tokenIs("or"))
+ if ((null != m_token) && tokenIs(Token.OR))
{
nextToken();
insertOp(opPos, 2, OpCodes.OP_OR);
@@ -836,16 +844,16 @@ protected void OrExpr() throws javax.xml.transform.TransformerException
* | AndExpr 'and' EqualityExpr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void AndExpr() throws javax.xml.transform.TransformerException
+ protected void AndExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
EqualityExpr(-1);
- if ((null != m_token) && tokenIs("and"))
+ if ((null != m_token) && tokenIs(Token.AND))
{
nextToken();
insertOp(opPos, 2, OpCodes.OP_AND);
@@ -869,9 +877,9 @@ protected void AndExpr() throws javax.xml.transform.TransformerException
*
* @return the position at the end of the equality expression.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerException
+ protected int EqualityExpr(int addPos) throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -883,7 +891,7 @@ protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerExc
if (null != m_token)
{
- if (tokenIs('!') && lookahead('=', 1))
+ if (tokenIs(Token.EM) && lookahead(Token.EQ, 1))
{
nextToken();
nextToken();
@@ -896,7 +904,7 @@ protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerExc
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs('='))
+ else if (tokenIs(Token.EQ))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_EQUALS);
@@ -929,9 +937,9 @@ else if (tokenIs('='))
*
* @return the position at the end of the relational expression.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerException
+ protected int RelationalExpr(int addPos) throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -943,11 +951,11 @@ protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerE
if (null != m_token)
{
- if (tokenIs('<'))
+ if (tokenIs(Token.LT))
{
nextToken();
- if (tokenIs('='))
+ if (tokenIs(Token.EQ))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_LTE);
@@ -964,11 +972,11 @@ protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerE
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs('>'))
+ else if (tokenIs(Token.GT))
{
nextToken();
- if (tokenIs('='))
+ if (tokenIs(Token.EQ))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_GTE);
@@ -1004,9 +1012,9 @@ else if (tokenIs('>'))
*
* @return the position at the end of the equality expression.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerException
+ protected int AdditiveExpr(int addPos) throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1018,7 +1026,7 @@ protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerExc
if (null != m_token)
{
- if (tokenIs('+'))
+ if (tokenIs(Token.PLUS))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_PLUS);
@@ -1030,7 +1038,7 @@ protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerExc
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs('-'))
+ else if (tokenIs(Token.MINUS))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_MINUS);
@@ -1062,9 +1070,9 @@ else if (tokenIs('-'))
*
* @return the position at the end of the equality expression.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.TransformerException
+ protected int MultiplicativeExpr(int addPos) throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1076,7 +1084,7 @@ protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.Transfor
if (null != m_token)
{
- if (tokenIs('*'))
+ if (tokenIs(Token.STAR))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_MULT);
@@ -1088,7 +1096,7 @@ protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.Transfor
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs("div"))
+ else if (tokenIs(Token.DIV))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_DIV);
@@ -1100,7 +1108,7 @@ else if (tokenIs("div"))
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs("mod"))
+ else if (tokenIs(Token.MOD))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_MOD);
@@ -1112,7 +1120,7 @@ else if (tokenIs("mod"))
m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen);
addPos += 2;
}
- else if (tokenIs("quo"))
+ else if (tokenIs(Token.QUO))
{
nextToken();
insertOp(addPos, 2, OpCodes.OP_QUO);
@@ -1135,15 +1143,15 @@ else if (tokenIs("quo"))
* | '-' UnaryExpr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void UnaryExpr() throws javax.xml.transform.TransformerException
+ protected void UnaryExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
boolean isNeg = false;
- if (m_tokenChar == '-')
+ if (m_tokenChar == Token.MINUS)
{
nextToken();
appendOp(2, OpCodes.OP_NEG);
@@ -1163,9 +1171,9 @@ protected void UnaryExpr() throws javax.xml.transform.TransformerException
* StringExpr ::= Expr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void StringExpr() throws javax.xml.transform.TransformerException
+ protected void StringExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1183,9 +1191,9 @@ protected void StringExpr() throws javax.xml.transform.TransformerException
* StringExpr ::= Expr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void BooleanExpr() throws javax.xml.transform.TransformerException
+ protected void BooleanExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1209,9 +1217,9 @@ protected void BooleanExpr() throws javax.xml.transform.TransformerException
* NumberExpr ::= Expr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void NumberExpr() throws javax.xml.transform.TransformerException
+ protected void NumberExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1234,9 +1242,9 @@ protected void NumberExpr() throws javax.xml.transform.TransformerException
* | UnionExpr '|' PathExpr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void UnionExpr() throws javax.xml.transform.TransformerException
+ protected void UnionExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1247,7 +1255,7 @@ protected void UnionExpr() throws javax.xml.transform.TransformerException
{
PathExpr();
- if (tokenIs('|'))
+ if (tokenIs(Token.VBAR))
{
if (false == foundUnion)
{
@@ -1280,9 +1288,9 @@ protected void UnionExpr() throws javax.xml.transform.TransformerException
* @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
* the error condition is severe enough to halt processing.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void PathExpr() throws javax.xml.transform.TransformerException
+ protected void PathExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1295,7 +1303,7 @@ protected void PathExpr() throws javax.xml.transform.TransformerException
// have been inserted.
boolean locationPathStarted = (filterExprMatch==FILTER_MATCH_PREDICATES);
- if (tokenIs('/'))
+ if (tokenIs(Token.SLASH))
{
nextToken();
@@ -1345,9 +1353,9 @@ protected void PathExpr() throws javax.xml.transform.TransformerException
* FilterExpr that was just a PrimaryExpr; or
* FILTER_MATCH_FAILED, if this method did not match a FilterExpr
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int FilterExpr() throws javax.xml.transform.TransformerException
+ protected int FilterExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1356,13 +1364,13 @@ protected int FilterExpr() throws javax.xml.transform.TransformerException
if (PrimaryExpr())
{
- if (tokenIs('['))
+ if (tokenIs(Token.LBRACK))
{
// int locationPathOpPos = opPos;
insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
- while (tokenIs('['))
+ while (tokenIs(Token.LBRACK))
{
Predicate();
}
@@ -1400,16 +1408,16 @@ protected int FilterExpr() throws javax.xml.transform.TransformerException
*
* @return true if this method successfully matched a PrimaryExpr
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*
*/
- protected boolean PrimaryExpr() throws javax.xml.transform.TransformerException
+ protected boolean PrimaryExpr() throws TransformerException
{
boolean matchFound;
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
- if ((m_tokenChar == '\'') || (m_tokenChar == '"'))
+ if ((m_tokenChar == Token.SQ) || (m_tokenChar == Token.DQ))
{
appendOp(2, OpCodes.OP_LITERAL);
Literal();
@@ -1419,7 +1427,7 @@ protected boolean PrimaryExpr() throws javax.xml.transform.TransformerException
matchFound = true;
}
- else if (m_tokenChar == '$')
+ else if (m_tokenChar == Token.DOLLAR)
{
nextToken(); // consume '$'
appendOp(2, OpCodes.OP_VARIABLE);
@@ -1430,12 +1438,12 @@ else if (m_tokenChar == '$')
matchFound = true;
}
- else if (m_tokenChar == '(')
+ else if (m_tokenChar == Token.LPAREN)
{
nextToken();
appendOp(2, OpCodes.OP_GROUP);
Expr();
- consumeExpected(')');
+ consumeExpected(Token.RPAREN);
m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH,
m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
@@ -1453,7 +1461,7 @@ else if ((null != m_token) && ((('.' == m_tokenChar) && (m_token.length() > 1) &
matchFound = true;
}
- else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3)))
+ else if (lookahead(Token.LPAREN, 1) || (lookahead(Token.COLON_CHAR, 1) && lookahead(Token.LPAREN, 3)))
{
matchFound = FunctionCall();
}
@@ -1470,9 +1478,9 @@ else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3)))
* Argument ::= Expr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Argument() throws javax.xml.transform.TransformerException
+ protected void Argument() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1490,14 +1498,14 @@ protected void Argument() throws javax.xml.transform.TransformerException
*
* @return true if, and only if, a FunctionCall was matched
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected boolean FunctionCall() throws javax.xml.transform.TransformerException
+ protected boolean FunctionCall() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
- if (lookahead(':', 1))
+ if (lookahead(Token.COLON_CHAR, 1))
{
appendOp(4, OpCodes.OP_EXTFUNCTION);
@@ -1537,22 +1545,23 @@ protected boolean FunctionCall() throws javax.xml.transform.TransformerException
nextToken();
}
- consumeExpected('(');
+ consumeExpected(Token.LPAREN);
- while (!tokenIs(')') && m_token != null)
+ while (!tokenIs(Token.RPAREN) && m_token != null)
{
- if (tokenIs(','))
+ if (tokenIs(Token.COMMA))
{
- error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null); //"Found ',' but no preceding argument!");
+ //"Found ',' but no preceding argument!");
+ error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null);
}
Argument();
- if (!tokenIs(')'))
+ if (!tokenIs(Token.RPAREN))
{
- consumeExpected(',');
+ consumeExpected(Token.COMMA);
- if (tokenIs(')'))
+ if (tokenIs(Token.RPAREN))
{
error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG,
null); //"Found ',' but no following argument!");
@@ -1560,7 +1569,7 @@ protected boolean FunctionCall() throws javax.xml.transform.TransformerException
}
}
- consumeExpected(')');
+ consumeExpected(Token.RPAREN);
// Terminate for safety.
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);
@@ -1579,9 +1588,9 @@ protected boolean FunctionCall() throws javax.xml.transform.TransformerException
* | AbsoluteLocationPath
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void LocationPath() throws javax.xml.transform.TransformerException
+ protected void LocationPath() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1589,7 +1598,7 @@ protected void LocationPath() throws javax.xml.transform.TransformerException
// int locationPathOpPos = opPos;
appendOp(2, OpCodes.OP_LOCATIONPATH);
- boolean seenSlash = tokenIs('/');
+ boolean seenSlash = tokenIs(Token.SLASH);
if (seenSlash)
{
@@ -1630,17 +1639,17 @@ protected void LocationPath() throws javax.xml.transform.TransformerException
*
* @returns true if, and only if, a RelativeLocationPath was matched
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
protected boolean RelativeLocationPath()
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
if (!Step())
{
return false;
}
- while (tokenIs('/'))
+ while (tokenIs(Token.SLASH))
{
nextToken();
@@ -1662,13 +1671,13 @@ protected boolean RelativeLocationPath()
*
* @returns false if step was empty (or only a '/'); true, otherwise
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected boolean Step() throws javax.xml.transform.TransformerException
+ protected boolean Step() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
- boolean doubleSlash = tokenIs('/');
+ boolean doubleSlash = tokenIs(Token.SLASH);
// At most a single '/' before each Step is consumed by caller; if the
// first thing is a '/', that means we had '//' and the Step must not
@@ -1700,11 +1709,11 @@ protected boolean Step() throws javax.xml.transform.TransformerException
opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
}
- if (tokenIs("."))
+ if (tokenIs(Token.DOT))
{
nextToken();
- if (tokenIs('['))
+ if (tokenIs(Token.LBRACK))
{
error(XPATHErrorResources.ER_PREDICATE_ILLEGAL_SYNTAX, null); //"'..[predicate]' or '.[predicate]' is illegal syntax. Use 'self::node()[predicate]' instead.");
}
@@ -1715,7 +1724,7 @@ protected boolean Step() throws javax.xml.transform.TransformerException
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2,4);
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_NODE);
}
- else if (tokenIs(".."))
+ else if (tokenIs(Token.DDOT))
{
nextToken();
appendOp(4, OpCodes.FROM_PARENT);
@@ -1728,12 +1737,12 @@ else if (tokenIs(".."))
// There is probably a better way to test for this
// transition... but it gets real hairy if you try
// to do it in basis().
- else if (tokenIs('*') || tokenIs('@') || tokenIs('_')
+ else if (tokenIs(Token.STAR) || tokenIs(Token.AT) || tokenIs(Token.US)
|| (m_token!= null && Character.isLetter(m_token.charAt(0))))
{
Basis();
- while (tokenIs('['))
+ while (tokenIs(Token.LBRACK))
{
Predicate();
}
@@ -1762,23 +1771,23 @@ else if (tokenIs('*') || tokenIs('@') || tokenIs('_')
* Basis ::= AxisName '::' NodeTest
* | AbbreviatedBasis
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Basis() throws javax.xml.transform.TransformerException
+ protected void Basis() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
int axesType;
// The next blocks guarantee that a FROM_XXX will be added.
- if (lookahead("::", 1))
+ if (lookahead(Token.DCOLON, 1))
{
axesType = AxisName();
nextToken();
nextToken();
}
- else if (tokenIs('@'))
+ else if (tokenIs(Token.AT))
{
axesType = OpCodes.FROM_ATTRIBUTES;
@@ -1809,9 +1818,9 @@ else if (tokenIs('@'))
*
* @return FROM_XXX axes type, found in {@link com.sun.org.apache.xpath.internal.compiler.Keywords}.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected int AxisName() throws javax.xml.transform.TransformerException
+ protected int AxisName() throws TransformerException
{
Object val = Keywords.getAxisName(m_token);
@@ -1837,12 +1846,12 @@ protected int AxisName() throws javax.xml.transform.TransformerException
*
* @param axesType FROM_XXX axes type, found in {@link com.sun.org.apache.xpath.internal.compiler.Keywords}.
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void NodeTest(int axesType) throws javax.xml.transform.TransformerException
+ protected void NodeTest(int axesType) throws TransformerException
{
- if (lookahead('(', 1))
+ if (lookahead(Token.LPAREN, 1))
{
Object nodeTestOp = Keywords.getNodeType(m_token);
@@ -1860,17 +1869,17 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), nt);
m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
- consumeExpected('(');
+ consumeExpected(Token.LPAREN);
if (OpCodes.NODETYPE_PI == nt)
{
- if (!tokenIs(')'))
+ if (!tokenIs(Token.RPAREN))
{
Literal();
}
}
- consumeExpected(')');
+ consumeExpected(Token.RPAREN);
}
}
else
@@ -1880,9 +1889,9 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.NODENAME);
m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
- if (lookahead(':', 1))
+ if (lookahead(Token.COLON_CHAR, 1))
{
- if (tokenIs('*'))
+ if (tokenIs(Token.STAR))
{
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD);
}
@@ -1892,7 +1901,7 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
// Minimalist check for an NCName - just check first character
// to distinguish from other possible tokens
- if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+ if (!Character.isLetter(m_tokenChar) && !tokenIs(Token.US))
{
// "Node test that matches either NCName:* or QName was expected."
error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
@@ -1909,7 +1918,7 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
- if (tokenIs('*'))
+ if (tokenIs(Token.STAR))
{
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD);
}
@@ -1919,7 +1928,7 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
// Minimalist check for an NCName - just check first character
// to distinguish from other possible tokens
- if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
+ if (!Character.isLetter(m_tokenChar) && !tokenIs(Token.US))
{
// "Node test that matches either NCName:* or QName was expected."
error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
@@ -1937,11 +1946,11 @@ protected void NodeTest(int axesType) throws javax.xml.transform.TransformerExce
* Predicate ::= '[' PredicateExpr ']'
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Predicate() throws javax.xml.transform.TransformerException
+ protected void Predicate() throws TransformerException
{
- if (tokenIs('['))
+ if (tokenIs(Token.LBRACK))
{
countPredicate++;
nextToken();
@@ -1956,9 +1965,9 @@ protected void Predicate() throws javax.xml.transform.TransformerException
* PredicateExpr ::= Expr
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void PredicateExpr() throws javax.xml.transform.TransformerException
+ protected void PredicateExpr() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -1978,12 +1987,12 @@ protected void PredicateExpr() throws javax.xml.transform.TransformerException
* Prefix ::= NCName
* LocalPart ::= NCName
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void QName() throws javax.xml.transform.TransformerException
+ protected void QName() throws TransformerException
{
// Namespace
- if(lookahead(':', 1))
+ if(lookahead(Token.COLON_CHAR, 1))
{
m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1);
m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1);
@@ -2025,16 +2034,16 @@ protected void NCName()
* | "'" [^']* "'"
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Literal() throws javax.xml.transform.TransformerException
+ protected void Literal() throws TransformerException
{
int last = m_token.length() - 1;
char c0 = m_tokenChar;
char cX = m_token.charAt(last);
- if (((c0 == '\"') && (cX == '\"')) || ((c0 == '\'') && (cX == '\'')))
+ if (((c0 == Token.DQ) && (cX == Token.DQ)) || ((c0 == Token.SQ) && (cX == Token.SQ)))
{
// Mutate the token to remove the quotes and have the XString object
@@ -2065,9 +2074,9 @@ protected void Literal() throws javax.xml.transform.TransformerException
* Number ::= [0-9]+('.'[0-9]+)? | '.'[0-9]+
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Number() throws javax.xml.transform.TransformerException
+ protected void Number() throws TransformerException
{
if (null != m_token)
@@ -2108,16 +2117,16 @@ protected void Number() throws javax.xml.transform.TransformerException
* | Pattern '|' LocationPathPattern
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void Pattern() throws javax.xml.transform.TransformerException
+ protected void Pattern() throws TransformerException
{
while (true)
{
LocationPathPattern();
- if (tokenIs('|'))
+ if (tokenIs(Token.VBAR))
{
nextToken();
}
@@ -2136,9 +2145,9 @@ protected void Pattern() throws javax.xml.transform.TransformerException
* | '//'? RelativePathPattern
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void LocationPathPattern() throws javax.xml.transform.TransformerException
+ protected void LocationPathPattern() throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -2151,17 +2160,17 @@ protected void LocationPathPattern() throws javax.xml.transform.TransformerExcep
appendOp(2, OpCodes.OP_LOCATIONPATHPATTERN);
- if (lookahead('(', 1)
+ if (lookahead(Token.LPAREN, 1)
&& (tokenIs(Keywords.FUNC_ID_STRING)
|| tokenIs(Keywords.FUNC_KEY_STRING)))
{
IdKeyPattern();
- if (tokenIs('/'))
+ if (tokenIs(Token.SLASH))
{
nextToken();
- if (tokenIs('/'))
+ if (tokenIs(Token.SLASH))
{
appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
@@ -2179,9 +2188,9 @@ protected void LocationPathPattern() throws javax.xml.transform.TransformerExcep
relativePathStatus = RELATIVE_PATH_REQUIRED;
}
}
- else if (tokenIs('/'))
+ else if (tokenIs(Token.SLASH))
{
- if (lookahead('/', 1))
+ if (lookahead(Token.SLASH, 1))
{
appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
@@ -2214,7 +2223,7 @@ else if (tokenIs('/'))
if (relativePathStatus != RELATIVE_PATH_NOT_PERMITTED)
{
- if (!tokenIs('|') && (null != m_token))
+ if (!tokenIs(Token.VBAR) && (null != m_token))
{
RelativePathPattern();
}
@@ -2239,9 +2248,9 @@ else if (relativePathStatus == RELATIVE_PATH_REQUIRED)
* (Also handle doc())
*
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
- protected void IdKeyPattern() throws javax.xml.transform.TransformerException
+ protected void IdKeyPattern() throws TransformerException
{
FunctionCall();
}
@@ -2252,17 +2261,17 @@ protected void IdKeyPattern() throws javax.xml.transform.TransformerException
* | RelativePathPattern '/' StepPattern
* | RelativePathPattern '//' StepPattern
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
protected void RelativePathPattern()
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
// Caller will have consumed any '/' or '//' preceding the
// RelativePathPattern, so let StepPattern know it can't begin with a '/'
boolean trailingSlashConsumed = StepPattern(false);
- while (tokenIs('/'))
+ while (tokenIs(Token.SLASH))
{
nextToken();
@@ -2282,10 +2291,10 @@ protected void RelativePathPattern()
*
* @return boolean indicating whether a slash following the step was consumed
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
protected boolean StepPattern(boolean isLeadingSlashPermitted)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
return AbbreviatedNodeTestStep(isLeadingSlashPermitted);
}
@@ -2299,10 +2308,10 @@ protected boolean StepPattern(boolean isLeadingSlashPermitted)
*
* @return boolean indicating whether a slash following the step was consumed
*
- * @throws javax.xml.transform.TransformerException
+ * @throws TransformerException
*/
protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted)
- throws javax.xml.transform.TransformerException
+ throws TransformerException
{
int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
@@ -2311,22 +2320,22 @@ protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted)
// The next blocks guarantee that a MATCH_XXX will be added.
int matchTypePos = -1;
- if (tokenIs('@'))
+ if (tokenIs(Token.AT))
{
axesType = OpCodes.MATCH_ATTRIBUTE;
appendOp(2, axesType);
nextToken();
}
- else if (this.lookahead("::", 1))
+ else if (this.lookahead(Token.DCOLON, 1))
{
- if (tokenIs("attribute"))
+ if (tokenIs(Token.ATTR))
{
axesType = OpCodes.MATCH_ATTRIBUTE;
appendOp(2, axesType);
}
- else if (tokenIs("child"))
+ else if (tokenIs(Token.CHILD))
{
matchTypePos = m_ops.getOp(OpMap.MAPINDEX_LENGTH);
axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
@@ -2344,7 +2353,7 @@ else if (tokenIs("child"))
nextToken();
nextToken();
}
- else if (tokenIs('/'))
+ else if (tokenIs(Token.SLASH))
{
if (!isLeadingSlashPermitted)
{
@@ -2373,7 +2382,7 @@ else if (tokenIs('/'))
m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1,
m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos);
- while (tokenIs('['))
+ while (tokenIs(Token.LBRACK))
{
Predicate();
}
@@ -2392,7 +2401,7 @@ else if (tokenIs('/'))
// If current step is on the attribute axis (e.g., "@x//b"), we won't
// change the current step, and let following step be marked as
// MATCH_ANY_ANCESTOR on next call instead.
- if ((matchTypePos > -1) && tokenIs('/') && lookahead('/', 1))
+ if ((matchTypePos > -1) && tokenIs(Token.SLASH) && lookahead(Token.SLASH, 1))
{
m_ops.setOp(matchTypePos, OpCodes.MATCH_ANY_ANCESTOR);
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java b/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java
index 5bb7468c60e..0f1a2262c3e 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java
@@ -30,6 +30,7 @@
import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver;
import jdk.xml.internal.JdkXmlFeatures;
+import jdk.xml.internal.XMLSecurityManager;
/**
* The XPathFactory builds XPaths.
@@ -67,6 +68,12 @@ public class XPathFactoryImpl extends XPathFactory {
*/
private final JdkXmlFeatures _featureManager;
+
+ /**
+ * The XML security manager
+ */
+ private XMLSecurityManager _xmlSecMgr;
+
/**
* javax.xml.xpath.XPathFactory implementation.
*/
@@ -77,6 +84,7 @@ public XPathFactoryImpl() {
_isNotSecureProcessing = false;
}
_featureManager = new JdkXmlFeatures(!_isNotSecureProcessing);
+ _xmlSecMgr = new XMLSecurityManager(true);
}
/**
*
Is specified object model supported by this
@@ -126,7 +134,7 @@ public boolean isObjectModelSupported(String objectModel) {
public javax.xml.xpath.XPath newXPath() {
return new com.sun.org.apache.xpath.internal.jaxp.XPathImpl(
xPathVariableResolver, xPathFunctionResolver,
- !_isNotSecureProcessing, _featureManager );
+ !_isNotSecureProcessing, _featureManager, _xmlSecMgr);
}
/**
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java b/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java
index 8c6437a0c83..8d15deaad30 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -46,6 +46,7 @@
import java.io.IOException;
import jdk.xml.internal.JdkXmlFeatures;
+import jdk.xml.internal.XMLSecurityManager;
import jdk.xml.internal.JdkXmlUtils;
/**
@@ -71,19 +72,23 @@ public class XPathImpl implements javax.xml.xpath.XPath {
private boolean featureSecureProcessing = false;
private boolean overrideDefaultParser = true;
private final JdkXmlFeatures featureManager;
+ XMLSecurityManager xmlSecMgr;
- XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) {
- this(vr, fr, false, new JdkXmlFeatures(false));
+ XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
+ this(vr, fr, false, new JdkXmlFeatures(false), new XMLSecurityManager(true));
}
- XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr,
- boolean featureSecureProcessing, JdkXmlFeatures featureManager) {
+ XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
+ boolean featureSecureProcessing, JdkXmlFeatures featureManager,
+ XMLSecurityManager xmlSecMgr) {
this.origVariableResolver = this.variableResolver = vr;
this.origFunctionResolver = this.functionResolver = fr;
this.featureSecureProcessing = featureSecureProcessing;
this.featureManager = featureManager;
this.overrideDefaultParser = featureManager.getFeature(
JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER);
+
+ this.xmlSecMgr = xmlSecMgr;
}
/**
@@ -186,7 +191,7 @@ private DocumentBuilder getParser() {
private XObject eval(String expression, Object contextItem)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
- null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
+ null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT, null, null, xmlSecMgr);
com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
if ( functionResolver != null ) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
@@ -387,7 +392,7 @@ public XPathExpression compile(String expression)
}
try {
com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
- prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
+ prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT, null, null, xmlSecMgr);
// Can have errorListener
XPathExpressionImpl ximpl = new XPathExpressionImpl(xpath,
prefixResolver, functionResolver, variableResolver,
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java b/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java
index 021a9b6415b..cdea6d69976 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,7 +31,7 @@
* 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
+ * @LastModified: Jan 2022
*/
public class XPATHErrorResources extends ListResourceBundle
{
@@ -321,6 +321,9 @@ public class XPATHErrorResources extends ListResourceBundle
public static final String ER_SECUREPROCESSING_FEATURE = "ER_SECUREPROCESSING_FEATURE";
public static final String ER_NULL_XPATH_FUNCTION_RESOLVER = "ER_NULL_XPATH_FUNCTION_RESOLVER";
public static final String ER_NULL_XPATH_VARIABLE_RESOLVER = "ER_NULL_XPATH_VARIABLE_RESOLVER";
+ public static final String ER_XPATH_GROUP_LIMIT = "XPATH_GROUP_LIMIT";
+ public static final String ER_XPATH_OPERATOR_LIMIT = "XPATH_OPERATOR_LIMIT";
+
//END: Keys needed for exception messages of JAXP 1.3 XPath API implementation
public static final String WG_LOCALE_NAME_NOT_HANDLED =
@@ -832,6 +835,14 @@ public class XPATHErrorResources extends ListResourceBundle
{ ER_NULL_XPATH_VARIABLE_RESOLVER,
"Attempting to set a null XPathVariableResolver:{0}#setXPathVariableResolver(null)"},
+ { ER_XPATH_GROUP_LIMIT,
+ "JAXP0801001: the compiler encountered an XPath expression containing "
+ + "''{0}'' groups that exceeds the ''{1}'' limit set by ''{2}''."},
+
+ { ER_XPATH_OPERATOR_LIMIT,
+ "JAXP0801002: the compiler encountered an XPath expression containing "
+ + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."},
+
//END: Definitions of error keys used in exception messages of JAXP 1.3 XPath API implementation
// Warnings...
diff --git a/jaxp/src/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java b/jaxp/src/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java
index e4b36ece592..638063283de 100644
--- a/jaxp/src/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java
+++ b/jaxp/src/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2021, 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
@@ -28,6 +28,7 @@
import javax.xml.stream.events.EntityDeclaration;
import javax.xml.stream.events.XMLEvent;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import jdk.xml.internal.JdkXmlUtils;
/**
*
@@ -129,18 +130,12 @@ protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
//escape quotes, lt and amps
writer.write(" \"");
charEncode(writer, fReplacementText);
+ writer.write("\"");
} else {
//external entity
- String pubId = getPublicId();
- if (pubId != null) {
- writer.write(" PUBLIC \"");
- writer.write(pubId);
- } else {
- writer.write(" SYSTEM \"");
- writer.write(getSystemId());
- }
+ writer.write(JdkXmlUtils.getDTDExternalDecl(getPublicId(), getSystemId()));
}
- writer.write("\"");
+
if (fNotationName != null) {
writer.write(" NDATA ");
writer.write(fNotationName);
diff --git a/jaxp/src/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java b/jaxp/src/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java
index af3d949b1a5..be0caee0cab 100644
--- a/jaxp/src/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java
+++ b/jaxp/src/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2021, 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
@@ -28,6 +28,7 @@
import javax.xml.stream.events.NotationDeclaration;
import javax.xml.stream.events.XMLEvent;
import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl;
+import jdk.xml.internal.JdkXmlUtils;
/**
* Implementation of NotationDeclaration event.
@@ -88,16 +89,7 @@ protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
{
writer.write("');
}
}
diff --git a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
index 012fa7711a9..767d2e176e9 100644
--- a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
+++ b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, 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
@@ -25,7 +25,6 @@
package jdk.xml.internal;
-import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
@@ -250,19 +249,40 @@ public static SAXTransformerFactory getSAXTransformFactory(boolean overrideDefau
}
/**
- * Returns the character to be used to quote the input content. Between
- * single and double quotes, this method returns the one that is not found
- * in the input. Returns double quote by default.
+ * Returns the external declaration for a DTD construct.
*
- * @param s the input string
- * @return returns the quote not found in the input
+ * @param publicId the public identifier
+ * @param systemId the system identifier
+ * @return a DTD external declaration
*/
- public static char getQuoteChar(String s) {
- if (s != null && s.indexOf('"') > -1) {
- return '\'';
- } else {
- return '"';
+ public static String getDTDExternalDecl(String publicId, String systemId) {
+ StringBuilder sb = new StringBuilder();
+ if (null != publicId) {
+ sb.append(" PUBLIC ");
+ sb.append(quoteString(publicId));
+ }
+
+ if (null != systemId) {
+ if (null == publicId) {
+ sb.append(" SYSTEM ");
+ } else {
+ sb.append(" ");
+ }
+
+ sb.append(quoteString(systemId));
}
+ return sb.toString();
+ }
+
+ /**
+ * Returns the input string quoted with double quotes or single ones if
+ * there is a double quote in the string.
+ * @param s the input string, can not be null
+ * @return the quoted string
+ */
+ private static String quoteString(String s) {
+ char c = (s.indexOf('"') > -1) ? '\'' : '"';
+ return c + s + c;
}
private static XMLReader getXMLReaderWSAXFactory(boolean overrideDefaultParser) {
diff --git a/jaxp/src/jdk/xml/internal/XMLLimitAnalyzer.java b/jaxp/src/jdk/xml/internal/XMLLimitAnalyzer.java
new file mode 100644
index 00000000000..18ce1b665fd
--- /dev/null
+++ b/jaxp/src/jdk/xml/internal/XMLLimitAnalyzer.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2013, 2022, 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
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.xml.internal;
+
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.xml.internal.XMLSecurityManager.Limit;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+
+
+/**
+ * A helper for analyzing entity expansion limits
+ *
+ */
+public final class XMLLimitAnalyzer {
+
+ /**
+ * Map old property names with the new ones
+ */
+ public static enum NameMap {
+ ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, XalanConstants.ENTITY_EXPANSION_LIMIT),
+ MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, XalanConstants.MAX_OCCUR_LIMIT),
+ ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, XalanConstants.ELEMENT_ATTRIBUTE_LIMIT);
+
+ final String newName;
+ final String oldName;
+
+ NameMap(String newName, String oldName) {
+ this.newName = newName;
+ this.oldName = oldName;
+ }
+
+ String getOldName(String newName) {
+ if (newName.equals(this.newName)) {
+ return oldName;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Max value accumulated for each property
+ */
+ private final int[] values;
+ /**
+ * Names of the entities corresponding to their max values
+ */
+ private final String[] names;
+ /**
+ * Total value of accumulated entities
+ */
+ private final int[] totalValue;
+
+ /**
+ * Maintain values of the top 10 elements in the process of parsing
+ */
+ private final Map[] caches;
+
+ private String entityStart, entityEnd;
+ /**
+ * Default constructor. Establishes default values for known security
+ * vulnerabilities.
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public XMLLimitAnalyzer() {
+ values = new int[Limit.values().length];
+ totalValue = new int[Limit.values().length];
+ names = new String[Limit.values().length];
+ caches = new Map[Limit.values().length];
+ }
+
+ /**
+ * Add the value to the current max count for the specified property
+ * To find the max value of all entities, set no limit
+ *
+ * @param limit the type of the property
+ * @param entityName the name of the entity
+ * @param value the value of the entity
+ */
+ public void addValue(Limit limit, String entityName, int value) {
+ addValue(limit.ordinal(), entityName, value);
+ }
+
+ /**
+ * Add the value to the current count by the index of the property
+ * @param index the index of the property
+ * @param entityName the name of the entity
+ * @param value the value of the entity
+ */
+ public void addValue(int index, String entityName, int value) {
+ if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
+ index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() ||
+ index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() ||
+ index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() ||
+ index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal()
+ ) {
+ totalValue[index] += value;
+ return;
+ }
+ if (index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() ||
+ index == Limit.MAX_NAME_LIMIT.ordinal()) {
+ values[index] = value;
+ totalValue[index] = value;
+ return;
+ }
+
+ Map cache;
+ if (caches[index] == null) {
+ cache = new HashMap<>(10);
+ caches[index] = cache;
+ } else {
+ cache = caches[index];
+ }
+
+ int accumulatedValue = value;
+ if (cache.containsKey(entityName)) {
+ accumulatedValue += cache.get(entityName);
+ cache.put(entityName, accumulatedValue);
+ } else {
+ cache.put(entityName, value);
+ }
+
+ if (accumulatedValue > values[index]) {
+ values[index] = accumulatedValue;
+ names[index] = entityName;
+ }
+
+
+ if (index == Limit.GENERAL_ENTITY_SIZE_LIMIT.ordinal() ||
+ index == Limit.PARAMETER_ENTITY_SIZE_LIMIT.ordinal()) {
+ totalValue[Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()] += value;
+ }
+ }
+
+ /**
+ * Return the value of the current max count for the specified property
+ *
+ * @param limit the property
+ * @return the value of the property
+ */
+ public int getValue(Limit limit) {
+ return getValue(limit.ordinal());
+ }
+
+ public int getValue(int index) {
+ if (index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal()) {
+ return totalValue[index];
+ }
+ return values[index];
+ }
+ /**
+ * Return the total value accumulated so far
+ *
+ * @param limit the property
+ * @return the accumulated value of the property
+ */
+ public int getTotalValue(Limit limit) {
+ return totalValue[limit.ordinal()];
+ }
+
+ public int getTotalValue(int index) {
+ return totalValue[index];
+ }
+ /**
+ * Return the current max value (count or length) by the index of a property
+ * @param index the index of a property
+ * @return count of a property
+ */
+ public int getValueByIndex(int index) {
+ return values[index];
+ }
+
+ public void startEntity(String name) {
+ entityStart = name;
+ }
+
+ public boolean isTracking(String name) {
+ if (entityStart == null) {
+ return false;
+ }
+ return entityStart.equals(name);
+ }
+ /**
+ * Stop tracking the entity
+ * @param limit the limit property
+ * @param name the name of an entity
+ */
+ public void endEntity(Limit limit, String name) {
+ entityStart = "";
+ Map cache = caches[limit.ordinal()];
+ if (cache != null) {
+ cache.remove(name);
+ }
+ }
+
+ /**
+ * Resets the current value of the specified limit.
+ * @param limit The limit to be reset.
+ */
+ public void reset(Limit limit) {
+ if (limit.ordinal() == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) {
+ totalValue[limit.ordinal()] = 0;
+ } else if (limit.ordinal() == Limit.GENERAL_ENTITY_SIZE_LIMIT.ordinal()) {
+ names[limit.ordinal()] = null;
+ values[limit.ordinal()] = 0;
+ caches[limit.ordinal()] = null;
+ totalValue[limit.ordinal()] = 0;
+ }
+ }
+
+ public void debugPrint(XMLSecurityManager securityManager) {
+ Formatter formatter = new Formatter();
+ System.out.println(formatter.format("%30s %15s %15s %15s %30s",
+ "Property","Limit","Total size","Size","Entity Name"));
+
+ for (Limit limit : Limit.values()) {
+ formatter = new Formatter();
+ System.out.println(formatter.format("%30s %15d %15d %15d %30s",
+ limit.name(),
+ securityManager.getLimit(limit),
+ totalValue[limit.ordinal()],
+ values[limit.ordinal()],
+ names[limit.ordinal()]));
+ }
+ }
+}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java b/jaxp/src/jdk/xml/internal/XMLSecurityManager.java
similarity index 67%
rename from jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java
rename to jaxp/src/jdk/xml/internal/XMLSecurityManager.java
index 96bb46c8c91..2dd165757fd 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java
+++ b/jaxp/src/jdk/xml/internal/XMLSecurityManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, 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
@@ -23,19 +23,17 @@
* questions.
*/
-package com.sun.org.apache.xalan.internal.utils;
+package jdk.xml.internal;
-import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xerces.internal.util.SecurityManager;
import java.util.concurrent.CopyOnWriteArrayList;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import org.xml.sax.SAXException;
/**
- * This class is not the same as that in Xerces. It is used to manage the
- * state of corresponding Xerces properties and pass the values over to
- * the Xerces Security Manager.
*
- * @author Joe Wang Oracle Corp.
+ * This class manages standard and implementation-specific limitations.
*
*/
public final class XMLSecurityManager {
@@ -66,38 +64,47 @@ String literal() {
* Limits managed by the security manager
*/
public static enum Limit {
-
ENTITY_EXPANSION_LIMIT("EntityExpansionLimit", XalanConstants.JDK_ENTITY_EXPANSION_LIMIT,
- XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000),
+ XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000, Processor.PARSER),
MAX_OCCUR_NODE_LIMIT("MaxOccurLimit", XalanConstants.JDK_MAX_OCCUR_LIMIT,
- XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000),
+ XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000, Processor.PARSER),
ELEMENT_ATTRIBUTE_LIMIT("ElementAttributeLimit", XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT,
- XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000),
+ XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000, Processor.PARSER),
TOTAL_ENTITY_SIZE_LIMIT("TotalEntitySizeLimit", XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT,
- XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000),
+ XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000, Processor.PARSER),
GENERAL_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_GENERAL_ENTITY_SIZE_LIMIT,
- XalanConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, 0, 0),
+ XalanConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, 0, 0, Processor.PARSER),
PARAMETER_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT,
- XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000),
+ XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000, Processor.PARSER),
MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", XalanConstants.JDK_MAX_ELEMENT_DEPTH,
- XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0),
+ XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0, Processor.PARSER),
MAX_NAME_LIMIT("MaxXMLNameLimit", XalanConstants.JDK_XML_NAME_LIMIT,
- XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000),
+ XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000, Processor.PARSER),
ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", XalanConstants.JDK_ENTITY_REPLACEMENT_LIMIT,
- XalanConstants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000);
+ XalanConstants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000, Processor.PARSER),
+ XPATH_GROUP_LIMIT("XPathGroupLimit", XalanConstants.XPATH_GROUP_LIMIT,
+ XalanConstants.XPATH_GROUP_LIMIT, 10, 10, Processor.XPATH),
+ XPATH_OP_LIMIT("XPathExprOpLimit", XalanConstants.XPATH_OP_LIMIT,
+ XalanConstants.XPATH_OP_LIMIT, 100, 100, Processor.XPATH),
+ XPATH_TOTALOP_LIMIT("XPathTotalOpLimit", XalanConstants.XPATH_TOTALOP_LIMIT,
+ XalanConstants.XPATH_TOTALOP_LIMIT, 10000, 10000, Processor.XPATH)
+ ;
final String key;
final String apiProperty;
final String systemProperty;
final int defaultValue;
final int secureValue;
+ final Processor processor;
- Limit(String key, String apiProperty, String systemProperty, int value, int secureValue) {
+ Limit(String key, String apiProperty, String systemProperty, int value,
+ int secureValue, Processor processor) {
this.key = key;
this.apiProperty = apiProperty;
this.systemProperty = systemProperty;
this.defaultValue = value;
this.secureValue = secureValue;
+ this.processor = processor;
}
public boolean equalsAPIPropertyName(String propertyName) {
@@ -124,6 +131,10 @@ public int defaultValue() {
return defaultValue;
}
+ public boolean isSupported(Processor p) {
+ return processor == p;
+ }
+
int secureValue() {
return secureValue;
}
@@ -134,12 +145,9 @@ int secureValue() {
*/
public static enum NameMap {
- ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT,
- XalanConstants.ENTITY_EXPANSION_LIMIT),
- MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT,
- XalanConstants.MAX_OCCUR_LIMIT),
- ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT,
- XalanConstants.ELEMENT_ATTRIBUTE_LIMIT);
+ ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, XalanConstants.ENTITY_EXPANSION_LIMIT),
+ MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, XalanConstants.MAX_OCCUR_LIMIT),
+ ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, XalanConstants.ELEMENT_ATTRIBUTE_LIMIT);
final String newName;
final String oldName;
@@ -155,14 +163,32 @@ String getOldName(String newName) {
return null;
}
}
+
+ /**
+ * Supported processors
+ */
+ public static enum Processor {
+ PARSER,
+ XPATH,
+ }
+
+ private static final int NO_LIMIT = 0;
+
/**
* Values of the properties
*/
private final int[] values;
+
/**
* States of the settings for each property
*/
private State[] states;
+
+ /**
+ * Flag indicating if secure processing is set
+ */
+ boolean secureProcessing;
+
/**
* States that determine if properties are set explicitly
*/
@@ -192,9 +218,10 @@ public XMLSecurityManager(boolean secureProcessing) {
values = new int[Limit.values().length];
states = new State[Limit.values().length];
isSet = new boolean[Limit.values().length];
+ this.secureProcessing = secureProcessing;
for (Limit limit : Limit.values()) {
if (secureProcessing) {
- values[limit.ordinal()] = limit.secureValue();
+ values[limit.ordinal()] = limit.secureValue;
states[limit.ordinal()] = State.FSP;
} else {
values[limit.ordinal()] = limit.defaultValue();
@@ -209,6 +236,7 @@ public XMLSecurityManager(boolean secureProcessing) {
* Setting FEATURE_SECURE_PROCESSING explicitly
*/
public void setSecureProcessing(boolean secure) {
+ secureProcessing = secure;
for (Limit limit : Limit.values()) {
if (secure) {
setLimit(limit.ordinal(), State.FSP, limit.secureValue());
@@ -218,6 +246,14 @@ public void setSecureProcessing(boolean secure) {
}
}
+ /**
+ * Return the state of secure processing
+ * @return the state of secure processing
+ */
+ public boolean isSecureProcessing() {
+ return secureProcessing;
+ }
+
/**
* Set limit by property name and state
* @param propertyName property name
@@ -255,7 +291,6 @@ public void setLimit(Limit limit, State state, int value) {
*/
public void setLimit(int index, State state, Object value) {
if (index == indexEntityCountInfo) {
- //if it's explicitly set, it's treated as yes no matter the value
printEntityCountInfo = (String)value;
} else {
int temp = 0;
@@ -289,9 +324,8 @@ public void setLimit(int index, State state, int value) {
}
}
-
/**
- * Return the value of the specified property.
+ * Return the value of the specified property
*
* @param propertyName the property name
* @return the value of the property as a string. If a property is managed
@@ -305,17 +339,6 @@ public String getLimitAsString(String propertyName) {
return null;
}
-
- /**
- * Return the value of a property by its ordinal
- *
- * @param limit the property
- * @return value of a property
- */
- public String getLimitValueAsString(Limit limit) {
- return Integer.toString(values[limit.ordinal()]);
- }
-
/**
* Return the value of the specified property
*
@@ -329,14 +352,15 @@ public int getLimit(Limit limit) {
/**
* Return the value of a property by its ordinal
*
- * @param index the index of a property
+ * @param limit the property
* @return value of a property
*/
- public int getLimitByIndex(int index) {
- return values[index];
+ public String getLimitValueAsString(Limit limit) {
+ return Integer.toString(values[limit.ordinal()]);
}
+
/**
- * Return the value of a property by its index
+ * Return the value of a property by its ordinal
*
* @param index the index of a property
* @return limit of a property as a string
@@ -348,6 +372,7 @@ public String getLimitValueByIndex(int index) {
return Integer.toString(values[index]);
}
+
/**
* Return the state of the limit property
*
@@ -388,6 +413,85 @@ public int getIndex(String propertyName) {
return -1;
}
+ /**
+ * Check if there's no limit defined by the Security Manager
+ * @param limit
+ * @return
+ */
+ public boolean isNoLimit(int limit) {
+ return limit == NO_LIMIT;
+ }
+ /**
+ * Check if the size (length or count) of the specified limit property is
+ * over the limit
+ *
+ * @param limit the type of the limit property
+ * @param entityName the name of the entity
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(Limit limit, String entityName, int size,
+ XMLLimitAnalyzer limitAnalyzer) {
+ return isOverLimit(limit.ordinal(), entityName, size, limitAnalyzer);
+ }
+
+ /**
+ * Check if the value (length or count) of the specified limit property is
+ * over the limit
+ *
+ * @param index the index of the limit property
+ * @param entityName the name of the entity
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(int index, String entityName, int size,
+ XMLLimitAnalyzer limitAnalyzer) {
+ if (values[index] == NO_LIMIT) {
+ return false;
+ }
+ if (size > values[index]) {
+ limitAnalyzer.addValue(index, entityName, size);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check against cumulated value
+ *
+ * @param limit the type of the limit property
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(Limit limit, XMLLimitAnalyzer limitAnalyzer) {
+ return isOverLimit(limit.ordinal(), limitAnalyzer);
+ }
+
+ public boolean isOverLimit(int index, XMLLimitAnalyzer limitAnalyzer) {
+ if (values[index] == NO_LIMIT) {
+ return false;
+ }
+
+ if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() ||
+ index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
+ index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() ||
+ index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal() ||
+ index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() ||
+ index == Limit.MAX_NAME_LIMIT.ordinal()
+ ) {
+ return (limitAnalyzer.getTotalValue(index) > values[index]);
+ } else {
+ return (limitAnalyzer.getValue(index) > values[index]);
+ }
+ }
+
+ public void debugPrint(XMLLimitAnalyzer limitAnalyzer) {
+ if (printEntityCountInfo.equals(XalanConstants.JDK_YES)) {
+ limitAnalyzer.debugPrint(this);
+ }
+ }
+
+
/**
* Indicate if a property is set explicitly
* @param index
@@ -400,6 +504,7 @@ public boolean isSet(int index) {
public boolean printEntityCountInfo() {
return printEntityCountInfo.equals(XalanConstants.JDK_YES);
}
+
/**
* Read from system properties, or those in jaxp.properties
*/
@@ -463,4 +568,37 @@ private boolean getSystemProperty(Limit limit, String sysPropertyName) {
}
return false;
}
+
+
+ /**
+ * Convert a value set through setProperty to XMLSecurityManager.
+ * If the value is an instance of XMLSecurityManager, use it to override the default;
+ * If the value is an old SecurityManager, convert to the new XMLSecurityManager.
+ *
+ * @param value user specified security manager
+ * @param securityManager an instance of XMLSecurityManager
+ * @return an instance of the new security manager XMLSecurityManager
+ */
+ public static XMLSecurityManager convert(Object value, XMLSecurityManager securityManager) {
+ if (value == null) {
+ if (securityManager == null) {
+ securityManager = new XMLSecurityManager(true);
+ }
+ return securityManager;
+ }
+ if (value instanceof XMLSecurityManager) {
+ return (XMLSecurityManager)value;
+ } else {
+ if (securityManager == null) {
+ securityManager = new XMLSecurityManager(true);
+ }
+ if (value instanceof SecurityManager) {
+ SecurityManager origSM = (SecurityManager)value;
+ securityManager.setLimit(Limit.MAX_OCCUR_NODE_LIMIT, State.APIPROPERTY, origSM.getMaxOccurNodeLimit());
+ securityManager.setLimit(Limit.ENTITY_EXPANSION_LIMIT, State.APIPROPERTY, origSM.getEntityExpansionLimit());
+ securityManager.setLimit(Limit.ELEMENT_ATTRIBUTE_LIMIT, State.APIPROPERTY, origSM.getElementAttrLimit());
+ }
+ return securityManager;
+ }
+ }
}
diff --git a/jdk/src/macosx/classes/apple/security/KeychainStore.java b/jdk/src/macosx/classes/apple/security/KeychainStore.java
index 034d6d43308..fcf2e8a771c 100644
--- a/jdk/src/macosx/classes/apple/security/KeychainStore.java
+++ b/jdk/src/macosx/classes/apple/security/KeychainStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022, 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
@@ -68,6 +68,25 @@ class TrustedCertEntry {
Certificate cert;
long certRef; // SecCertificateRef for this key
+
+ // Each KeyStore.TrustedCertificateEntry have 2 attributes:
+ // 1. "trustSettings" -> trustSettings.toString()
+ // 2. "2.16.840.1.113894.746875.1.1" -> trustedKeyUsageValue
+ // The 1st one is mainly for debugging use. The 2nd one is similar
+ // to the attribute with the same key in a PKCS12KeyStore.
+
+ // The SecTrustSettingsCopyTrustSettings() output for this certificate
+ // inside the KeyChain in its original array of CFDictionaryRef objects
+ // structure with values dumped as strings. For each trust, an extra
+ // entry "SecPolicyOid" is added whose value is the OID for this trust.
+ // The extra entries are used to construct trustedKeyUsageValue.
+ List