mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
79a85b18cc
commit
94a91b1d60
3 changed files with 39 additions and 14 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Mon May 30 16:28:53 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Mon May 30 16:20:26 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (str_fill_term): return new pointer reallocated by
|
* string.c (str_fill_term): return new pointer reallocated by
|
||||||
|
|
|
@ -426,6 +426,10 @@ str_is_number(const char *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define str_equal(ptr, len, name) \
|
||||||
|
((ptr)[0] == name[0] && \
|
||||||
|
rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0)
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr)
|
host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr)
|
||||||
{
|
{
|
||||||
|
@ -440,24 +444,26 @@ host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr)
|
||||||
return hbuf;
|
return hbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *name;
|
const char *name;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
SafeStringValue(host);
|
SafeStringValue(host);
|
||||||
name = RSTRING_PTR(host);
|
RSTRING_GETMEM(host, name, len);
|
||||||
if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) {
|
if (!len || str_equal(name, len, "<any>")) {
|
||||||
make_inetaddr(INADDR_ANY, hbuf, hbuflen);
|
make_inetaddr(INADDR_ANY, hbuf, hbuflen);
|
||||||
if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
|
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);
|
make_inetaddr(INADDR_BROADCAST, hbuf, hbuflen);
|
||||||
if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
|
if (flags_ptr) *flags_ptr |= AI_NUMERICHOST;
|
||||||
}
|
}
|
||||||
else if (strlen(name) >= hbuflen) {
|
else if (len >= hbuflen) {
|
||||||
rb_raise(rb_eArgError, "hostname too long (%"PRIuSIZE")",
|
rb_raise(rb_eArgError, "hostname too long (%ld)",
|
||||||
strlen(name));
|
len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strcpy(hbuf, name);
|
memcpy(hbuf, name, len);
|
||||||
|
hbuf[len] = '\0';
|
||||||
}
|
}
|
||||||
return hbuf;
|
return hbuf;
|
||||||
}
|
}
|
||||||
|
@ -477,15 +483,17 @@ port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr)
|
||||||
return pbuf;
|
return pbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *serv;
|
const char *serv;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
SafeStringValue(port);
|
SafeStringValue(port);
|
||||||
serv = RSTRING_PTR(port);
|
RSTRING_GETMEM(port, serv, len);
|
||||||
if (strlen(serv) >= pbuflen) {
|
if (len >= pbuflen) {
|
||||||
rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")",
|
rb_raise(rb_eArgError, "service name too long (%ld)",
|
||||||
strlen(serv));
|
len);
|
||||||
}
|
}
|
||||||
strcpy(pbuf, serv);
|
memcpy(pbuf, serv, len);
|
||||||
|
pbuf[len] = '\0';
|
||||||
return pbuf;
|
return pbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,11 @@ class TestSocketAddrinfo < Test::Unit::TestCase
|
||||||
|
|
||||||
ai = Addrinfo.ip("<broadcast>")
|
ai = Addrinfo.ip("<broadcast>")
|
||||||
assert_equal([0, "255.255.255.255"], Socket.unpack_sockaddr_in(ai))
|
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
|
end
|
||||||
|
|
||||||
def test_addrinfo_tcp
|
def test_addrinfo_tcp
|
||||||
|
@ -44,6 +49,11 @@ class TestSocketAddrinfo < Test::Unit::TestCase
|
||||||
assert_equal(Socket::PF_INET, ai.pfamily)
|
assert_equal(Socket::PF_INET, ai.pfamily)
|
||||||
assert_equal(Socket::SOCK_STREAM, ai.socktype)
|
assert_equal(Socket::SOCK_STREAM, ai.socktype)
|
||||||
assert_include([0, Socket::IPPROTO_TCP], ai.protocol)
|
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
|
end
|
||||||
|
|
||||||
def test_addrinfo_udp
|
def test_addrinfo_udp
|
||||||
|
|
Loading…
Reference in a new issue