From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 6AAFF1FF13E for ; Fri, 06 Feb 2026 17:12:08 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D51CF9A01; Fri, 6 Feb 2026 17:12:40 +0100 (CET) From: Arthur Bied-Charreton To: pve-devel@lists.proxmox.com Subject: [PATCH pve-common v2 1/1] fix #7077: Change JSON Schema attribute validation order Date: Fri, 6 Feb 2026 17:12:32 +0100 Message-ID: <20260206161236.335026-2-a.bied-charreton@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260206161236.335026-1-a.bied-charreton@proxmox.com> References: <20260206161236.335026-1-a.bied-charreton@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.082 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: L33NI2ZZPMIDD55CCNEXGIMQPVQUOQXU X-Message-ID-Hash: L33NI2ZZPMIDD55CCNEXGIMQPVQUOQXU X-MailFrom: abied-charreton@jett.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 --- 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