Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 56 additions & 8 deletions engine/src/main/java/org/hibernate/validator/constraints/UUID.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,77 @@

/**
* @return allow empty strings.
* Per default does not allow empty strings
* Per default does not allow empty strings.
*/
boolean allowEmpty() default false;

/**
* @return {@code true} if nil UUIDs {@code 00000000-0000-0000-0000-000000000000} are valid
* Per default nil UUIDs are valid
* @return {@code true} if nil UUIDs {@code 00000000-0000-0000-0000-000000000000} are valid.
* Per default nil UUIDs are valid.
*/
boolean allowNil() default true;

/**
* Must not be lower than version 1
* Accepts values in the {@code [1; 15]} range, which corresponds to the hexadecimal {@code [1; f]} range.
*
* @return the accepted UUID version numbers
* Per default versions 1 to 5 are allowed
* @return the accepted UUID version numbers.
* Per default, versions 1 through 5 are allowed.
*/
int[] version() default { 1, 2, 3, 4, 5 };

/**
* Must not be lower than variant 0
* Accepts values in the {@code [0; 2]} range.
* <p>
* The variant of the UUID is determined by the binary representation of the 17th hex digit
* ({@code xxxxxxxx-xxxx-xxxx-Vxxx-xxxxxxxxxxxx} where {@code V} is the variant digit).
* <p>
* Currently, only variants {@code [0, 1, 2]} are supported by the validator:
* <table>
* <caption>Table 1</caption>
* <thead>
* <tr>
* <th>Variant #</th>
* <th>Binary Representation</th>
* <th>Hex Digit</th>
* <th>Comment</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>0</td>
* <td>0xxx</td>
* <td>0 - 7</td>
* <td></td>
* </tr>
* <tr>
* <td>1</td>
* <td>10xx</td>
* <td>8 - b</td>
* <td></td>
* </tr>
* <tr>
* <td>2</td>
* <td>110x</td>
* <td>c - d</td>
* <td></td>
* </tr>
* <tr>
* <td>-</td>
* <td>1110</td>
* <td>e</td>
* <td>Unsupported, an UUID with such variant will be considered invalid.</td>
* </tr>
* <tr>
* <td>-</td>
* <td>1111</td>
* <td>f</td>
* <td>Unsupported, an UUID with such variant will be considered invalid.</td>
* </tr>
* </tbody>
* </table>
*
* @return the allowed UUID variant numbers
* Per default variants 0 to 2 are allowed
* Per default, all variants 0 to 2 are allowed
*/
int[] variant() default { 0, 1, 2 };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,11 @@ else if ( valueLength != 36 ) {
return allowNil;
}
else {
if ( Arrays.binarySearch( this.version, version ) == -1 ) {
if ( Arrays.binarySearch( this.version, version ) < 0 ) {
return false;
}
return Arrays.binarySearch( this.variant, variant ) != -1;
return Arrays.binarySearch( this.variant, variant ) > -1;
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
package org.hibernate.validator.test.internal.constraintvalidators.hv;

import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
Expand Down Expand Up @@ -287,5 +288,121 @@ public void validOnlyIfConfiguredVariantMatches() {

}

@Test
public void versionNotInTheAllowedList() {
char[] versions = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

for ( int i = 0; i < versions.length; i++ ) {
int version = Character.digit( versions[i], 16 );
descriptorBuilder.setAttribute( "version", new int[] { version } );

uuidAnnotation = descriptorBuilder.build().getAnnotation();
uuidValidator.initialize( uuidAnnotation );

for ( int j = 0; j < versions.length; j++ ) {
if ( i == j ) {
continue;
}
String uuid = "24e6abaa-b2a8-%sa8e-0622-92adaaae229f".formatted( versions[j] );
assertThat( uuidValidator.isValid( uuid, null ) )
.as( "Expected uuid %s to be invalid because of the version %s not being allowed", uuid, versions[j] )
.isFalse();
}
}
}

@Test
public void variantNotInTheAllowedLis11t() {
descriptorBuilder.setAttribute( "variant", new int[] { 1 } );

uuidAnnotation = descriptorBuilder.build().getAnnotation();
uuidValidator.initialize( uuidAnnotation );

assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-c622-92adaaae229f", null ) );
}

@Test
public void variantNotInTheAllowedList() {
// 0xxx 0 - 7 reserved (NCS backward compatible)
// 10xx 8 - b DCE 1.1, ISO/IEC 11578:1996
// 110x c - d reserved (Microsoft GUID)
// 1110 e reserved (future use)
// 1111 f unknown / invalid. Must end with "0"

descriptorBuilder.setAttribute( "variant", new int[] { 0 } );

uuidAnnotation = descriptorBuilder.build().getAnnotation();
uuidValidator.initialize( uuidAnnotation );

assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-0622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-1622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-2622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-3622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-4622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-5622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-6622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-7622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-8622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-9622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-a622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-b622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-c622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-d622-92adaaae229f", null ) );
// Next two variants are always invalid as they are currently "undefined":
// 1110 e
// 1111 f
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-e622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-f622-92adaaae229f", null ) );

descriptorBuilder.setAttribute( "variant", new int[] { 1 } );

uuidAnnotation = descriptorBuilder.build().getAnnotation();
uuidValidator.initialize( uuidAnnotation );

assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-0622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-1622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-2622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-3622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-4622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-5622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-6622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-7622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-8622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-9622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-a622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-b622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-c622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-d622-92adaaae229f", null ) );
// Next two variants are always invalid as they are currently "undefined":
// 1110 e
// 1111 f
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-e622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-f622-92adaaae229f", null ) );

descriptorBuilder.setAttribute( "variant", new int[] { 2 } );

uuidAnnotation = descriptorBuilder.build().getAnnotation();
uuidValidator.initialize( uuidAnnotation );

assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-0622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-1622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-2622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-3622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-4622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-5622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-6622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-7622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-8622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-9622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-a622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-b622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-c622-92adaaae229f", null ) );
assertTrue( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-d622-92adaaae229f", null ) );
// Next two variants are always invalid as they are currently "undefined":
// 1110 e
// 1111 f
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-e622-92adaaae229f", null ) );
assertFalse( uuidValidator.isValid( "24e6abaa-b2a8-4a8e-f622-92adaaae229f", null ) );

}
}
Loading