The JSON Schema validation first checks input against the registered
format function, then against the registered pattern, and only then
against {min,max}-length.

This causes length constraints to be poorly reported when they are
implicit in custom format verification code or regex patterns, which 
results in generic format violation error messages instead of the
more specific length violation.

Change the validation order to check length constraints before anything
else. This is functionally equivalent, and comes with the UX advantage
of providing more precise error messages in a lot of cases.

Signed-off-by: Arthur Bied-Charreton <[email protected]>
---
 src/PVE/JSONSchema.pm | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/PVE/JSONSchema.pm b/src/PVE/JSONSchema.pm
index 0c9bb82..531a52c 100644
--- a/src/PVE/JSONSchema.pm
+++ b/src/PVE/JSONSchema.pm
@@ -1463,31 +1463,31 @@ sub check_prop {
 
     } else {
 
-        if (my $format = $schema->{format}) {
-            eval { check_format($format, $value, $path); };
-            if ($@) {
-                add_error($errors, $path, "invalid format - $@");
+        if (defined(my $max = $schema->{maxLength})) {
+            if (length($value) > $max) {
+                add_error($errors, $path, "value may only be $max characters 
long");
                 return;
             }
         }
 
-        if (my $pattern = $schema->{pattern}) {
-            if ($value !~ m/^$pattern$/) {
-                add_error($errors, $path, "value does not match the regex 
pattern");
+        if (defined(my $min = $schema->{minLength})) {
+            if (length($value) < $min) {
+                add_error($errors, $path, "value must be at least $min 
characters long");
                 return;
             }
         }
 
-        if (defined(my $max = $schema->{maxLength})) {
-            if (length($value) > $max) {
-                add_error($errors, $path, "value may only be $max characters 
long");
+        if (my $format = $schema->{format}) {
+            eval { check_format($format, $value, $path); };
+            if ($@) {
+                add_error($errors, $path, "invalid format - $@");
                 return;
             }
         }
 
-        if (defined(my $min = $schema->{minLength})) {
-            if (length($value) < $min) {
-                add_error($errors, $path, "value must be at least $min 
characters long");
+        if (my $pattern = $schema->{pattern}) {
+            if ($value !~ m/^$pattern$/) {
+                add_error($errors, $path, "value does not match the regex 
pattern");
                 return;
             }
         }
-- 
2.47.3



Reply via email to