Loading adb/adb.cpp +19 −18 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include "adb_auth.h" #include "adb_io.h" #include "adb_listeners.h" #include "adb_utils.h" #include "transport.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) Loading Loading @@ -896,28 +897,28 @@ int handle_host_request(const char* service, TransportType type, // remove TCP transport if (!strncmp(service, "disconnect:", 11)) { char buffer[4096]; memset(buffer, 0, sizeof(buffer)); const char* serial = service + 11; if (serial[0] == 0) { const std::string address(service + 11); if (address.empty()) { // disconnect from all TCP devices unregister_all_tcp_transports(); } else { char hostbuf[100]; // assume port 5555 if no port is specified if (!strchr(serial, ':')) { snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); serial = hostbuf; } atransport* t = find_transport(serial); if (t) { unregister_transport(t); } else { snprintf(buffer, sizeof(buffer), "No such device %s", serial); } return SendOkay(reply_fd, "disconnected everything"); } return SendOkay(reply_fd, buffer); std::string serial; std::string host; int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; std::string error; if (!parse_host_and_port(address, &serial, &host, &port, &error)) { return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s", address.c_str(), error.c_str())); } atransport* t = find_transport(serial.c_str()); if (t == nullptr) { return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", serial.c_str())); } unregister_transport(t); return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str())); } // returns our value for ADB_SERVER_VERSION Loading adb/adb_client.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -277,8 +277,7 @@ bool adb_query(const std::string& service, std::string* result, std::string* err D("adb_query: %s\n", service.c_str()); int fd = adb_connect(service, error); if (fd < 0) { fprintf(stderr,"error: %s\n", error->c_str()); return 0; return false; } result->clear(); Loading adb/adb_utils.cpp +55 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ #include <algorithm> #include <base/logging.h> #include <base/stringprintf.h> #include <base/strings.h> #include "adb_trace.h" #include "sysdeps.h" Loading Loading @@ -103,3 +105,56 @@ void dump_hex(const void* data, size_t byte_count) { DR("%s\n", line.c_str()); } bool parse_host_and_port(const std::string& address, std::string* canonical_address, std::string* host, int* port, std::string* error) { host->clear(); bool ipv6 = true; bool saw_port = false; size_t colons = std::count(address.begin(), address.end(), ':'); size_t dots = std::count(address.begin(), address.end(), '.'); std::string port_str; if (address[0] == '[') { // [::1]:123 if (address.rfind("]:") == std::string::npos) { *error = android::base::StringPrintf("bad IPv6 address '%s'", address.c_str()); return false; } *host = address.substr(1, (address.find("]:") - 1)); port_str = address.substr(address.rfind("]:") + 2); saw_port = true; } else if (dots == 0 && colons >= 2 && colons <= 7) { // ::1 *host = address; } else if (colons <= 1) { // 1.2.3.4 or some.accidental.domain.com ipv6 = false; std::vector<std::string> pieces = android::base::Split(address, ":"); *host = pieces[0]; if (pieces.size() > 1) { port_str = pieces[1]; saw_port = true; } } if (host->empty()) { *error = android::base::StringPrintf("no host in '%s'", address.c_str()); return false; } if (saw_port) { if (sscanf(port_str.c_str(), "%d", port) != 1 || *port <= 0 || *port > 65535) { *error = android::base::StringPrintf("bad port number '%s' in '%s'", port_str.c_str(), address.c_str()); return false; } } *canonical_address = android::base::StringPrintf(ipv6 ? "[%s]:%d" : "%s:%d", host->c_str(), *port); LOG(DEBUG) << "parsed " << address << " as " << *host << " and " << *port << " (" << *canonical_address << ")"; return true; } adb/adb_utils.h +11 −0 Original line number Diff line number Diff line Loading @@ -28,4 +28,15 @@ std::string escape_arg(const std::string& s); void dump_hex(const void* ptr, size_t byte_count); // Parses 'address' into 'host' and 'port'. // If no port is given, takes the default from *port. // 'canonical_address' then becomes "host:port" or "[host]:port" as appropriate. // Note that no real checking is done that 'host' or 'port' is valid; that's // left to getaddrinfo(3). // Returns false on failure and sets *error to an appropriate message. bool parse_host_and_port(const std::string& address, std::string* canonical_address, std::string* host, int* port, std::string* error); #endif adb/adb_utils_test.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -50,3 +50,85 @@ TEST(adb_utils, escape_arg) { ASSERT_EQ(R"('abc(')", escape_arg("abc(")); ASSERT_EQ(R"('abc)')", escape_arg("abc)")); } TEST(adb_utils, parse_host_and_port) { std::string canonical_address; std::string host; int port; std::string error; // Name, default port. port = 123; ASSERT_TRUE(parse_host_and_port("www.google.com", &canonical_address, &host, &port, &error)); ASSERT_EQ("www.google.com:123", canonical_address); ASSERT_EQ("www.google.com", host); ASSERT_EQ(123, port); // Name, explicit port. ASSERT_TRUE(parse_host_and_port("www.google.com:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("www.google.com:666", canonical_address); ASSERT_EQ("www.google.com", host); ASSERT_EQ(666, port); // IPv4, default port. port = 123; ASSERT_TRUE(parse_host_and_port("1.2.3.4", &canonical_address, &host, &port, &error)); ASSERT_EQ("1.2.3.4:123", canonical_address); ASSERT_EQ("1.2.3.4", host); ASSERT_EQ(123, port); // IPv4, explicit port. ASSERT_TRUE(parse_host_and_port("1.2.3.4:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("1.2.3.4:666", canonical_address); ASSERT_EQ("1.2.3.4", host); ASSERT_EQ(666, port); // Simple IPv6, default port. port = 123; ASSERT_TRUE(parse_host_and_port("::1", &canonical_address, &host, &port, &error)); ASSERT_EQ("[::1]:123", canonical_address); ASSERT_EQ("::1", host); ASSERT_EQ(123, port); // Simple IPv6, explicit port. ASSERT_TRUE(parse_host_and_port("[::1]:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("[::1]:666", canonical_address); ASSERT_EQ("::1", host); ASSERT_EQ(666, port); // Hairy IPv6, default port. port = 123; ASSERT_TRUE(parse_host_and_port("fe80::200:5aee:feaa:20a2", &canonical_address, &host, &port, &error)); ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:123", canonical_address); ASSERT_EQ("fe80::200:5aee:feaa:20a2", host); ASSERT_EQ(123, port); // Simple IPv6, explicit port. ASSERT_TRUE(parse_host_and_port("[fe80::200:5aee:feaa:20a2]:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:666", canonical_address); ASSERT_EQ("fe80::200:5aee:feaa:20a2", host); ASSERT_EQ(666, port); // Invalid IPv4. EXPECT_FALSE(parse_host_and_port("1.2.3.4:", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4::", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:hello", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port(":123", &canonical_address, &host, &port, &error)); // Invalid IPv6. EXPECT_FALSE(parse_host_and_port(":1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("::::::::1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]::", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:hello", &canonical_address, &host, &port, &error)); // Invalid ports. EXPECT_FALSE(parse_host_and_port("[::1]:-1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:0", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:65536", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:-1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:0", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:65536", &canonical_address, &host, &port, &error)); } Loading
adb/adb.cpp +19 −18 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include "adb_auth.h" #include "adb_io.h" #include "adb_listeners.h" #include "adb_utils.h" #include "transport.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) Loading Loading @@ -896,28 +897,28 @@ int handle_host_request(const char* service, TransportType type, // remove TCP transport if (!strncmp(service, "disconnect:", 11)) { char buffer[4096]; memset(buffer, 0, sizeof(buffer)); const char* serial = service + 11; if (serial[0] == 0) { const std::string address(service + 11); if (address.empty()) { // disconnect from all TCP devices unregister_all_tcp_transports(); } else { char hostbuf[100]; // assume port 5555 if no port is specified if (!strchr(serial, ':')) { snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); serial = hostbuf; } atransport* t = find_transport(serial); if (t) { unregister_transport(t); } else { snprintf(buffer, sizeof(buffer), "No such device %s", serial); } return SendOkay(reply_fd, "disconnected everything"); } return SendOkay(reply_fd, buffer); std::string serial; std::string host; int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; std::string error; if (!parse_host_and_port(address, &serial, &host, &port, &error)) { return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s", address.c_str(), error.c_str())); } atransport* t = find_transport(serial.c_str()); if (t == nullptr) { return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", serial.c_str())); } unregister_transport(t); return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str())); } // returns our value for ADB_SERVER_VERSION Loading
adb/adb_client.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -277,8 +277,7 @@ bool adb_query(const std::string& service, std::string* result, std::string* err D("adb_query: %s\n", service.c_str()); int fd = adb_connect(service, error); if (fd < 0) { fprintf(stderr,"error: %s\n", error->c_str()); return 0; return false; } result->clear(); Loading
adb/adb_utils.cpp +55 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ #include <algorithm> #include <base/logging.h> #include <base/stringprintf.h> #include <base/strings.h> #include "adb_trace.h" #include "sysdeps.h" Loading Loading @@ -103,3 +105,56 @@ void dump_hex(const void* data, size_t byte_count) { DR("%s\n", line.c_str()); } bool parse_host_and_port(const std::string& address, std::string* canonical_address, std::string* host, int* port, std::string* error) { host->clear(); bool ipv6 = true; bool saw_port = false; size_t colons = std::count(address.begin(), address.end(), ':'); size_t dots = std::count(address.begin(), address.end(), '.'); std::string port_str; if (address[0] == '[') { // [::1]:123 if (address.rfind("]:") == std::string::npos) { *error = android::base::StringPrintf("bad IPv6 address '%s'", address.c_str()); return false; } *host = address.substr(1, (address.find("]:") - 1)); port_str = address.substr(address.rfind("]:") + 2); saw_port = true; } else if (dots == 0 && colons >= 2 && colons <= 7) { // ::1 *host = address; } else if (colons <= 1) { // 1.2.3.4 or some.accidental.domain.com ipv6 = false; std::vector<std::string> pieces = android::base::Split(address, ":"); *host = pieces[0]; if (pieces.size() > 1) { port_str = pieces[1]; saw_port = true; } } if (host->empty()) { *error = android::base::StringPrintf("no host in '%s'", address.c_str()); return false; } if (saw_port) { if (sscanf(port_str.c_str(), "%d", port) != 1 || *port <= 0 || *port > 65535) { *error = android::base::StringPrintf("bad port number '%s' in '%s'", port_str.c_str(), address.c_str()); return false; } } *canonical_address = android::base::StringPrintf(ipv6 ? "[%s]:%d" : "%s:%d", host->c_str(), *port); LOG(DEBUG) << "parsed " << address << " as " << *host << " and " << *port << " (" << *canonical_address << ")"; return true; }
adb/adb_utils.h +11 −0 Original line number Diff line number Diff line Loading @@ -28,4 +28,15 @@ std::string escape_arg(const std::string& s); void dump_hex(const void* ptr, size_t byte_count); // Parses 'address' into 'host' and 'port'. // If no port is given, takes the default from *port. // 'canonical_address' then becomes "host:port" or "[host]:port" as appropriate. // Note that no real checking is done that 'host' or 'port' is valid; that's // left to getaddrinfo(3). // Returns false on failure and sets *error to an appropriate message. bool parse_host_and_port(const std::string& address, std::string* canonical_address, std::string* host, int* port, std::string* error); #endif
adb/adb_utils_test.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -50,3 +50,85 @@ TEST(adb_utils, escape_arg) { ASSERT_EQ(R"('abc(')", escape_arg("abc(")); ASSERT_EQ(R"('abc)')", escape_arg("abc)")); } TEST(adb_utils, parse_host_and_port) { std::string canonical_address; std::string host; int port; std::string error; // Name, default port. port = 123; ASSERT_TRUE(parse_host_and_port("www.google.com", &canonical_address, &host, &port, &error)); ASSERT_EQ("www.google.com:123", canonical_address); ASSERT_EQ("www.google.com", host); ASSERT_EQ(123, port); // Name, explicit port. ASSERT_TRUE(parse_host_and_port("www.google.com:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("www.google.com:666", canonical_address); ASSERT_EQ("www.google.com", host); ASSERT_EQ(666, port); // IPv4, default port. port = 123; ASSERT_TRUE(parse_host_and_port("1.2.3.4", &canonical_address, &host, &port, &error)); ASSERT_EQ("1.2.3.4:123", canonical_address); ASSERT_EQ("1.2.3.4", host); ASSERT_EQ(123, port); // IPv4, explicit port. ASSERT_TRUE(parse_host_and_port("1.2.3.4:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("1.2.3.4:666", canonical_address); ASSERT_EQ("1.2.3.4", host); ASSERT_EQ(666, port); // Simple IPv6, default port. port = 123; ASSERT_TRUE(parse_host_and_port("::1", &canonical_address, &host, &port, &error)); ASSERT_EQ("[::1]:123", canonical_address); ASSERT_EQ("::1", host); ASSERT_EQ(123, port); // Simple IPv6, explicit port. ASSERT_TRUE(parse_host_and_port("[::1]:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("[::1]:666", canonical_address); ASSERT_EQ("::1", host); ASSERT_EQ(666, port); // Hairy IPv6, default port. port = 123; ASSERT_TRUE(parse_host_and_port("fe80::200:5aee:feaa:20a2", &canonical_address, &host, &port, &error)); ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:123", canonical_address); ASSERT_EQ("fe80::200:5aee:feaa:20a2", host); ASSERT_EQ(123, port); // Simple IPv6, explicit port. ASSERT_TRUE(parse_host_and_port("[fe80::200:5aee:feaa:20a2]:666", &canonical_address, &host, &port, &error)); ASSERT_EQ("[fe80::200:5aee:feaa:20a2]:666", canonical_address); ASSERT_EQ("fe80::200:5aee:feaa:20a2", host); ASSERT_EQ(666, port); // Invalid IPv4. EXPECT_FALSE(parse_host_and_port("1.2.3.4:", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4::", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:hello", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port(":123", &canonical_address, &host, &port, &error)); // Invalid IPv6. EXPECT_FALSE(parse_host_and_port(":1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("::::::::1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]::", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:hello", &canonical_address, &host, &port, &error)); // Invalid ports. EXPECT_FALSE(parse_host_and_port("[::1]:-1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:0", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("[::1]:65536", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:-1", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:0", &canonical_address, &host, &port, &error)); EXPECT_FALSE(parse_host_and_port("1.2.3.4:65536", &canonical_address, &host, &port, &error)); }