From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH common 2/3] json schema: add tests for numeric behavior
Date: Thu, 8 Oct 2026 15:48:12 +0200 [thread overview]
Message-ID: <20261008135224.3323985-3-d.csapak@proxmox.com> (raw)
In-Reply-To: <20261008135224.3323985-1-d.csapak@proxmox.com>
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
test/json-schema-test.pl | 166 +++++++++++++++++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/test/json-schema-test.pl b/test/json-schema-test.pl
index f1c968f..c5014e9 100755
--- a/test/json-schema-test.pl
+++ b/test/json-schema-test.pl
@@ -22,6 +22,10 @@ use Test::More;
# in - input of the sub-test
# out - expected output of the sub-test, falls back to outer `out`
# must_fail - if set the test must fail and the error must match the regex defined here.
+
+# exceeds the range of a double, so it numifies to infinity
+my $huge_int = '1' . ('0' x 400);
+
my $property_string_tests = [
{
name => 'default-key-with-type-boolean',
@@ -99,6 +103,38 @@ my $property_string_tests = [
},
],
},
+ {
+ name => 'huge-numeric-values',
+ format => {
+ int => { type => 'integer', optional => 1 },
+ num => { type => 'number', optional => 1 },
+ 'int-ranged' => { type => 'integer', optional => 1, minimum => -10, maximum => 10 },
+ 'num-ranged' => { type => 'number', optional => 1, minimum => -1, maximum => 1 },
+ },
+ subtests => [
+ { in => "int=$huge_int", out => { int => $huge_int } },
+ { in => "int=-$huge_int", out => { int => "-$huge_int" } },
+ { in => "num=$huge_int", out => { num => $huge_int } },
+ { in => "num=1e400", out => { num => '1e400' } },
+ { in => "num=-1e400", out => { num => '-1e400' } },
+ {
+ in => "int-ranged=$huge_int",
+ must_fail => qr/int-ranged: value must have a maximum value of 10/,
+ },
+ {
+ in => "int-ranged=-$huge_int",
+ must_fail => qr/int-ranged: value must have a minimum value of -10/,
+ },
+ {
+ in => "num-ranged=1e400",
+ must_fail => qr/num-ranged: value must have a maximum value of 1/,
+ },
+ {
+ in => "num-ranged=-1e400",
+ must_fail => qr/num-ranged: value must have a minimum value of -1/,
+ },
+ ],
+ },
# TODO: more tests, like complex formats and ranges and the like
];
@@ -863,4 +899,134 @@ for my $test ($check_one_of->@*) {
};
}
+# check numeric type and range checks with values exceeding the range of a double
+#
+# Properties of a test:
+#
+# name - describes the test
+# schema - the schema of the property 'value'
+# subtests - list of:
+# name - describes the sub-test
+# in - the value to check
+# must_fail - regex that must match the error of the property
+my $numeric_tests = [
+ {
+ name => 'huge integer',
+ schema => { type => 'integer' },
+ subtests => [
+ { name => 'positive', in => "100" },
+ { name => 'negative', in => "-100" },
+ { name => 'explicit plus sign', in => "+100" },
+ {
+ name => 'exponent notation',
+ in => '1e2',
+ must_fail => qr/^type check \('integer'\) failed - got '1e2'/,
+ },
+ {
+ name => 'not a number',
+ in => 'foo',
+ must_fail => qr/^type check \('integer'\) failed/,
+ },
+ ],
+ },
+ {
+ name => 'huge integer',
+ schema => { type => 'integer' },
+ subtests => [
+ { name => 'positive', in => $huge_int },
+ { name => 'negative', in => "-$huge_int" },
+ { name => 'explicit plus sign', in => "+$huge_int" },
+ {
+ name => 'exponent notation',
+ in => '1e400',
+ must_fail => qr/^type check \('integer'\) failed/,
+ },
+ {
+ name => 'fractional part',
+ in => "$huge_int.0",
+ must_fail => qr/^type check \('integer'\) failed/,
+ },
+ ],
+ },
+ {
+ name => 'huge integer with range',
+ schema => { type => 'integer', minimum => -10, maximum => 10 },
+ subtests => [
+ {
+ name => 'above maximum',
+ in => $huge_int,
+ must_fail => qr/^value must have a maximum value of 10$/,
+ },
+ {
+ name => 'below minimum',
+ in => "-$huge_int",
+ must_fail => qr/^value must have a minimum value of -10$/,
+ },
+ ],
+ },
+ {
+ name => 'huge number',
+ schema => { type => 'number' },
+ subtests => [
+ { name => 'integer notation', in => $huge_int },
+ { name => 'negative integer notation', in => "-$huge_int" },
+ { name => 'fractional part', in => "$huge_int.5" },
+ { name => 'exponent notation', in => '1e400' },
+ { name => 'negative exponent notation', in => '-1e400' },
+ { name => 'tiny exponent notation', in => '1e-400' },
+ {
+ name => 'infinity literal',
+ in => 'inf',
+ must_fail => qr/^type check \('number'\) failed/,
+ },
+ ],
+ },
+ {
+ name => 'huge number with range',
+ schema => { type => 'number', minimum => 0, maximum => 1 },
+ subtests => [
+ {
+ name => 'above maximum',
+ in => '1e400',
+ must_fail => qr/^value must have a maximum value of 1$/,
+ },
+ {
+ name => 'above maximum in integer notation',
+ in => $huge_int,
+ must_fail => qr/^value must have a maximum value of 1$/,
+ },
+ {
+ name => 'below minimum',
+ in => '-1e400',
+ must_fail => qr/^value must have a minimum value of 0$/,
+ },
+ { name => 'tiny value within range', in => '1e-400' },
+ ],
+ },
+];
+
+for my $test ($numeric_tests->@*) {
+ subtest $test->{name}, sub {
+ for my $subtest ($test->{subtests}->@*) {
+ my $name = $subtest->{name};
+ my $schema = {
+ type => 'object',
+ properties => { value => $test->{schema} },
+ };
+ my $value = { value => $subtest->{in} };
+
+ my $errors = {};
+ PVE::JSONSchema::check_prop($value, $schema, undef, $errors);
+
+ if (my $must_fail = $subtest->{must_fail}) {
+ like(delete($errors->{value}) // '', $must_fail, "$name - failed as expected");
+ }
+ my $err_str = join("\n", map { "$_: $errors->{$_}" } sort keys %$errors);
+ is($err_str, '', "$name - no unexpected errors");
+ is($value->{value}, $subtest->{in}, "$name - value remains unchanged");
+ }
+ done_testing();
+ };
+}
+
done_testing();
--
2.47.3
next prev parent reply other threads:[~2026-10-08 13:52 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-08 13:48 [PATCH common 0/3] fix #7612 Dominik Csapak
2026-10-08 13:48 ` [PATCH common 1/3] json schema: reorder imports to our style guide Dominik Csapak
2026-10-08 13:48 ` Dominik Csapak [this message]
2026-10-08 13:48 ` [PATCH common 3/3] fix #7612: json schema: don't allow integers that are too large Dominik Csapak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261008135224.3323985-3-d.csapak@proxmox.com \
--to=d.csapak@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox