From 1db5ec5e3f1e740912584669758fef37862e6654 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 7 Jun 2026 21:36:30 +0200 Subject: [PATCH 1/2] Empty host part in the URI is allowed --- .../json/schema/internal/formats/UriSpec.kt | 32 ++++++++++++++----- .../JsonSchemaUriFormatValidationTest.kt | 2 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt index 08c629ce..a9584932 100644 --- a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt +++ b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt @@ -17,12 +17,17 @@ internal object UriSpec { return true } return when { - hierPart.startsWith("//") -> + hierPart.startsWith("//") -> { isValidAuthorityWithPath(hierPart.substring(2)) - hierPart.startsWith("/") -> + } + + hierPart.startsWith("/") -> { isValidAbsolutePath(hierPart.substring(1)) - else -> + } + + else -> { isValidRootlessPath(hierPart) + } } } @@ -31,12 +36,17 @@ internal object UriSpec { return true } return when { - relativePart.startsWith("//") -> + relativePart.startsWith("//") -> { isValidAuthorityWithPath(relativePart.substring(2)) - relativePart.startsWith("/") -> + } + + relativePart.startsWith("/") -> { isValidAbsolutePath(relativePart.substring(1)) - else -> + } + + else -> { isValidNoschemaPath(relativePart) + } } } @@ -106,8 +116,12 @@ internal object UriSpec { val segmentSeparatorIndex = authorityWithPath.indexOf('/') val hostEndIndex = when { + // authority cannot start from : portSeparatorIndex > 0 -> portSeparatorIndex - segmentSeparatorIndex > 0 -> segmentSeparatorIndex + + // there is not / in authority part so we should take the segment as the end of host name event if it is the first character (empty host) + segmentSeparatorIndex >= 0 -> segmentSeparatorIndex + else -> authorityWithPath.length } val hostStartIndex = @@ -148,8 +162,10 @@ internal object UriSpec { } private fun isValidHost(host: String): Boolean { + // According to RFC3986 https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2 + // It is okay to have an empty host because some of the schemas have a default resolution strategy if (host.isEmpty()) { - return false + return true } if (IpV4FormatValidator.validate(host).isValid()) { return true diff --git a/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaUriFormatValidationTest.kt b/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaUriFormatValidationTest.kt index 5ab13011..f2200f75 100644 --- a/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaUriFormatValidationTest.kt +++ b/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaUriFormatValidationTest.kt @@ -20,11 +20,11 @@ class JsonSchemaUriFormatValidationTest : FunSpec() { "https://localhost#", "h://localhost", "https://locahost#frag?ment", + "file:///home/runner/work/gloo-mesh-enterprise", ), invalidTestCases = listOf( TestCase("", "empty"), - TestCase("https:///", "empty hostname"), TestCase("2http://localhost", "invalid schema"), TestCase("https://example.com:44a/", "invalid port"), TestCase("https:", "only schema"), From 27e923aa433df7624ad9fa3e6a079b24ca7cea1f Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 7 Jun 2026 21:40:31 +0200 Subject: [PATCH 2/2] fix comment lenght issue --- .../github/optimumcode/json/schema/internal/formats/UriSpec.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt index a9584932..cd4ee6b0 100644 --- a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt +++ b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt @@ -119,7 +119,8 @@ internal object UriSpec { // authority cannot start from : portSeparatorIndex > 0 -> portSeparatorIndex - // there is not / in authority part so we should take the segment as the end of host name event if it is the first character (empty host) + // there is not / in authority part so we should take the segment + // as the end of host name event if it is the first character (empty host) segmentSeparatorIndex >= 0 -> segmentSeparatorIndex else -> authorityWithPath.length