diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-30 07:28:55 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-30 07:28:55 +0000 |
commit | 94a91b1d60d048dcf75039d6d64ad9ee7e5929f4 (patch) | |
tree | 68b97807dc9950dce7af0642722b1378559ba8ec /ext/socket/raddrinfo.c | |
parent | 79a85b18cc6ad27f1a70a703270680dc30a1263e (diff) | |
download | ruby-94a91b1d60d048dcf75039d6d64ad9ee7e5929f4.tar.gz |
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/raddrinfo.c')
-rw-r--r-- | ext/socket/raddrinfo.c | 36 |
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; } } |