Repository: tipsy/javalin (kotlin)

Issue:
CORS `IndexOutOfBoundsException` when you pass an `Origin` without a `.`
**Actual behavior (the bug)**
I get a `java.lang.IndexOutOfBoundsException: Index: 1, Size: 1` exception when using the `CorsPlugin` and pass in header `https://exactxcom`. This is due to `CorsUtils` `originsMatch` method line 139, - see the split: `clientOrigin.host.split('.', limit = 2)[1]`

**Expected behavior**
Need to allow for a client host without a full stop.

**To Reproduce**
Enable Cors plugin, pass in an origin header like `https://single` see the fireworks.

**Additional context**

Pull request description:
This fixes the Exception as described in #2104.

Will do another PR soon to rewrite it using the JDK's URI class.

Fixes #2104

Patch:
diff --git a/javalin/src/main/java/io/javalin/plugin/bundled/CorsUtils.kt b/javalin/src/main/java/io/javalin/plugin/bundled/CorsUtils.kt
index 1662f1540..0015e7590 100644
--- a/javalin/src/main/java/io/javalin/plugin/bundled/CorsUtils.kt
+++ b/javalin/src/main/java/io/javalin/plugin/bundled/CorsUtils.kt
@@ -135,6 +135,10 @@ internal object CorsUtils {
         if (!serverOrigin.host.startsWith("*.")) {
             return false
         }
+        // the above lines imply a requirement of at least one dot in the origin header sent by the client
+        if ('.' !in clientOrigin.host) {
+            return false
+        }
         val serverHostBase = serverOrigin.host.removePrefix("*.")
         val clientHostBase = clientOrigin.host.split('.', limit = 2)[1]
 


Test patch:
diff --git a/javalin/src/test/java/io/javalin/TestCors.kt b/javalin/src/test/java/io/javalin/TestCors.kt
index 95c603d1e..b7308807c 100644
--- a/javalin/src/test/java/io/javalin/TestCors.kt
+++ b/javalin/src/test/java/io/javalin/TestCors.kt
@@ -427,6 +427,23 @@ class TestCors {
                 .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED)
             assertThat(getResponse.header(ACCESS_CONTROL_ALLOW_ORIGIN)).isEqualTo("https://example.com")
         }
+
+        @Test
+        fun `GH-2104 client sends dotless origin - wildcard configured`() = TestUtil.test(Javalin.create { cfg ->
+            cfg.bundledPlugins.enableCors { cors ->
+                cors.addRule {
+                    it.allowHost("*.example.com")
+                }
+            }
+        }) { app, http ->
+            app.get("/") { it.result("Hello") }
+
+            val response = http.get("/", mapOf(ORIGIN to "https://single"))
+            assertThat(response.status)
+                .describedAs("get status code")
+                .isEqualTo(HttpStatus.BAD_REQUEST)
+            assertThat(response.header(ACCESS_CONTROL_ALLOW_ORIGIN)).isEmpty()
+        }
     }
 
     @Nested