Skip to content

Commit

Permalink
fix: ipv4 format validation
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
  • Loading branch information
Stranger6667 committed Sep 15, 2024
1 parent 426df9c commit 0f21542
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- `ipv4` format validation. [#512](https://github.com/Stranger6667/jsonschema-rs/issues/512)

## [0.19.0] - 2024-09-14

### Added
Expand Down
4 changes: 4 additions & 0 deletions crates/jsonschema-py/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- `ipv4` format validation. [#512](https://github.com/Stranger6667/jsonschema-rs/issues/512)

## [0.19.0] - 2024-09-14

### Fixed
Expand Down
42 changes: 30 additions & 12 deletions crates/jsonschema/src/keywords/format.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Validator for `format` keyword.
use std::{net::IpAddr, str::FromStr, sync::Arc};
use std::{
net::{Ipv4Addr, Ipv6Addr},
str::FromStr,
sync::Arc,
};

use fancy_regex::Regex;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -206,13 +210,7 @@ impl Validate for IpV4Validator {
validate!("ipv4");
fn is_valid(&self, instance: &Value) -> bool {
if let Value::String(item) = instance {
if item.starts_with('0') {
return false;
}
match IpAddr::from_str(item.as_str()) {
Ok(i) => i.is_ipv4(),
Err(_) => false,
}
Ipv4Addr::from_str(item).is_ok()
} else {
true
}
Expand All @@ -224,10 +222,7 @@ impl Validate for IpV6Validator {
validate!("ipv6");
fn is_valid(&self, instance: &Value) -> bool {
if let Value::String(item) = instance {
match IpAddr::from_str(item.as_str()) {
Ok(i) => i.is_ipv6(),
Err(_) => false,
}
Ipv6Addr::from_str(item).is_ok()
} else {
true
}
Expand Down Expand Up @@ -531,6 +526,7 @@ pub(crate) fn compile<'a>(
#[cfg(test)]
mod tests {
use serde_json::json;
use test_case::test_case;

use crate::{
compilation::JSONSchema, error::ValidationErrorKind, schemas::Draft::Draft201909,
Expand Down Expand Up @@ -642,4 +638,26 @@ mod tests {
);
assert_eq!("\"custom\"", validation_error.instance.to_string())
}

#[test_case("127.0.0.1", true)]
#[test_case("192.168.1.1", true)]
#[test_case("10.0.0.1", true)]
#[test_case("0.0.0.0", true)]
#[test_case("256.1.2.3", false; "first octet too large")]
#[test_case("1.256.3.4", false; "second octet too large")]
#[test_case("1.2.256.4", false; "third octet too large")]
#[test_case("1.2.3.256", false; "fourth octet too large")]
#[test_case("01.2.3.4", false; "leading zero in first octet")]
#[test_case("1.02.3.4", false; "leading zero in second octet")]
#[test_case("1.2.03.4", false; "leading zero in third octet")]
#[test_case("1.2.3.04", false; "leading zero in fourth octet")]
#[test_case("1.2.3", false; "too few octets")]
#[test_case("1.2.3.4.5", false; "too many octets")]
fn ip_v4(input: &str, expected: bool) {
let validator = JSONSchema::options()
.should_validate_formats(true)
.compile(&json!({"format": "ipv4", "type": "string"}))
.expect("Invalid schema");
assert_eq!(validator.is_valid(&json!(input)), expected);
}
}

0 comments on commit 0f21542

Please sign in to comment.