diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-06-14 10:11:01 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-06-14 10:11:01 +0000 |
commit | 79c0d0687711f029470b4d8567695aab844246df (patch) | |
tree | 60ce42aa5876ecbcf9f07326d67172d06212dbc7 /ext/socket/raddrinfo.c | |
parent | 1a87c6cfa695da5771c7e8a02f9e389f402c89b9 (diff) | |
download | ruby-79c0d0687711f029470b4d8567695aab844246df.tar.gz |
* ext/socket/raddrinfo.c (parse_numeric_port): Detect
port overflow.
(numeric_getaddrinfo): Use parse_numeric_port.
numeric_getaddrinfo fails if port is too big now.
This makes rb_getaddrinfo invokes the real getaddrinfo()
on such condition.
This change is related to [ruby-core:69355] [Bug #11179].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50890 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/raddrinfo.c')
-rw-r--r-- | ext/socket/raddrinfo.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index caa08fea47..370ea6907f 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -154,6 +154,32 @@ struct getaddrinfo_arg struct addrinfo **res; }; +static int +parse_numeric_port(const char *service, int *portp) +{ + unsigned long u; + + if (!service) { + *portp = 0; + return 1; + } + + if (strspn(service, "0123456789") != strlen(service)) + return 0; + + errno = 0; + u = STRTOUL(service, NULL, 10); + if (errno) + return 0; + + if (0x10000 <= u) + return 0; + + *portp = u; + + return 1; +} + static void * nogvl_getaddrinfo(void *arg) { @@ -181,7 +207,9 @@ numeric_getaddrinfo(const char *node, const char *service, # define inet_pton(f,s,d) rb_w32_inet_pton(f,s,d) # endif - if (node && (!service || strspn(service, "0123456789") == strlen(service))) { + int port; + + if (node && parse_numeric_port(service, &port)) { static const struct { int socktype; int protocol; @@ -191,7 +219,6 @@ numeric_getaddrinfo(const char *node, const char *service, { SOCK_RAW, 0 } }; struct addrinfo *ai = NULL; - int port = service ? (unsigned short)atoi(service): 0; int hint_family = hints ? hints->ai_family : PF_UNSPEC; int hint_socktype = hints ? hints->ai_socktype : 0; int hint_protocol = hints ? hints->ai_protocol : 0; |