Skip to content

Commit 9bf38a0

Browse files
authored
Empty host part in the URI is allowed (#455)
Based on https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, the URI might have an empty host part in the authority section. Resolves #454
1 parent 665f203 commit 9bf38a0

2 files changed

Lines changed: 26 additions & 9 deletions

File tree

json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/UriSpec.kt

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@ internal object UriSpec {
1717
return true
1818
}
1919
return when {
20-
hierPart.startsWith("//") ->
20+
hierPart.startsWith("//") -> {
2121
isValidAuthorityWithPath(hierPart.substring(2))
22-
hierPart.startsWith("/") ->
22+
}
23+
24+
hierPart.startsWith("/") -> {
2325
isValidAbsolutePath(hierPart.substring(1))
24-
else ->
26+
}
27+
28+
else -> {
2529
isValidRootlessPath(hierPart)
30+
}
2631
}
2732
}
2833

@@ -31,12 +36,17 @@ internal object UriSpec {
3136
return true
3237
}
3338
return when {
34-
relativePart.startsWith("//") ->
39+
relativePart.startsWith("//") -> {
3540
isValidAuthorityWithPath(relativePart.substring(2))
36-
relativePart.startsWith("/") ->
41+
}
42+
43+
relativePart.startsWith("/") -> {
3744
isValidAbsolutePath(relativePart.substring(1))
38-
else ->
45+
}
46+
47+
else -> {
3948
isValidNoschemaPath(relativePart)
49+
}
4050
}
4151
}
4252

@@ -106,8 +116,13 @@ internal object UriSpec {
106116
val segmentSeparatorIndex = authorityWithPath.indexOf('/')
107117
val hostEndIndex =
108118
when {
119+
// authority cannot start from :
109120
portSeparatorIndex > 0 -> portSeparatorIndex
110-
segmentSeparatorIndex > 0 -> segmentSeparatorIndex
121+
122+
// there is not / in authority part so we should take the segment
123+
// as the end of host name event if it is the first character (empty host)
124+
segmentSeparatorIndex >= 0 -> segmentSeparatorIndex
125+
111126
else -> authorityWithPath.length
112127
}
113128
val hostStartIndex =
@@ -148,8 +163,10 @@ internal object UriSpec {
148163
}
149164

150165
private fun isValidHost(host: String): Boolean {
166+
// According to RFC3986 https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
167+
// It is okay to have an empty host because some of the schemas have a default resolution strategy
151168
if (host.isEmpty()) {
152-
return false
169+
return true
153170
}
154171
if (IpV4FormatValidator.validate(host).isValid()) {
155172
return true

json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaUriFormatValidationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class JsonSchemaUriFormatValidationTest : FunSpec() {
2020
"https://localhost#",
2121
"h://localhost",
2222
"https://locahost#frag?ment",
23+
"file:///home/runner/work/gloo-mesh-enterprise",
2324
),
2425
invalidTestCases =
2526
listOf(
2627
TestCase("", "empty"),
27-
TestCase("https:///", "empty hostname"),
2828
TestCase("2http://localhost", "invalid schema"),
2929
TestCase("https://example.com:44a/", "invalid port"),
3030
TestCase("https:", "only schema"),

0 commit comments

Comments
 (0)