Fixes single label domains with non ascii chars around them
This commit is contained in:
+13
-2
@@ -298,11 +298,22 @@ class DomainNameReader(
|
||||
topLevelLength = currentLabelLength
|
||||
}
|
||||
|
||||
var lastWasAscii: Boolean? = null
|
||||
var lastWasAscii: Boolean? =
|
||||
if (current.isNullOrEmpty()) {
|
||||
null
|
||||
} else {
|
||||
val last = current.last()
|
||||
if (isDot(last)) {
|
||||
null
|
||||
} else {
|
||||
last.code < INTERNATIONAL_CHAR_START
|
||||
}
|
||||
}
|
||||
var isAscii = false
|
||||
|
||||
while (!done && !reader.eof()) {
|
||||
val curr: Char = reader.read()
|
||||
|
||||
isAscii = curr.code < INTERNATIONAL_CHAR_START
|
||||
if (lastWasAscii == null) {
|
||||
lastWasAscii = isAscii
|
||||
@@ -765,7 +776,7 @@ class DomainNameReader(
|
||||
* The start of the utf character code table which indicates that this character is an international character.
|
||||
* Everything below this value is either a-z,A-Z,0-9 or symbols that are not included in domain name.
|
||||
*/
|
||||
private const val INTERNATIONAL_CHAR_START = 192
|
||||
const val INTERNATIONAL_CHAR_START = 192
|
||||
|
||||
/**
|
||||
* The maximum length of each label in the domain name.
|
||||
|
||||
+23
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.utils.urldetector.detection
|
||||
import com.vitorpamplona.quartz.utils.urldetector.Url
|
||||
import com.vitorpamplona.quartz.utils.urldetector.UrlMarker
|
||||
import com.vitorpamplona.quartz.utils.urldetector.UrlPart
|
||||
import com.vitorpamplona.quartz.utils.urldetector.detection.DomainNameReader.Companion.INTERNATIONAL_CHAR_START
|
||||
import kotlin.math.max
|
||||
import kotlin.text.deleteRange
|
||||
|
||||
@@ -84,6 +85,9 @@ class UrlDetector(
|
||||
var length = 0
|
||||
var position = 0
|
||||
|
||||
var lastWasAscii: Boolean? = null
|
||||
var isAscii = false
|
||||
|
||||
// until end of string read the contents
|
||||
while (!reader.eof()) {
|
||||
// read the next char to process.
|
||||
@@ -96,6 +100,7 @@ class UrlDetector(
|
||||
}
|
||||
readEnd(ReadEndState.InvalidUrl)
|
||||
length = 0
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
'%' -> {
|
||||
@@ -116,6 +121,7 @@ class UrlDetector(
|
||||
length = 0
|
||||
}
|
||||
}
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
'\u3002', '\uFF0E', '\uFF61', '.' -> {
|
||||
@@ -125,6 +131,7 @@ class UrlDetector(
|
||||
readEnd(ReadEndState.InvalidUrl)
|
||||
}
|
||||
length = 0
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
'@' -> {
|
||||
@@ -136,6 +143,7 @@ class UrlDetector(
|
||||
}
|
||||
length = 0
|
||||
}
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
'[' -> {
|
||||
@@ -153,6 +161,7 @@ class UrlDetector(
|
||||
reader.seek(beginning)
|
||||
}
|
||||
length = 0
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
'/' -> {
|
||||
@@ -180,15 +189,29 @@ class UrlDetector(
|
||||
hasScheme = readHtml5Root()
|
||||
length = buffer.length
|
||||
}
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
':' -> {
|
||||
// add the ":" to the url and check for scheme/username
|
||||
buffer.append(curr)
|
||||
length = processColon(length)
|
||||
lastWasAscii = null
|
||||
}
|
||||
|
||||
else -> {
|
||||
isAscii = curr.code < INTERNATIONAL_CHAR_START
|
||||
if (lastWasAscii == null) {
|
||||
lastWasAscii = isAscii
|
||||
} else if (isAscii != lastWasAscii) {
|
||||
// threat changes in char as a space
|
||||
if (buffer.isNotEmpty() && hasScheme) {
|
||||
reader.goBack()
|
||||
readDomainName(buffer.substring(length))
|
||||
}
|
||||
length = 0
|
||||
}
|
||||
|
||||
buffer.append(curr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,6 @@ class UrlTest {
|
||||
assertNotNull(url.path)
|
||||
assertNotNull(url.query)
|
||||
assertNotNull(url.fragment)
|
||||
assertEquals(-1, url.port) // getPart(PORT) returns null → -1
|
||||
assertEquals(443, url.port) // getPart(PORT) returns null → -1
|
||||
}
|
||||
}
|
||||
|
||||
+31
@@ -739,6 +739,37 @@ class UriDetectionTest {
|
||||
runTest("blossom:9584b6d64e43747364b10276f4b821e5df09f46477b3b8c60cced3e8c647fbef.jpg?xs=blossom.primal.net", "blossom:9584b6d64e43747364b10276f4b821e5df09f46477b3b8c60cced3e8c647fbef.jpg?xs=blossom.primal.net")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBrokenCaseInProduction() {
|
||||
runTest("今北産業")
|
||||
runTest("http://test.com今北産業", "http://test.com")
|
||||
runTest("ftp://test.com今北産業", "ftp://test.com")
|
||||
runTest("test.com今北産業", "test.com")
|
||||
runTest("wss://test.com今北産業", "wss://test.com")
|
||||
runTest("blossom:test.com今北産業", "blossom:test.com")
|
||||
runTest("nostr:test.com今北産業", "nostr:test.com")
|
||||
runTest("nostr:test今北産業", "nostr:test")
|
||||
runTest("nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m今北産業", "nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m")
|
||||
|
||||
runTest("今北産業http://test.com", "http://test.com")
|
||||
runTest("今北産業ftp://test.com", "ftp://test.com")
|
||||
runTest("今北産業test.com", "test.com")
|
||||
runTest("今北産業wss://test.com", "wss://test.com")
|
||||
runTest("今北産業blossom:test.com", "blossom:test.com")
|
||||
runTest("今北産業nostr:test.com", "nostr:test.com")
|
||||
runTest("今北産業nostr:test", "nostr:test")
|
||||
runTest("今北産業nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m今北産業", "nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m")
|
||||
|
||||
runTest("今北産業http://test.com今北産業", "http://test.com")
|
||||
runTest("今北産業ftp://test.com今北産業", "ftp://test.com")
|
||||
runTest("今北産業test.com今北産業", "test.com")
|
||||
runTest("今北産業wss://test.com今北産業", "wss://test.com")
|
||||
runTest("今北産業blossom:test.com今北産業", "blossom:test.com")
|
||||
runTest("今北産業nostr:test.com今北産業", "nostr:test.com")
|
||||
runTest("今北産業nostr:test今北産業", "nostr:test")
|
||||
runTest("今北産業nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m今北産業", "nostr:nprofile1qqsv0agl52pt4e5pe586fz9vsd5phqz7je49yrcg532h2u5nejsc8gcpzamhxue69uhhxetpwf3kstnwdaejuar0v3shjtcv8453m")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFullText() {
|
||||
val text =
|
||||
|
||||
Reference in New Issue
Block a user