[pbs-devel] [PATCH proxmox 1/3] schema: use i64 for minimum / maximum / default integer values

Stefan Hanreich s.hanreich at proxmox.com
Wed Jan 29 11:42:48 CET 2025


IntegerSchema used isize for the minimum / maximum parameters. On 32
bit targets (wasm for instance) API defintions with minimum / maximum
sizes outside the i32 range would fail.

This also changes the u64 deserialize to fail if it encounters a value
that cannot be represented as i64 instead of simply casting it to i64
and moving on.

Signed-off-by: Stefan Hanreich <s.hanreich at proxmox.com>
---
 proxmox-schema/src/de/mod.rs    |  3 +--
 proxmox-schema/src/de/verify.rs | 13 ++++++++-----
 proxmox-schema/src/schema.rs    | 18 +++++++++---------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/proxmox-schema/src/de/mod.rs b/proxmox-schema/src/de/mod.rs
index eca835e3..1f14503e 100644
--- a/proxmox-schema/src/de/mod.rs
+++ b/proxmox-schema/src/de/mod.rs
@@ -173,8 +173,7 @@ impl<'de> de::Deserializer<'de> for SchemaDeserializer<'de, '_> {
                     .map_err(|_| Error::msg(format!("not a boolean: {:?}", self.input)))?,
             ),
             Schema::Integer(schema) => {
-                // FIXME: isize vs explicit i64, needs fixing in schema check_constraints api
-                let value: isize = self
+                let value: i64 = self
                     .input
                     .parse()
                     .map_err(|_| Error::msg(format!("not an integer: {:?}", self.input)))?;
diff --git a/proxmox-schema/src/de/verify.rs b/proxmox-schema/src/de/verify.rs
index 67a8c9e8..917f956b 100644
--- a/proxmox-schema/src/de/verify.rs
+++ b/proxmox-schema/src/de/verify.rs
@@ -170,7 +170,7 @@ impl<'de> de::Visitor<'de> for Visitor {
 
     fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
         match self.0 {
-            Schema::Integer(schema) => match schema.check_constraints(v as isize) {
+            Schema::Integer(schema) => match schema.check_constraints(v) {
                 Ok(()) => Ok(Verifier),
                 Err(err) => Err(E::custom(err)),
             },
@@ -180,10 +180,13 @@ impl<'de> de::Visitor<'de> for Visitor {
 
     fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
         match self.0 {
-            Schema::Integer(schema) => match schema.check_constraints(v as isize) {
-                Ok(()) => Ok(Verifier),
-                Err(err) => Err(E::custom(err)),
-            },
+            Schema::Integer(schema) => {
+                let val = v.try_into().or_else(|err| Err(E::custom(err)))?;
+                match schema.check_constraints(val) {
+                    Ok(()) => Ok(Verifier),
+                    Err(err) => Err(E::custom(err)),
+                }
+            }
             _ => Err(E::invalid_type(Unexpected::Unsigned(v), &self)),
         }
     }
diff --git a/proxmox-schema/src/schema.rs b/proxmox-schema/src/schema.rs
index 3448112b..3090da09 100644
--- a/proxmox-schema/src/schema.rs
+++ b/proxmox-schema/src/schema.rs
@@ -228,11 +228,11 @@ impl BooleanSchema {
 pub struct IntegerSchema {
     pub description: &'static str,
     /// Optional minimum.
-    pub minimum: Option<isize>,
+    pub minimum: Option<i64>,
     /// Optional maximum.
-    pub maximum: Option<isize>,
+    pub maximum: Option<i64>,
     /// Optional default.
-    pub default: Option<isize>,
+    pub default: Option<i64>,
 }
 
 impl IntegerSchema {
@@ -250,17 +250,17 @@ impl IntegerSchema {
         self
     }
 
-    pub const fn default(mut self, default: isize) -> Self {
+    pub const fn default(mut self, default: i64) -> Self {
         self.default = Some(default);
         self
     }
 
-    pub const fn minimum(mut self, minimum: isize) -> Self {
+    pub const fn minimum(mut self, minimum: i64) -> Self {
         self.minimum = Some(minimum);
         self
     }
 
-    pub const fn maximum(mut self, maximum: isize) -> Self {
+    pub const fn maximum(mut self, maximum: i64) -> Self {
         self.maximum = Some(maximum);
         self
     }
@@ -269,7 +269,7 @@ impl IntegerSchema {
         Schema::Integer(self)
     }
 
-    pub fn check_constraints(&self, value: isize) -> Result<(), Error> {
+    pub fn check_constraints(&self, value: i64) -> Result<(), Error> {
         if let Some(minimum) = self.minimum {
             if value < minimum {
                 bail!(
@@ -296,7 +296,7 @@ impl IntegerSchema {
     /// Verify JSON value using an `IntegerSchema`.
     pub fn verify_json(&self, data: &Value) -> Result<(), Error> {
         if let Some(value) = data.as_i64() {
-            self.check_constraints(value as isize)
+            self.check_constraints(value)
         } else {
             bail!("Expected integer value.");
         }
@@ -1235,7 +1235,7 @@ impl Schema {
                 Value::Bool(res)
             }
             Schema::Integer(integer_schema) => {
-                let res: isize = value_str.parse()?;
+                let res: i64 = value_str.parse()?;
                 integer_schema.check_constraints(res)?;
                 Value::Number(res.into())
             }
-- 
2.39.5




More information about the pbs-devel mailing list