diff options
| author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-23 08:25:41 +0000 |
|---|---|---|
| committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-23 08:25:41 +0000 |
| commit | 0fcc2cdb99264e196846155617f14e503ac951fc (patch) | |
| tree | 40e556f3e690422b1666c6e34ae52bde0b9f7e29 /ext/socket/socket.c | |
| parent | cfdeb2ef10d20347040af4ce42d858d7a25f7a83 (diff) | |
merge revision(s) 39239,45045,45530: [Backport #9697]
* ext/socket: always operate length of socket addess companion with
socket address.
* ext/socket/rubysocket.h (rsock_make_ipaddr): add an argument for
socket address length.
(rsock_ipaddr): ditto.
* ext/socket/ipsocket.c (ip_addr): pass length to rsock_ipaddr.
(ip_peeraddr): ditto.
(ip_s_getaddress): pass length to rsock_make_ipaddr.
* ext/socket/socket.c (make_addrinfo): pass length to rsock_ipaddr.
(sock_s_getnameinfo): pass actual address length to rb_getnameinfo.
(sock_s_unpack_sockaddr_in): pass length to rsock_make_ipaddr.
* ext/socket/init.c (rsock_s_recvfrom): pass length to rsock_ipaddr.
(rsock_s_recvfrom_nonblock): ditto.
* ext/socket/tcpsocket.c (tcp_sockaddr): pass length to
rsock_make_ipaddr.
* ext/socket/raddrinfo.c (make_ipaddr0): add an argument for socket
address length. pass the length to rb_getnameinfo.
(rsock_ipaddr): ditto.
(rsock_make_ipaddr): add an argument for socket address length.
pass the length to make_ipaddr0.
(make_inetaddr): pass length to make_ipaddr0.
a local variable renamed.
(host_str): a local variable renamed.
(port_str): ditto.
* ext/socket/ipsocket.c (ip_s_getaddress): Don't access freed memory.
* ext/socket/socket.c (sock_s_getnameinfo): Save errno for EAI_SYSTEM.
Reported by Saravana kumar. [ruby-core:61820] [Bug #9697]
Fixed by Heesob Park. [ruby-core:61868]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@46510 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/socket.c')
| -rw-r--r-- | ext/socket/socket.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 6900dbcca6..3df435bbc9 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -937,7 +937,7 @@ make_addrinfo(struct addrinfo *res0, int norevlookup) } base = rb_ary_new(); for (res = res0; res; res = res->ai_next) { - ary = rsock_ipaddr(res->ai_addr, norevlookup); + ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); if (res->ai_canonname) { RARRAY_PTR(ary)[2] = rb_str_new2(res->ai_canonname); } @@ -1216,9 +1216,10 @@ sock_s_getnameinfo(int argc, VALUE *argv) char hbuf[1024], pbuf[1024]; int fl; struct addrinfo hints, *res = NULL, *r; - int error; + int error, saved_errno; struct sockaddr_storage ss; struct sockaddr *sap; + socklen_t salen; sa = flags = Qnil; rb_scan_args(argc, argv, "11", &sa, &flags); @@ -1238,6 +1239,7 @@ sock_s_getnameinfo(int argc, VALUE *argv) rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); } sap = (struct sockaddr*)&ss; + salen = RSTRING_LEN(sa); goto call_nameinfo; } tmp = rb_check_array_type(sa); @@ -1299,13 +1301,14 @@ sock_s_getnameinfo(int argc, VALUE *argv) error = rb_getaddrinfo(hptr, pptr, &hints, &res); if (error) goto error_exit_addr; sap = res->ai_addr; + salen = res->ai_addrlen; } else { rb_raise(rb_eTypeError, "expecting String or Array"); } call_nameinfo: - error = rb_getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf), + error = rb_getnameinfo(sap, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), fl); if (error) goto error_exit_name; if (res) { @@ -1313,7 +1316,8 @@ sock_s_getnameinfo(int argc, VALUE *argv) char hbuf2[1024], pbuf2[1024]; sap = r->ai_addr; - error = rb_getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2), + salen = r->ai_addrlen; + error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2), pbuf2, sizeof(pbuf2), fl); if (error) goto error_exit_name; if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { @@ -1326,11 +1330,15 @@ sock_s_getnameinfo(int argc, VALUE *argv) return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); error_exit_addr: + saved_errno = errno; if (res) freeaddrinfo(res); + errno = saved_errno; rsock_raise_socket_error("getaddrinfo", error); error_exit_name: + saved_errno = errno; if (res) freeaddrinfo(res); + errno = saved_errno; rsock_raise_socket_error("getnameinfo", error); UNREACHABLE; @@ -1399,7 +1407,7 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr) rb_raise(rb_eArgError, "not an AF_INET sockaddr"); #endif } - host = rsock_make_ipaddr((struct sockaddr*)sockaddr); + host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_LEN(addr)); OBJ_INFECT(host, addr); return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); } |
