@@ -2163,29 +2163,57 @@ void GetServers(const FunctionCallbackInfo<Value>& args) {
21632163 std::string entry = servers_str.substr (pos, comma - pos);
21642164 pos = comma + 1 ;
21652165
2166+ // Trim whitespace just in case c-ares somehow adds it
2167+ size_t first = entry.find_first_not_of (" \t\r\n " );
2168+ if (first == std::string::npos) continue ;
2169+ size_t last = entry.find_last_not_of (" \t\r\n " );
2170+ entry = entry.substr (first, (last - first + 1 ));
2171+ if (entry.empty ()) continue ;
2172+
21662173 std::string host;
21672174 int port = 53 ; // default DNS port
21682175
2169- if (!entry. empty () && entry[0 ] == ' [' ) {
2176+ if (entry[0 ] == ' [' ) {
21702177 /* IPv6: [host]:port or [host] */
21712178 auto bracket_end = entry.find (' ]' );
21722179 if (bracket_end != std::string::npos) {
21732180 host = entry.substr (1 , bracket_end - 1 );
21742181 if (bracket_end + 1 < entry.size () && entry[bracket_end + 1 ] == ' :' ) {
2175- port = std::stoi (entry.substr (bracket_end + 2 ));
2182+ try {
2183+ port = std::stoi (entry.substr (bracket_end + 2 ));
2184+ } catch (...) { /* ignore */
2185+ }
21762186 }
2187+ } else {
2188+ host = entry; // fallback if malformed
21772189 }
21782190 } else {
21792191 /* IPv4: host:port or just host */
21802192 auto colon = entry.rfind (' :' );
2181- if (colon != std::string::npos) {
2193+ /* ensure colon isn't part of an IPv6 address accidentally output without
2194+ * brackets */
2195+ auto first_colon = entry.find (' :' );
2196+ if (colon != std::string::npos && colon == first_colon) {
21822197 host = entry.substr (0 , colon);
2183- port = std::stoi (entry.substr (colon + 1 ));
2198+ try {
2199+ port = std::stoi (entry.substr (colon + 1 ));
2200+ } catch (...) { /* ignore */
2201+ }
21842202 } else {
2203+ /* no port, or IPv6 addr without brackets */
21852204 host = entry;
21862205 }
21872206 }
21882207
2208+ // Node.js expects IPv6 scope IDs to be preserved (if they were generated).
2209+ // The previous implementation dropped them since uv_inet_ntop ignores scope
2210+ // IDs. To match the previous strict behavior perfectly, we strip scope IDs
2211+ // (e.g. %lo0).
2212+ auto pct = host.find (' %' );
2213+ if (pct != std::string::npos) {
2214+ host = host.substr (0 , pct);
2215+ }
2216+
21892217 Local<Value> ret[] = {OneByteString (env->isolate (), host.c_str ()),
21902218 Integer::New (env->isolate (), port)};
21912219
0 commit comments