From 55289d9c925ae1a74b73c65b58a7aed81bd76300 Mon Sep 17 00:00:00 2001 From: Jan Rose Date: Tue, 27 Jun 2017 11:44:19 +0200 Subject: [PATCH 1/2] =?UTF-8?q?add=20=E2=80=98uri=E2=80=99=20format=20vali?= =?UTF-8?q?dation=20with=20regex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/JSONSchema.swift | 1 + Sources/Validators.swift | 21 +++++++++++++++++++++ Tests/JSONSchemaCases.swift | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Sources/JSONSchema.swift b/Sources/JSONSchema.swift index c4d5c81..b00bdad 100644 --- a/Sources/JSONSchema.swift +++ b/Sources/JSONSchema.swift @@ -61,6 +61,7 @@ public struct Schema { formats = [ "ipv4": validateIPv4, "ipv6": validateIPv6, + "uri": validateURI, ] } diff --git a/Sources/Validators.swift b/Sources/Validators.swift index 6b7d55f..15b69c9 100644 --- a/Sources/Validators.swift +++ b/Sources/Validators.swift @@ -423,3 +423,24 @@ func validateIPv6(_ value:Any) -> ValidationResult { return .Valid } + +func validateURI(_ value:Any) -> ValidationResult { + if let uri = value as? String { + // Using the regex from http://blog.dieweltistgarnichtso.net/constructing-a-regular-expression-that-matches-uris + + if let expression = try? NSRegularExpression(pattern: "((?<=\\()[A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+(?=\\)))|([A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+)", options: NSRegularExpression.Options(rawValue: 0)) { + + let result = expression.matches(in: uri, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, uri.characters.count)) + if result.count == 1 { + let foundRange = result[0].range + if foundRange.location == 0 && foundRange.length == uri.characters.count { + return .Valid + } + } + } + + return .invalid(["'\(uri)' is not a valid URI."]) + } + + return .Valid +} diff --git a/Tests/JSONSchemaCases.swift b/Tests/JSONSchemaCases.swift index 46a1253..d0349be 100644 --- a/Tests/JSONSchemaCases.swift +++ b/Tests/JSONSchemaCases.swift @@ -108,7 +108,7 @@ func makeAssertions(_ c:Case) -> ([Assertion]) { let result = validate(test.data, schema: c.schema) switch result { case .Valid: - XCTAssertEqual(result.valid, test.value, "Result is valid") + XCTAssertEqual(result.valid, test.value, "Result \(test.data) is valid but shouldn't") case .invalid(let errors): XCTAssertEqual(result.valid, test.value, "Failed validation: \(errors)") } From a1231c16c9ce33505d020abc9f2f56f98227282f Mon Sep 17 00:00:00 2001 From: Jan Rose Date: Tue, 27 Jun 2017 11:51:47 +0200 Subject: [PATCH 2/2] removes empty line and modification of testcode --- Sources/Validators.swift | 3 +-- Tests/JSONSchemaCases.swift | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/Validators.swift b/Sources/Validators.swift index 15b69c9..6ae6dc7 100644 --- a/Sources/Validators.swift +++ b/Sources/Validators.swift @@ -428,8 +428,7 @@ func validateURI(_ value:Any) -> ValidationResult { if let uri = value as? String { // Using the regex from http://blog.dieweltistgarnichtso.net/constructing-a-regular-expression-that-matches-uris - if let expression = try? NSRegularExpression(pattern: "((?<=\\()[A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+(?=\\)))|([A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+)", options: NSRegularExpression.Options(rawValue: 0)) { - + if let expression = try? NSRegularExpression(pattern: "((?<=\\()[A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+(?=\\)))|([A-Za-z][A-Za-z0-9\\+\\.\\-]*:([A-Za-z0-9\\.\\-_~:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=]|%[A-Fa-f0-9]{2})+)", options: NSRegularExpression.Options(rawValue: 0)) { let result = expression.matches(in: uri, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, uri.characters.count)) if result.count == 1 { let foundRange = result[0].range diff --git a/Tests/JSONSchemaCases.swift b/Tests/JSONSchemaCases.swift index d0349be..46a1253 100644 --- a/Tests/JSONSchemaCases.swift +++ b/Tests/JSONSchemaCases.swift @@ -108,7 +108,7 @@ func makeAssertions(_ c:Case) -> ([Assertion]) { let result = validate(test.data, schema: c.schema) switch result { case .Valid: - XCTAssertEqual(result.valid, test.value, "Result \(test.data) is valid but shouldn't") + XCTAssertEqual(result.valid, test.value, "Result is valid") case .invalid(let errors): XCTAssertEqual(result.valid, test.value, "Failed validation: \(errors)") }