ruby-changes:43139
From: nobu <ko1@a...>
Date: Mon, 30 May 2016 16:28:59 +0900 (JST)
Subject: [ruby-changes:43139] nobu:r55213 (trunk): raddrinfo.c: fix for SHARABLE_MIDDLE_SUBSTRING
nobu 2016-05-30 16:28:55 +0900 (Mon, 30 May 2016) New Revision: 55213 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55213 Log: raddrinfo.c: fix for SHARABLE_MIDDLE_SUBSTRING * ext/socket/raddrinfo.c (host_str, port_str): use RSTRING_LEN instead of strlen, since RSTRING_PTR StringValueCStr may not be NUL-terminated when SHARABLE_MIDDLE_SUBSTRING=1. reported by @tmtms, http://twitter.com/tmtms/status/736910516229005312 Modified files: trunk/ChangeLog trunk/ext/socket/raddrinfo.c trunk/test/socket/test_addrinfo.rb Index: test/socket/test_addrinfo.rb =================================================================== --- test/socket/test_addrinfo.rb (revision 55212) +++ test/socket/test_addrinfo.rb (revision 55213) @@ -35,6 +35,11 @@ class TestSocketAddrinfo < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/socket/test_addrinfo.rb#L35 ai = Addrinfo.ip("<broadcast>") assert_equal([0, "255.255.255.255"], Socket.unpack_sockaddr_in(ai)) + + ai = assert_nothing_raised(SocketError) do + Addrinfo.ip("00000000127.000000000.00000000.0000001x".chop) + end + assert_equal([0, "127.0.0.1"], Socket.unpack_sockaddr_in(ai)) end def test_addrinfo_tcp @@ -44,6 +49,11 @@ class TestSocketAddrinfo < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/socket/test_addrinfo.rb#L49 assert_equal(Socket::PF_INET, ai.pfamily) assert_equal(Socket::SOCK_STREAM, ai.socktype) assert_include([0, Socket::IPPROTO_TCP], ai.protocol) + + ai = assert_nothing_raised(SocketError) do + Addrinfo.tcp("127.0.0.1", "0000000000000000000000080x".chop) + end + assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai)) end def test_addrinfo_udp Index: ChangeLog =================================================================== --- ChangeLog (revision 55212) +++ ChangeLog (revision 55213) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon May 30 16:28:53 2016 Nobuyoshi Nakada <nobu@r...> + + * ext/socket/raddrinfo.c (host_str, port_str): use RSTRING_LEN + instead of strlen, since RSTRING_PTR StringValueCStr may not be + NUL-terminated when SHARABLE_MIDDLE_SUBSTRING=1. reported by + @tmtms, http://twitter.com/tmtms/status/736910516229005312 + Mon May 30 16:20:26 2016 Nobuyoshi Nakada <nobu@r...> * string.c (str_fill_term): return new pointer reallocated by Index: ext/socket/raddrinfo.c =================================================================== --- ext/socket/raddrinfo.c (revision 55212) +++ ext/socket/raddrinfo.c (revision 55213) @@ -426,6 +426,10 @@ str_is_number(const char *p) https://github.com/ruby/ruby/blob/trunk/ext/socket/raddrinfo.c#L426 return 0; } +#define str_equal(ptr, len, name) \ + ((ptr)[0] == name[0] && \ + rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0) + static char* host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) { @@ -440,24 +444,26 @@ host_str(VALUE host, char *hbuf, size_t https://github.com/ruby/ruby/blob/trunk/ext/socket/raddrinfo.c#L444 return hbuf; } else { - char *name; + const char *name; + size_t len; SafeStringValue(host); - name = RSTRING_PTR(host); - if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) { + RSTRING_GETMEM(host, name, len); + if (!len || str_equal(name, len, "<any>")) { make_inetaddr(INADDR_ANY, hbuf, hbuflen); if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; } - else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) { + else if (str_equal(name, len, "<broadcast>")) { make_inetaddr(INADDR_BROADCAST, hbuf, hbuflen); if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; } - else if (strlen(name) >= hbuflen) { - rb_raise(rb_eArgError, "hostname too long (%"PRIuSIZE")", - strlen(name)); + else if (len >= hbuflen) { + rb_raise(rb_eArgError, "hostname too long (%ld)", + len); } else { - strcpy(hbuf, name); + memcpy(hbuf, name, len); + hbuf[len] = '\0'; } return hbuf; } @@ -477,15 +483,17 @@ port_str(VALUE port, char *pbuf, size_t https://github.com/ruby/ruby/blob/trunk/ext/socket/raddrinfo.c#L483 return pbuf; } else { - char *serv; + const char *serv; + size_t len; SafeStringValue(port); - serv = RSTRING_PTR(port); - if (strlen(serv) >= pbuflen) { - rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")", - strlen(serv)); + RSTRING_GETMEM(port, serv, len); + if (len >= pbuflen) { + rb_raise(rb_eArgError, "service name too long (%ld)", + len); } - strcpy(pbuf, serv); + memcpy(pbuf, serv, len); + pbuf[len] = '\0'; return pbuf; } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/