Skip to content

Commit d833ec0

Browse files
committed
[bugfix] Make sure the format of the value of a decimal-format property is correct
1 parent 38cedd0 commit d833ec0

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,12 @@ throws PermissionDeniedException, EXistException, XPathException
567567
current = (XQueryAST) pval.getNextSibling();
568568
}
569569

570-
final DecimalFormat df = DecimalFormat.fromProperties(dfProperties);
570+
final DecimalFormat df;
571+
try {
572+
df = DecimalFormat.fromProperties(dfProperties);
573+
} catch (final IllegalArgumentException ex) {
574+
throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0097.getErrorCode(), ex.getMessage() + " within the picture string of the decimal format: " + dfName.getText() + ".");
575+
}
571576
if (!df.checkDistinctCharacters()) {
572577
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.");
573578
}

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,16 @@ public boolean checkDistinctCharacters() {
136136
return true;
137137
}
138138

139-
public static DecimalFormat fromProperties(final Map<String, String> properties) {
139+
/**
140+
* Constructs a Decimal Format from a map of decimal format properties.
141+
*
142+
* @param properties the properties for the decimal format.
143+
*
144+
* @return the Decimal Format.
145+
*
146+
* @throws IllegalArgumentException if any of the properties are invalid.
147+
*/
148+
public static DecimalFormat fromProperties(final Map<String, String> properties) throws IllegalArgumentException {
140149
int decimalSeparator = UNNAMED.decimalSeparator;
141150
int exponentSeparator = UNNAMED.exponentSeparator;
142151
int groupingSeparator = UNNAMED.groupingSeparator;
@@ -153,36 +162,73 @@ public static DecimalFormat fromProperties(final Map<String, String> properties)
153162
final String value = property.getValue();
154163
switch (property.getKey()) {
155164
case "decimal-separator":
165+
if (value.length() != 1) {
166+
throw new IllegalArgumentException("decimal-separator must be a single character");
167+
}
156168
decimalSeparator = value.charAt(0);
157169
break;
170+
158171
case "exponent-separator":
172+
if (value.length() != 1) {
173+
throw new IllegalArgumentException("exponent-separator must be a single character");
174+
}
159175
exponentSeparator = value.charAt(0);
160176
break;
177+
161178
case "grouping-separator":
179+
if (value.length() != 1) {
180+
throw new IllegalArgumentException("groupung-separator must be a single character");
181+
}
162182
groupingSeparator = value.charAt(0);
163183
break;
184+
164185
case "percent":
186+
if (value.length() != 1) {
187+
throw new IllegalArgumentException("percent must be a single character");
188+
}
165189
percent = value.charAt(0);
166190
break;
191+
167192
case "per-mille":
193+
if (value.length() != 1) {
194+
throw new IllegalArgumentException("per-mille must be a single character");
195+
}
168196
perMille = value.charAt(0);
169197
break;
198+
170199
case "zero-digit":
200+
if (value.length() != 1) {
201+
throw new IllegalArgumentException("zero-digit must be a single character");
202+
}
171203
zeroDigit = value.charAt(0);
172204
break;
205+
173206
case "digit":
207+
if (value.length() != 1) {
208+
throw new IllegalArgumentException("digit must be a single character");
209+
}
174210
digit = value.charAt(0);
175211
break;
212+
176213
case "pattern-separator":
214+
if (value.length() != 1) {
215+
throw new IllegalArgumentException("pattern-separator must be a single character");
216+
}
177217
patternSeparator = value.charAt(0);
178218
break;
219+
179220
case "infinity":
180221
infinity = value;
181222
break;
223+
182224
case "NaN":
183225
NaN = value;
184226
break;
227+
185228
case "minus-sign":
229+
if (value.length() != 1) {
230+
throw new IllegalArgumentException("minus-sign must be a single character");
231+
}
186232
minusSign = value.charAt(0);
187233
break;
188234
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ public enum W3CErrorCode implements IErrorCode {
220220
XQDY0092 ("An implementation MAY raise a dynamic error if a constructed attribute named xml:space has a value other than preserve or default."),
221221
XQST0093 ("It is a static error to import a module M1 if there exists a sequence of modules M1 ... Mi ... M1 such that each module directly depends on the next module in the sequence (informally, if M1 depends on itself through some chain of module dependencies.)"),
222222
XQST0094 ("The name of each grouping variable must be equal (by the eq operator on expanded QNames) to the name of a variable in the input tuple stream."),
223+
XQST0097 ("It is a static error for a decimal-format to specify a value that is not valid for a given property, as described in statically known decimal formats"),
223224
XQST0098 ("It is a static error if, for any named or unnamed decimal format, the properties representing characters used in a picture string do not each have distinct values. The following properties represent characters used in a picture string: decimal-separator, exponent-separator, grouping-separator, percent, per-mille, the family of ten decimal digits starting with zero-digit, digit, and pattern-separator."),
224225
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."),
225226
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."),

0 commit comments

Comments
 (0)