From bfa69dce01c7fe5ddfc8901616da5fe98d33817c Mon Sep 17 00:00:00 2001 From: mcarare Date: Mon, 21 Feb 2022 15:57:25 +0200 Subject: [PATCH] [fenix] For https://github.com/mozilla-mobile/fenix/issues/21743: Use isNumericAddress to validate Ipv4 and Ipv6 for SDK>=29. --- .../src/main/java/org/mozilla/fenix/ext/String.kt | 32 +++++++++++++++++----- .../test/java/org/mozilla/fenix/ext/StringTest.kt | 22 +++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/String.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/String.kt index c01e4db5a208..1608218fcc71 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/String.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/String.kt @@ -4,7 +4,8 @@ package org.mozilla.fenix.ext -import android.net.Uri +import android.net.InetAddresses +import android.os.Build import android.text.Editable import android.util.Patterns import android.webkit.URLUtil @@ -44,8 +45,7 @@ fun String.toShortUrl(publicSuffixList: PublicSuffixList): String { return inputString } - if (uri.host?.isIpv4() == true || - uri.isIpv6() || + if (uri.host?.isIpv4OrIpv6() == true || // If inputString is just a hostname and not a FQDN, use the entire hostname. uri.host?.contains(".") == false ) { @@ -73,13 +73,25 @@ fun String.toShortUrl(publicSuffixList: PublicSuffixList): String { // impl via FFTV https://searchfox.org/mozilla-mobile/source/firefox-echo-show/app/src/main/java/org/mozilla/focus/utils/FormattedDomain.java#129 @Suppress("DEPRECATION") -fun String.isIpv4(): Boolean = Patterns.IP_ADDRESS.matcher(this).matches() +internal fun String.isIpv4(): Boolean = Patterns.IP_ADDRESS.matcher(this).matches() // impl via FFiOS: https://github.com/mozilla-mobile/firefox-ios/blob/deb9736c905cdf06822ecc4a20152df7b342925d/Shared/Extensions/NSURLExtensions.swift#L292 // True IPv6 validation is difficult. This is slightly better than nothing -private fun Uri.isIpv6(): Boolean { - val host = this.host ?: return false - return host.isNotEmpty() && host.contains(":") +internal fun String.isIpv6(): Boolean { + return this.isNotEmpty() && this.contains(":") +} + +/** + * Returns true if the string represents a valid Ipv4 or Ipv6 IP address. + * Note: does not validate a dual format Ipv6 ( "y:y:y:y:y:y:x.x.x.x" format). + * + */ +fun String.isIpv4OrIpv6(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + InetAddresses.isNumericAddress(this) + } else { + this.isIpv4() || this.isIpv6() + } } /** @@ -103,3 +115,9 @@ fun String.simplifiedUrl(): String { * Returns an [Editable] for the provided string. */ fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this) + +/** + * Returns a Ipv6 address with consecutive sections of zeroes replaced with a double colon. + */ +fun String?.replaceConsecutiveZeros(): String? = + this?.replaceFirst(":0", ":")?.replace(":0", "") diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/ext/StringTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/ext/StringTest.kt index 751f23491f00..eb3b18ca14aa 100644 --- a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/ext/StringTest.kt +++ b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/ext/StringTest.kt @@ -225,9 +225,31 @@ class StringTest { assertFalse("2001:db8::1 ".isIpv4()) assertFalse("2001:db8:0:1:1:1:1:1".isIpv4()) assertFalse("[2001:db8:a0b:12f0::1]".isIpv4()) + assertFalse("2001:db8: 3333:4444:5555:6666:1.2.3.4".isIpv4()) + } + + @Test + fun testIsIPv6WithIPv6() { + assertTrue("2001:db8::1".isIpv6()) + assertTrue("2001:db8:0:1:1:1:1:1".isIpv6()) + } + + @Test + fun testIsIPv6WithIPv4() { + assertFalse("192.168.1.1".isIpv6()) + assertFalse("8.8.8.8".isIpv6()) + assertFalse("63.245.215.20".isIpv6()) } // END test cases borrowed from FFTV + @Test + fun testReplaceConsecutiveZeros() { + assertEquals( + "2001:db8::ff00:42:8329", + "2001:db8:0:0:0:ff00:42:8329".replaceConsecutiveZeros() + ) + } + private infix fun String.shortenedShouldBecome(expect: String) { assertEquals(expect, this.shortened()) } -- 2.11.4.GIT