From 71c159156980f22ad3431d2925ba2026a130a26c Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Mon, 3 Feb 2025 19:36:20 +0400 Subject: [PATCH] Disallow a single dot in idn hostnames --- .../schema/internal/formats/IdnHostnameFormatValidator.kt | 7 ++++++- .../format/JsonSchemaIdnHostnameFormatValidationTest.kt | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/IdnHostnameFormatValidator.kt b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/IdnHostnameFormatValidator.kt index 6e52596f..29e622e6 100644 --- a/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/IdnHostnameFormatValidator.kt +++ b/json-schema-validator/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/formats/IdnHostnameFormatValidator.kt @@ -49,7 +49,7 @@ internal object IdnHostnameFormatValidator : AbstractStringFormatValidator() { return FormatValidator.Invalid() } if (value.length == 1 && isLabelSeparator(value[0])) { - return FormatValidator.Valid() + return FormatValidator.Invalid() } // https://datatracker.ietf.org/doc/html/rfc5893#section-1.4 @@ -506,6 +506,11 @@ internal object IdnHostnameFormatValidator : AbstractStringFormatValidator() { private fun isACE(label: String): Boolean = label.length > Punycode.PREFIX_SIZE && label.startsWith(Punycode.PREFIX_STRING) + /** + * Returns `true` if the [c] is a dot + * according to [RFC3490 Section 3.1](https://datatracker.ietf.org/doc/html/rfc3490#section-3.1). + * Otherwise, returns `false` + */ private fun isLabelSeparator(c: Char): Boolean = c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61' private fun findDot( diff --git a/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaIdnHostnameFormatValidationTest.kt b/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaIdnHostnameFormatValidationTest.kt index 76ab6654..b16fe2a3 100644 --- a/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaIdnHostnameFormatValidationTest.kt +++ b/json-schema-validator/src/commonTest/kotlin/io/github/optimumcode/json/schema/assertions/general/format/JsonSchemaIdnHostnameFormatValidationTest.kt @@ -9,7 +9,6 @@ class JsonSchemaIdnHostnameFormatValidationTest : FunSpec() { format = "idn-hostname", validTestCases = listOf( - ".", "a", "hostname", // 63 @@ -30,6 +29,10 @@ class JsonSchemaIdnHostnameFormatValidationTest : FunSpec() { invalidTestCases = listOf( TestCase("", "empty value"), + TestCase(".", "single separator"), + TestCase("\u3002", "single separator U+3002"), + TestCase("\uFF0E", "single separator U+FF0E"), + TestCase("\uFF61", "single separator U+FF61"), TestCase("xn--80aakdqneodaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaai7g2bxc6qoj1f", "too long punycode"), TestCase("оооооооооооооооооооооооооооооооооооченьдлиннаястрока", "too long unicode"), // Not normalized \u4E3D. Example from https://unicode.org/Public/UNIDATA/NormalizationTest.txt