Skip to content

Commit 4d1d399

Browse files
committed
[bugfix] Query prolog must not allow two decimal format declarations with the same name
1 parent b4699fe commit 4d1d399

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

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);
@@ -518,6 +519,26 @@ throws PermissionDeniedException, EXistException, XPathException
518519
// first sibling is either DEFAULT_DECIMAL_FORMAT (default) or EQNAME (named)
519520
final XQueryAST dfName = (XQueryAST) root.getNextSibling();
520521

522+
final QName qnDfName;
523+
if ("default".equals(dfName.getText())) {
524+
qnDfName = XQueryContext.UNNAMED_DECIMAL_FORMAT;
525+
if (hasDefaultDecimalFormat) {
526+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0111.getErrorCode(), "Query prolog cannot contain two default decimal format declarations.");
527+
} else {
528+
hasDefaultDecimalFormat = true;
529+
}
530+
} else {
531+
try {
532+
qnDfName = QName.parse(staticContext, dfName.getText(), null);
533+
} catch (final IllegalQNameException iqe) {
534+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.XPST0081, "No namespace defined for prefix " + dfName.getText());
535+
}
536+
537+
if (staticContext.getStaticDecimalFormat(qnDfName) != null) {
538+
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());
539+
}
540+
}
541+
521542
// position current at the first property name for the decimal format
522543
XQueryAST current = (XQueryAST) dfName.getNextSibling();
523544
if ("default".equals(dfName.getText())) {
@@ -544,17 +565,6 @@ throws PermissionDeniedException, EXistException, XPathException
544565
current = (XQueryAST) pval.getNextSibling();
545566
}
546567

547-
final QName qnDfName;
548-
if ("default".equals(dfName.getText())) {
549-
qnDfName = XQueryContext.UNNAMED_DECIMAL_FORMAT;
550-
} else {
551-
try {
552-
qnDfName = QName.parse(staticContext, dfName.getText(), null);
553-
} catch (final IllegalQNameException iqe) {
554-
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.XPST0081, "No namespace defined for prefix " + dfName.getText());
555-
}
556-
}
557-
558568
final DecimalFormat df = DecimalFormat.fromProperties(dfProperties);
559569
if (!df.checkDistinctCharacters()) {
560570
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)