Skip to content

Commit 0408cc2

Browse files
committed
[bugfix] Do not identify non-exponent characters as exponent character in the exponent part of the picture string given to fn:format-number
1 parent 15bd753 commit 0408cc2

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

exist-core/src/main/java/org/exist/xquery/functions/fn/FnFormatNumbers.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ private Tuple2<SubPicture, Optional<SubPicture>> analyzePictureString(final Deci
401401
subPicture.clearSuffix();
402402

403403
subPicture.incrementMaximumFractionalPartSize();
404-
} else if (c == decimalFormat.patternSeparator) {
404+
} else if (c == decimalFormat.patternSeparator) {
405405
capturePrefix = false;
406406
subPicture.clearSuffix();
407407

@@ -442,17 +442,55 @@ private Tuple2<SubPicture, Optional<SubPicture>> analyzePictureString(final Deci
442442
break; // end of FRACTIONAL_PART
443443

444444

445-
446445
case EXPONENT_PART:
446+
447447
if (c == decimalFormat.decimalSeparator
448-
|| c == decimalFormat.exponentSeparator
449448
|| c == decimalFormat.groupingSeparator
450449
|| c == decimalFormat.digit) {
451450
capturePrefix = false;
452451
subPicture.clearSuffix();
453452

454453
throw new XPathException(this, ErrorCodes.FODF1310, "format-number() sub-picture in $picture cannot have any active characters following the exponent-separator-sign");
455454

455+
} else if (c == decimalFormat.exponentSeparator) {
456+
457+
/*
458+
A character that matches the exponent-separator property is treated as an
459+
exponent-separator-sign if it is both preceded and followed within the
460+
sub-picture by an active character.
461+
*/
462+
463+
// we need to peek at the next char to determine if it is active
464+
final boolean nextIsActive;
465+
if (idx + 1 < pictureString.length()) {
466+
nextIsActive = isActiveChar(decimalFormat, pictureString.codePointAt(idx + 1));
467+
} else {
468+
nextIsActive = false;
469+
}
470+
471+
if (isActiveChar(decimalFormat, prevChar) && nextIsActive) {
472+
// this is an exponent-separator-sign... but we already have one
473+
capturePrefix = false;
474+
subPicture.clearSuffix();
475+
476+
throw new XPathException(this, ErrorCodes.FODF1310, "format-number() sub-picture in $picture cannot have any active characters following the exponent-separator-sign");
477+
478+
} else {
479+
// just another passive character
480+
481+
/* passive character */
482+
analyzePassiveChar(decimalFormat, c, capturePrefix, subPicture);
483+
484+
if (subPicture.hasPercent()) {
485+
throw new XPathException(this, ErrorCodes.FODF1310, "format-number() sub-picture cannot contain a percent character as it already has an exponent separator sign.");
486+
}
487+
488+
if (subPicture.hasPerMille()) {
489+
throw new XPathException(this, ErrorCodes.FODF1310, "format-number() sub-picture cannot contain a per-mille character as it already has an exponent separator sign.");
490+
}
491+
}
492+
493+
456494
} else if (c == decimalFormat.patternSeparator) {
457495
capturePrefix = false;
458496
subPicture.clearSuffix();

0 commit comments

Comments
 (0)