mirror of
https://github.com/thunderbird/thunderbird-android.git
synced 2024-09-20 20:13:04 +02:00
Merge pull request #6878 from thundernest/check_UriParser_startPos_argument
Explicitly check `startPos` parameter in `UriParser.parseUri()` implementations
This commit is contained in:
commit
d407f18b11
@ -9,6 +9,8 @@ import java.util.regex.Pattern
|
|||||||
*/
|
*/
|
||||||
class GenericUriParser : UriParser {
|
class GenericUriParser : UriParser {
|
||||||
override fun parseUri(text: CharSequence, startPos: Int): UriMatch? {
|
override fun parseUri(text: CharSequence, startPos: Int): UriMatch? {
|
||||||
|
require(startPos in text.indices) { "Invalid 'startPos' value" }
|
||||||
|
|
||||||
val matcher = PATTERN.matcher(text)
|
val matcher = PATTERN.matcher(text)
|
||||||
if (!matcher.find(startPos) || matcher.start() != startPos) return null
|
if (!matcher.find(startPos) || matcher.start() != startPos) return null
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@ import kotlin.math.min
|
|||||||
*/
|
*/
|
||||||
internal class HttpUriParser : UriParser {
|
internal class HttpUriParser : UriParser {
|
||||||
override fun parseUri(text: CharSequence, startPos: Int): UriMatch? {
|
override fun parseUri(text: CharSequence, startPos: Int): UriMatch? {
|
||||||
|
require(startPos in text.indices) { "Invalid 'startPos' value" }
|
||||||
|
|
||||||
val matchResult = SCHEME_REGEX.find(text, startPos) ?: return null
|
val matchResult = SCHEME_REGEX.find(text, startPos) ?: return null
|
||||||
if (matchResult.range.first != startPos) return null
|
if (matchResult.range.first != startPos) return null
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
import assertk.assertThat
|
import assertk.assertThat
|
||||||
|
import assertk.assertions.hasMessage
|
||||||
import assertk.assertions.isEqualTo
|
import assertk.assertions.isEqualTo
|
||||||
|
import assertk.assertions.isFailure
|
||||||
|
import assertk.assertions.isInstanceOf
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@ -62,6 +65,24 @@ class GenericUriParserTest {
|
|||||||
assertUriValid("matrix:roomid/rid:example.org/event/lol823y4bcp3qo4?via=example2.org")
|
assertUriValid("matrix:roomid/rid:example.org/event/lol823y4bcp3qo4?via=example2.org")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `negative 'startPos' value`() {
|
||||||
|
assertThat {
|
||||||
|
parser.parseUri("test", -1)
|
||||||
|
}.isFailure()
|
||||||
|
.isInstanceOf(IllegalArgumentException::class)
|
||||||
|
.hasMessage("Invalid 'startPos' value")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `out of bounds 'startPos' value`() {
|
||||||
|
assertThat {
|
||||||
|
parser.parseUri("test", 4)
|
||||||
|
}.isFailure()
|
||||||
|
.isInstanceOf(IllegalArgumentException::class)
|
||||||
|
.hasMessage("Invalid 'startPos' value")
|
||||||
|
}
|
||||||
|
|
||||||
private fun assertUriValid(input: String) {
|
private fun assertUriValid(input: String) {
|
||||||
val result = parser.parseUri(input, 0)
|
val result = parser.parseUri(input, 0)
|
||||||
|
|
||||||
|
@ -1,312 +0,0 @@
|
|||||||
package com.fsck.k9.message.html;
|
|
||||||
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
|
|
||||||
public class HttpUriParserTest {
|
|
||||||
private final HttpUriParser parser = new HttpUriParser();
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void emptyUriIgnored() {
|
|
||||||
assertInvalidUri("http://");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void emptyAuthorityIgnored() {
|
|
||||||
assertInvalidUri("http:///");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void simpleDomain() {
|
|
||||||
assertValidUri("http://www.google.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void simpleDomainWithHttps() {
|
|
||||||
assertValidUri("https://www.google.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void simpleRtspUri() {
|
|
||||||
assertValidUri("rtsp://example.com/media.mp4");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void invalidDomainIgnored() {
|
|
||||||
assertInvalidUri("http://-www.google.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithTrailingSlash() {
|
|
||||||
assertValidUri("http://www.google.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithUserInfo() {
|
|
||||||
assertValidUri("http://test@google.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithFullUserInfo() {
|
|
||||||
assertValidUri("http://test:secret@google.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithoutWww() {
|
|
||||||
assertValidUri("http://google.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void query() {
|
|
||||||
assertValidUri("http://google.com/give/me/?q=mode&c=information");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fragment() {
|
|
||||||
assertValidUri("http://google.com/give/me#only-the-best");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void queryAndFragment() {
|
|
||||||
assertValidUri("http://google.com/give/me/?q=mode&c=information#only-the-best");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv4Address() {
|
|
||||||
assertValidUri("http://127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv4AddressWithTrailingSlash() {
|
|
||||||
assertValidUri("http://127.0.0.1/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv4AddressWithEmptyPort() {
|
|
||||||
assertValidUri("http://127.0.0.1:");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv4AddressWithPort() {
|
|
||||||
assertValidUri("http://127.0.0.1:524/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6Address() {
|
|
||||||
assertValidUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithPort() {
|
|
||||||
assertValidUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithTrailingSlash() {
|
|
||||||
assertValidUri("http://[1080:0:0:0:8:800:200C:417A]/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithEndCompression() {
|
|
||||||
assertValidUri("http://[3ffe:2a00:100:7031::1]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithBeginCompression() {
|
|
||||||
assertValidUri("http://[1080::8:800:200C:417A]/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithCompressionPort() {
|
|
||||||
assertValidUri("http://[::FFFF:129.144.52.38]:80/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithPrependedCompression() {
|
|
||||||
assertValidUri("http://[::192.9.5.5]/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6AddressWithTrailingIp4AndPort() {
|
|
||||||
assertValidUri("http://[::192.9.5.5]:80/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6WithoutClosingSquareBracketIgnored() {
|
|
||||||
assertInvalidUri("http://[1080:0:0:0:8:80:200C:417A/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ipv6InvalidClosingSquareBracketIgnored() {
|
|
||||||
assertInvalidUri("http://[1080:0:0:0:8:800:270C:417A/]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithTrailingSpace() {
|
|
||||||
String text = "http://google.com/ ";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(text, 0);
|
|
||||||
|
|
||||||
assertUriMatch("http://google.com/", uriMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithTrailingNewline() {
|
|
||||||
String text = "http://google.com/\n";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(text, 0);
|
|
||||||
|
|
||||||
assertUriMatch("http://google.com/", uriMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void domainWithTrailingAngleBracket() {
|
|
||||||
String text = "<http://google.com/>";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(text, 1);
|
|
||||||
|
|
||||||
assertUriMatch("http://google.com/", uriMatch, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriInMiddleAfterInput() {
|
|
||||||
String prefix = "prefix ";
|
|
||||||
String uri = "http://google.com/";
|
|
||||||
String text = prefix + uri;
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(text, prefix.length());
|
|
||||||
|
|
||||||
assertUriMatch("http://google.com/", uriMatch, prefix.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriInMiddleOfInput() {
|
|
||||||
String prefix = "prefix ";
|
|
||||||
String uri = "http://google.com/";
|
|
||||||
String postfix = " postfix";
|
|
||||||
String text = prefix + uri + postfix;
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(text, prefix.length());
|
|
||||||
|
|
||||||
assertUriMatch("http://google.com/", uriMatch, prefix.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInParentheses() {
|
|
||||||
String input = "(https://domain.example/)";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 1);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/", uriMatch, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriContainingParentheses() {
|
|
||||||
String input = "https://domain.example/(parentheses)";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 0);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/(parentheses)", uriMatch, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriContainingParenthesesWrappedInParentheses() {
|
|
||||||
String input = "(https://domain.example/(parentheses))";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 1);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/(parentheses)", uriMatch, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriEndingInDotAtEndOfText() {
|
|
||||||
String input = "URL: https://domain.example/path.";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 5);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path", uriMatch, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriEndingInDotWithAdditionalText() {
|
|
||||||
String input = "URL: https://domain.example/path. Some other text";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 5);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path", uriMatch, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInAngleBracketsEndingInDot() {
|
|
||||||
String input = "URL: <https://domain.example/path.>";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 6);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path.", uriMatch, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInParenthesesEndingInDot() {
|
|
||||||
String input = "URL: (https://domain.example/path.)";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 6);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path.", uriMatch, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInParenthesesFollowedByADot() {
|
|
||||||
String input = "URL: (https://domain.example/path).";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 6);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path", uriMatch, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInParenthesesFollowedByADotAndSomeOtherText() {
|
|
||||||
String input = "URL: (https://domain.example/path). Some other text";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 6);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path", uriMatch, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void uriWrappedInParenthesesFollowedByAQuestionMarkAndSomeOtherText() {
|
|
||||||
String input = "URL: (https://domain.example/path)? Some other text";
|
|
||||||
|
|
||||||
UriMatch uriMatch = parser.parseUri(input, 6);
|
|
||||||
|
|
||||||
assertUriMatch("https://domain.example/path", uriMatch, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void assertValidUri(String uri) {
|
|
||||||
UriMatch uriMatch = parser.parseUri(uri, 0);
|
|
||||||
assertUriMatch(uri, uriMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertUriMatch(String uri, UriMatch uriMatch) {
|
|
||||||
assertUriMatch(uri, uriMatch, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertUriMatch(String uri, UriMatch uriMatch, int offset) {
|
|
||||||
assertNotNull(uriMatch);
|
|
||||||
Assert.assertEquals(offset, uriMatch.getStartIndex());
|
|
||||||
Assert.assertEquals(uri.length() + offset, uriMatch.getEndIndex());
|
|
||||||
Assert.assertEquals(uri, uriMatch.getUri().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertInvalidUri(String uri) {
|
|
||||||
UriMatch uriMatch = parser.parseUri(uri, 0);
|
|
||||||
assertNull(uriMatch);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,326 @@
|
|||||||
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
|
import assertk.assertThat
|
||||||
|
import assertk.assertions.hasMessage
|
||||||
|
import assertk.assertions.isEqualTo
|
||||||
|
import assertk.assertions.isFailure
|
||||||
|
import assertk.assertions.isInstanceOf
|
||||||
|
import assertk.assertions.isNotNull
|
||||||
|
import assertk.assertions.isNull
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class HttpUriParserTest {
|
||||||
|
private val parser = HttpUriParser()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `missing domain`() {
|
||||||
|
assertInvalidUri("http://")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `missing domain followed by slash`() {
|
||||||
|
assertInvalidUri("http:///")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `simple domain`() {
|
||||||
|
assertValidUri("http://www.google.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `simple domain with https`() {
|
||||||
|
assertValidUri("https://www.google.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `simple RTSP URI`() {
|
||||||
|
assertValidUri("rtsp://example.com/media.mp4")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `subdomain starting with invalid character`() {
|
||||||
|
assertInvalidUri("http://-www.google.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with trailing slash`() {
|
||||||
|
assertValidUri("http://www.google.com/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with user info`() {
|
||||||
|
assertValidUri("http://test@google.com/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with full user info`() {
|
||||||
|
assertValidUri("http://test:secret@google.com/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain without www`() {
|
||||||
|
assertValidUri("http://google.com/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun query() {
|
||||||
|
assertValidUri("http://google.com/give/me/?q=mode&c=information")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fragment() {
|
||||||
|
assertValidUri("http://google.com/give/me#only-the-best")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `query and fragment`() {
|
||||||
|
assertValidUri("http://google.com/give/me/?q=mode&c=information#only-the-best")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv4 address`() {
|
||||||
|
assertValidUri("http://127.0.0.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv4 address with trailing slash`() {
|
||||||
|
assertValidUri("http://127.0.0.1/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv4 address with empty port`() {
|
||||||
|
assertValidUri("http://127.0.0.1:")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv4 address with port`() {
|
||||||
|
assertValidUri("http://127.0.0.1:524/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address`() {
|
||||||
|
assertValidUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with port`() {
|
||||||
|
assertValidUri("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with trailing slash`() {
|
||||||
|
assertValidUri("http://[1080:0:0:0:8:800:200C:417A]/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with end compression`() {
|
||||||
|
assertValidUri("http://[3ffe:2a00:100:7031::1]")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with begin compression`() {
|
||||||
|
assertValidUri("http://[1080::8:800:200C:417A]/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with compression port`() {
|
||||||
|
assertValidUri("http://[::FFFF:129.144.52.38]:80/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with prepended compression`() {
|
||||||
|
assertValidUri("http://[::192.9.5.5]/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 address with trailing IP4 and port`() {
|
||||||
|
assertValidUri("http://[::192.9.5.5]:80/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 without closing square bracket`() {
|
||||||
|
assertInvalidUri("http://[1080:0:0:0:8:80:200C:417A/")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IPv6 invalid closing square bracket`() {
|
||||||
|
assertInvalidUri("http://[1080:0:0:0:8:800:270C:417A/]")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with trailing space`() {
|
||||||
|
val text = "http://google.com/ "
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(text, 0)
|
||||||
|
|
||||||
|
assertUriMatch("http://google.com/", uriMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with trailing newline`() {
|
||||||
|
val text = "http://google.com/\n"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(text, 0)
|
||||||
|
|
||||||
|
assertUriMatch("http://google.com/", uriMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `domain with trailing angle bracket`() {
|
||||||
|
val text = "<http://google.com/>"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(text, 1)
|
||||||
|
|
||||||
|
assertUriMatch("http://google.com/", uriMatch, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI at the end of input`() {
|
||||||
|
val prefix = "prefix "
|
||||||
|
val uri = "http://google.com/"
|
||||||
|
val text = prefix + uri
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(text, prefix.length)
|
||||||
|
|
||||||
|
assertUriMatch("http://google.com/", uriMatch, prefix.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI in middle of input`() {
|
||||||
|
val prefix = "prefix "
|
||||||
|
val uri = "http://google.com/"
|
||||||
|
val postfix = " postfix"
|
||||||
|
val text = prefix + uri + postfix
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(text, prefix.length)
|
||||||
|
|
||||||
|
assertUriMatch("http://google.com/", uriMatch, prefix.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in parentheses`() {
|
||||||
|
val input = "(https://domain.example/)"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 1)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/", uriMatch, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI containing parentheses`() {
|
||||||
|
val input = "https://domain.example/(parentheses)"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 0)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/(parentheses)", uriMatch, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI containing parentheses wrapped in parentheses`() {
|
||||||
|
val input = "(https://domain.example/(parentheses))"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 1)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/(parentheses)", uriMatch, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI ending in dot at end of text`() {
|
||||||
|
val input = "URL: https://domain.example/path."
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 5)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path", uriMatch, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI ending in dot with additional text`() {
|
||||||
|
val input = "URL: https://domain.example/path. Some other text"
|
||||||
|
val uriMatch = parser.parseUri(input, 5)
|
||||||
|
assertUriMatch("https://domain.example/path", uriMatch, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in angle brackets ending in dot`() {
|
||||||
|
val input = "URL: <https://domain.example/path.>"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 6)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path.", uriMatch, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in parentheses ending in dot`() {
|
||||||
|
val input = "URL: (https://domain.example/path.)"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 6)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path.", uriMatch, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in parentheses followed by a dot`() {
|
||||||
|
val input = "URL: (https://domain.example/path)."
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 6)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path", uriMatch, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in parentheses followed by a dot and some other text`() {
|
||||||
|
val input = "URL: (https://domain.example/path). Some other text"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 6)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path", uriMatch, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `URI wrapped in parentheses followed by a question mark and some other text`() {
|
||||||
|
val input = "URL: (https://domain.example/path)? Some other text"
|
||||||
|
|
||||||
|
val uriMatch = parser.parseUri(input, 6)
|
||||||
|
|
||||||
|
assertUriMatch("https://domain.example/path", uriMatch, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `negative 'startPos' value`() {
|
||||||
|
assertThat {
|
||||||
|
parser.parseUri("test", -1)
|
||||||
|
}.isFailure()
|
||||||
|
.isInstanceOf(IllegalArgumentException::class)
|
||||||
|
.hasMessage("Invalid 'startPos' value")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `out of bounds 'startPos' value`() {
|
||||||
|
assertThat {
|
||||||
|
parser.parseUri("test", 4)
|
||||||
|
}.isFailure()
|
||||||
|
.isInstanceOf(IllegalArgumentException::class)
|
||||||
|
.hasMessage("Invalid 'startPos' value")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertValidUri(uri: String) {
|
||||||
|
val uriMatch = parser.parseUri(uri, 0)
|
||||||
|
|
||||||
|
assertUriMatch(uri, uriMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertUriMatch(uri: String, uriMatch: UriMatch?, offset: Int = 0) {
|
||||||
|
assertThat(uriMatch).isNotNull().isEqualTo(
|
||||||
|
UriMatch(
|
||||||
|
startIndex = offset,
|
||||||
|
endIndex = offset + uri.length,
|
||||||
|
uri = uri,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertInvalidUri(uri: String) {
|
||||||
|
val uriMatch = parser.parseUri(uri, 0)
|
||||||
|
assertThat(uriMatch).isNull()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user