diff --git a/src/main/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java b/src/main/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java index 2054fbe3f..6f46f77fd 100644 --- a/src/main/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java +++ b/src/main/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java @@ -66,8 +66,13 @@ public SedolCheckDigit() { */ @Override protected int calculateModulus(final String code, final boolean includesCheckDigit) throws CheckDigitException { - if (code.length() > POSITION_WEIGHT.length) { - throw new CheckDigitException("Invalid Code Length = %d", code.length()); + final int length = code.length(); + // A SEDOL is exactly seven characters. When the check digit is included the whole code must be that + // length; the previous test only rejected over-length codes, so a shorter string carrying a chance + // modulus 10 check digit (for example "55") still validated. The calculate path receives the six + // character base, so only the over-length case is guarded there. + if (length > POSITION_WEIGHT.length || includesCheckDigit && length != POSITION_WEIGHT.length) { + throw new CheckDigitException("Invalid Code Length = %d", length); } return super.calculateModulus(code, includesCheckDigit); } diff --git a/src/test/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigitTest.java b/src/test/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigitTest.java index 91ae353b9..185443662 100644 --- a/src/test/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigitTest.java +++ b/src/test/java/org/apache/commons/validator/routines/checkdigit/SedolCheckDigitTest.java @@ -64,4 +64,15 @@ void testVowelsRejected(final String code) { assertFalse(routine.isValid(code), "Should fail (contains a vowel): " + code); } + /** + * A SEDOL is exactly seven characters, but a shorter string can carry a modulus 10 check digit by chance (for + * example "55", "550" and "5500" all weight to 20, and "0055" to 40), so the length must be enforced or isValid + * accepts it. + */ + @ParameterizedTest + @ValueSource(strings = { "55", "550", "5500", "0055" }) + void testUnderLengthRejected(final String code) { + assertFalse(routine.isValid(code), "Should fail (not seven characters): " + code); + } + }