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..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 @@ -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,13 @@ 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 +163,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"),