Skip to content

Commit

Permalink
8289486: Improve XSLT XPath operators count efficiency
Browse files Browse the repository at this point in the history
Backport-of: 3212dc9c6f3538e1d0bd1809efd5f33ad8b47701
  • Loading branch information
GoeLin committed Jul 21, 2022
1 parent d3a4879 commit 77d9210
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 29 deletions.
Expand Up @@ -137,7 +137,7 @@
* @see com.sun.java_cup.internal.runtime.virtual_parse_stack
* @author Frank Flannery
*
* @LastModified: June 2022
* @LastModified: July 2022
*/

public abstract class lr_parser {
Expand All @@ -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) ----------------------------------------*/
Expand Down Expand Up @@ -376,11 +380,13 @@ public Symbol scan() throws Exception {
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;
}
Expand All @@ -390,6 +396,16 @@ public Symbol scan() throws Exception {
}
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;
}

Expand Down Expand Up @@ -591,12 +607,14 @@ public Symbol parse() throws java.lang.Exception
/* 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();
Expand Down Expand Up @@ -671,12 +689,16 @@ else if (act == 0)
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.
*
Expand Down
Expand Up @@ -43,12 +43,9 @@
* 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.
Expand Down Expand Up @@ -1118,29 +1115,37 @@ public Symbol parse(String expression, int lineNumber) throws Exception {
_expression = expression;
_lineNumber = lineNumber;
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);
/*
* 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);
}
}
return s;
} catch (IllegalCharException e) {
Expand Down

1 comment on commit 77d9210

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.