Skip to content

Commit

Permalink
Fix IPv6 validation on Android < 29
Browse files Browse the repository at this point in the history
  • Loading branch information
emanuele-f committed Jun 13, 2023
1 parent e357534 commit 4e96623
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
76 changes: 75 additions & 1 deletion app/src/main/java/com/emanuelef/remote_capture/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,80 @@ public static boolean validatePort(String value) {
}
}

// from bouncycastle
private static boolean isValidIPv6(String address) {
if (address.length() == 0)
return false;

char firstChar = address.charAt(0);
if (firstChar != ':' && Character.digit(firstChar, 16) < 0)
return false;

int segmentCount = 0;
String temp = address + ":";
boolean doubleColonFound = false;

int pos = 0, end;
while (pos < temp.length() && (end = temp.indexOf(':', pos)) >= pos) {
if (segmentCount == 8)
return false;

if (pos != end) {
String value = temp.substring(pos, end);

if (end == temp.length() - 1 && value.indexOf('.') > 0) {
// add an extra one as address covers 2 words.
if (++segmentCount == 8)
return false;
if (!validateIpv4Address(value))
return false;
}
else if (!isParseableIPv6Segment(temp, pos, end))
return false;
} else {
if (end != 1 && end != temp.length() - 1 && doubleColonFound)
return false;
doubleColonFound = true;
}

pos = end + 1;
++segmentCount;
}

return segmentCount == 8 || doubleColonFound;
}

private static boolean isParseableIPv6Segment(String s, int pos, int end) {
return isParseable(s, pos, end, 16, 4, true, 0x0000, 0xFFFF);
}

private static boolean isParseable(String s, int pos, int end, int radix,
int maxLength, boolean allowLeadingZero,
int minValue, int maxValue) {
int length = end - pos;
if (length < 1 | length > maxLength)
return false;

boolean checkLeadingZero = length > 1 & !allowLeadingZero;
if (checkLeadingZero && Character.digit(s.charAt(pos), radix) <= 0)
return false;

int value = 0;
while (pos < end) {
char c = s.charAt(pos++);
int d = Character.digit(c, radix);
if (d < 0)
{
return false;
}

value *= radix;
value += d;
}

return value >= minValue & value <= maxValue;
}

@SuppressWarnings("deprecation")
public static boolean validateIpAddress(String value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
Expand All @@ -1526,7 +1600,7 @@ public static boolean validateIpv4Address(String s) {
}

public static boolean validateIpv6Address(String s) {
return validateIpAddress(s) && !validateIpv4Address(s);
return isValidIPv6(s) && !validateIpv4Address(s);
}

// rough validation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S
p1.setOnPreferenceChangeListener((preference, newValue) -> Utils.validateIpv4Address(newValue.toString()));

EditTextPreference p2 = Objects.requireNonNull(findPreference(Prefs.PREF_DNS_SERVER_V6));
p2.setOnPreferenceChangeListener((preference, newValue) -> Utils.validateIpv6Address(newValue.toString()));
p2.setOnPreferenceChangeListener((preference, newValue) -> {
String ip = newValue.toString();
return !ip.equals("::") && Utils.validateIpv6Address(ip);
});
}
}

0 comments on commit 4e96623

Please sign in to comment.