Skip to content

Commit d42d2b1

Browse files
committed
[bugfix] Query prolog must not allow two decimal format declarations with the same name
1 parent 67b0fa3 commit d42d2b1

2 files changed

Lines changed: 22 additions & 11 deletions

File tree

exist-core/src/main/antlr/org/exist/xquery/parser/XQueryTree.g

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ options {
106106
protected Set<String> importedModules = new HashSet<>();
107107
protected Set<String> importedModuleFunctions = null;
108108
protected Set<QName> importedModuleVariables = null;
109+
private boolean hasDefaultDecimalFormat = false;
109110

110111
public XQueryTreeParser(XQueryContext context) {
111112
this(context, null);
@@ -504,6 +505,26 @@ throws PermissionDeniedException, EXistException, XPathException
504505
// first sibling is either DEFAULT_DECIMAL_FORMAT (default) or EQNAME (named)
505506
final XQueryAST dfName = (XQueryAST) root.getNextSibling();
506507

508+
final QName qnDfName;
509+
if ("default".equals(dfName.getText())) {
510+
qnDfName = XQueryContext.UNNAMED_DECIMAL_FORMAT;
511+
if (hasDefaultDecimalFormat) {
512+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0111.getErrorCode(), "Query prolog cannot contain two default decimal format declarations.");
513+
} else {
514+
hasDefaultDecimalFormat = true;
515+
}
516+
} else {
517+
try {
518+
qnDfName = QName.parse(staticContext, dfName.getText(), null);
519+
} catch (final IllegalQNameException iqe) {
520+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.XPST0081, "No namespace defined for prefix " + dfName.getText());
521+
}
522+
523+
if (staticContext.getStaticDecimalFormat(qnDfName) != null) {
524+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0111.getErrorCode(), "Query prolog cannot contain two decimal format declarations with the same name: " + dfName.getText());
525+
}
526+
}
527+
507528
// position current at the first property name for the decimal format
508529
XQueryAST current = (XQueryAST) dfName.getNextSibling();
509530
if ("default".equals(dfName.getText())) {
@@ -530,17 +551,6 @@ throws PermissionDeniedException, EXistException, XPathException
530551
current = (XQueryAST) pval.getNextSibling();
531552
}
532553

533-
final QName qnDfName;
534-
if ("default".equals(dfName.getText())) {
535-
qnDfName = XQueryContext.UNNAMED_DECIMAL_FORMAT;
536-
} else {
537-
try {
538-
qnDfName = QName.parse(staticContext, dfName.getText(), null);
539-
} catch (final IllegalQNameException iqe) {
540-
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.XPST0081, "No namespace defined for prefix " + dfName.getText());
541-
}
542-
}
543-
544554
final DecimalFormat df = DecimalFormat.fromProperties(dfProperties);
545555
if (!df.checkDistinctCharacters()) {
546556
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0098.getErrorCode(), "Characters within the picture string of the decimal format: " + dfName.getText() + " are not distinct.");

exist-core/src/main/java/org/exist/xquery/ErrorCodes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ public enum W3CErrorCode implements IErrorCode {
224224
XQDY0101 ("An error is raised if a computed namespace constructor attempts to do any of the following: Bind the prefix xml to some namespace URI other than http://www.w3.org/XML/1998/namespace. Bind a prefix other than xml to the namespace URI http://www.w3.org/XML/1998/namespace. Bind the prefix xmlns to any namespace URI. Bind a prefix to the namespace URI http://www.w3.org/2000/xmlns/. Bind any prefix (including the empty prefix) to a zero-length namespace URI."),
225225
XQDY0102 ("If the name of an element in an element constructor is in no namespace, creating a default namespace for that element using a computed namespace constructor is an error."),
226226
XQST0103 ("All variables in a window clause must have distinct names."),
227+
XQST0111 ("It is a static error for a query prolog to contain two decimal formats with the same name, or to contain two default decimal formats."),
227228
XQDY0137 ("No two keys in a map may have the same key value"),
228229
XQDY0138 ("Position n does not exist in this array"),
229230
XUDY0023 ("It is a dynamic error if an insert, replace, or rename expression affects an element node by introducing a new namespace binding that conflicts with one of its existing namespace bindings."),

0 commit comments

Comments
 (0)