[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]