all lists on lists.proxmox.com
 help / color / mirror / Atom feed
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





  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal