summaryrefslogtreecommitdiff
path: root/ext/socket
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-05-30 07:28:55 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-05-30 07:28:55 +0000
commit94a91b1d60d048dcf75039d6d64ad9ee7e5929f4 (patch)
tree68b97807dc9950dce7af0642722b1378559ba8ec /ext/socket
parent79a85b18cc6ad27f1a70a703270680dc30a1263e (diff)
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
Diffstat (limited to 'ext/socket')
-rw-r--r--ext/socket/raddrinfo.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index 92556fc9d2..f18e278323 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -426,6 +426,10 @@ str_is_number(const char *p)
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 hbuflen, int *flags_ptr)
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 pbuflen, int *flags_ptr)
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;
}
}