8289486: Improve XSLT XPath operators count efficiency
Reviewed-by: naoto, lancea
This commit is contained in:
parent
a8eb728680
commit
3212dc9c6f
src/java.xml/share/classes/com/sun
@ -137,7 +137,7 @@ import java.util.Stack;
|
||||
* @see com.sun.java_cup.internal.runtime.virtual_parse_stack
|
||||
* @author Frank Flannery
|
||||
*
|
||||
* @LastModified: June 2022
|
||||
* @LastModified: July 2022
|
||||
*/
|
||||
|
||||
public abstract class lr_parser {
|
||||
@ -150,6 +150,10 @@ public abstract class lr_parser {
|
||||
private int opCount = 0;
|
||||
private int totalOpCount = 0;
|
||||
private int lastSym;
|
||||
private boolean overLimit = false;
|
||||
public int grpLimit = 0;
|
||||
public int opLimit = 0;
|
||||
public int totalOpLimit = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*--- Constructor(s) ----------------------------------------*/
|
||||
@ -376,11 +380,13 @@ public abstract class lr_parser {
|
||||
grpCount++;
|
||||
}
|
||||
opCount++; // function
|
||||
totalOpCount++;
|
||||
isLiteral = false;
|
||||
} else if (contains(sym.OPERATORS, s.sym)) {
|
||||
// axis nodetest is counted as one step, so not counted if last=DCOLON
|
||||
if (lastSym != sym.DCOLON) {
|
||||
opCount++;
|
||||
totalOpCount++;
|
||||
}
|
||||
isLiteral = false;
|
||||
}
|
||||
@ -390,6 +396,16 @@ public abstract class lr_parser {
|
||||
}
|
||||
lastSym = s.sym;
|
||||
|
||||
/*
|
||||
* Sets the overLimit status as soon as the count of operators is over the
|
||||
* limit, which in turn triggers the XPathParser to report an error.
|
||||
*/
|
||||
if (grpLimit > 0 && grpCount > grpLimit
|
||||
|| opLimit > 0 && opCount > opLimit
|
||||
|| totalOpLimit > 0 && totalOpCount > totalOpLimit) {
|
||||
overLimit = true;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -591,12 +607,14 @@ public abstract class lr_parser {
|
||||
/* do user initialization */
|
||||
user_init();
|
||||
isLiteral = false;
|
||||
overLimit = false;
|
||||
grpCount = 0;
|
||||
opCount = 0;
|
||||
lastSym = -1;
|
||||
|
||||
/* get the first token */
|
||||
cur_token = scan();
|
||||
if (overLimit) return null;
|
||||
|
||||
/* push dummy Symbol with start state to get us underway */
|
||||
stack.removeAllElements();
|
||||
@ -671,12 +689,16 @@ public abstract class lr_parser {
|
||||
lhs_sym = stack.peek();
|
||||
}
|
||||
}
|
||||
if (overLimit) return null;
|
||||
}
|
||||
|
||||
totalOpCount += opCount;
|
||||
return lhs_sym;
|
||||
}
|
||||
|
||||
public boolean isOverLimit() {
|
||||
return overLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of operators in XPath expressions.
|
||||
*
|
||||
|
@ -43,12 +43,9 @@ import jdk.xml.internal.XMLSecurityManager.Limit;
|
||||
* CUP v0.11b generated parser.
|
||||
* This class was generated by CUP v0.11b on Nov 12, 2019.
|
||||
*
|
||||
* @LastModified: Jan 2022
|
||||
* @LastModified: July 2022
|
||||
*/
|
||||
public class XPathParser extends lr_parser {
|
||||
private int grpLimit = 0;
|
||||
private int opLimit = 0;
|
||||
private int totalOpLimit = 0;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@ -1118,29 +1115,37 @@ public class XPathParser extends lr_parser {
|
||||
_expression = expression;
|
||||
_lineNumber = lineNumber;
|
||||
Symbol s = super.parse();
|
||||
int grpCount = getCount(ID_GROUP);
|
||||
int opCount = getCount(ID_OPERATOR);
|
||||
int totalOpCount = getCount(ID_TOTAL_OPERATOR);
|
||||
/*
|
||||
* While the Java CUP parser is used for parsing symbols, the error
|
||||
* report mechanism has so far been kept within the Xalan implementation.
|
||||
* An error, i.e. the count of operators is over the limit, is
|
||||
* therefore handled here.
|
||||
*/
|
||||
if (isOverLimit()) {
|
||||
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);
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user