Merge "adb: fix host-side serial number parsing for IPv6." am: b1c4d90215 am: 94c652ed31 am: dde69001c2
am: 5cab7cc637
Change-Id: I425b06ae91e657647878350319a242052c9959f2
diff --git a/adb/socket_test.cpp b/adb/socket_test.cpp
index 2bb01a3..5e79b5e 100644
--- a/adb/socket_test.cpp
+++ b/adb/socket_test.cpp
@@ -307,6 +307,17 @@
// Don't register a port unless it's all numbers and ends with ':'.
VerifySkipHostSerial(protocol + "foo:123", ":123");
VerifySkipHostSerial(protocol + "foo:123bar:baz", ":123bar:baz");
+
+ VerifySkipHostSerial(protocol + "100.100.100.100:5555:foo", ":foo");
+ VerifySkipHostSerial(protocol + "[0123:4567:89ab:CDEF:0:9:a:f]:5555:foo", ":foo");
+ VerifySkipHostSerial(protocol + "[::1]:5555:foo", ":foo");
+
+ // If we can't find both [] then treat it as a normal serial with [ in it.
+ VerifySkipHostSerial(protocol + "[0123:foo", ":foo");
+
+ // Don't be fooled by random IPv6 addresses in the command string.
+ VerifySkipHostSerial(protocol + "foo:ping [0123:4567:89ab:CDEF:0:9:a:f]:5555",
+ ":ping [0123:4567:89ab:CDEF:0:9:a:f]:5555");
}
}
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 503e018..b809c4f 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -622,21 +622,32 @@
service += 4;
}
- char* first_colon = strchr(service, ':');
- if (!first_colon) {
+ // Check for an IPv6 address. `adb connect` creates the serial number from the canonical
+ // network address so it will always have the [] delimiters.
+ if (service[0] == '[') {
+ char* ipv6_end = strchr(service, ']');
+ if (ipv6_end != nullptr) {
+ service = ipv6_end;
+ }
+ }
+
+ // The next colon we find must either begin the port field or the command field.
+ char* colon_ptr = strchr(service, ':');
+ if (!colon_ptr) {
// No colon in service string.
return nullptr;
}
- char* serial_end = first_colon;
+ // If the next field is only decimal digits and ends with another colon, it's a port.
+ char* serial_end = colon_ptr;
if (isdigit(serial_end[1])) {
serial_end++;
while (*serial_end && isdigit(*serial_end)) {
serial_end++;
}
if (*serial_end != ':') {
- // Something other than numbers was found, reset the end.
- serial_end = first_colon;
+ // Something other than "<port>:" was found, this must be the command field instead.
+ serial_end = colon_ptr;
}
}
return serial_end;