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

ruby-changes:23423

From: akr <ko1@a...>
Date: Thu, 26 Apr 2012 12:34:26 +0900 (JST)
Subject: [ruby-changes:23423] akr:r35474 (trunk): * ext/socket/raddrinfo.c (init_unix_addrinfo): support the longest

akr	2012-04-26 12:34:12 +0900 (Thu, 26 Apr 2012)

  New Revision: 35474

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35474

  Log:
    * ext/socket/raddrinfo.c (init_unix_addrinfo): support the longest
      path in sockaddr_un.
      (inspect_sockaddr): ditto.
      (addrinfo_mdump): ditto.
      (addrinfo_mload): ditto.
      (rsock_unixpath_str): new function.
      (rsock_unixpath): removed.
      (rsock_unixaddr): use rsock_unixpath_str.
    
    * ext/socket/socket.c (sock_s_pack_sockaddr_un): support the longest
      path in sockaddr_un.
      (sock_s_unpack_sockaddr_un): ditto.
      (sock_s_gethostbyaddr): unused variable removed.
    
    * ext/socket/unixsocket.c (rsock_init_unixsock): support the longest
      path in sockaddr_un.
    
    * ext/socket/rubysocket.h (rsock_unixpath_str): declared.
      (rsock_unixpath): removed.
    
    * test/socket/test_unix.rb: comment out test_nul because abstract unix
      sockets may contain NULs.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/raddrinfo.c
    trunk/ext/socket/rubysocket.h
    trunk/ext/socket/socket.c
    trunk/ext/socket/unixsocket.c
    trunk/test/socket/test_unix.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35473)
+++ ChangeLog	(revision 35474)
@@ -1,3 +1,28 @@
+Thu Apr 26 12:28:06 2012  Tanaka Akira  <akr@f...>
+
+	* ext/socket/raddrinfo.c (init_unix_addrinfo): support the longest
+	  path in sockaddr_un.
+	  (inspect_sockaddr): ditto.
+	  (addrinfo_mdump): ditto.
+	  (addrinfo_mload): ditto.
+	  (rsock_unixpath_str): new function.
+	  (rsock_unixpath): removed.
+	  (rsock_unixaddr): use rsock_unixpath_str.
+
+	* ext/socket/socket.c (sock_s_pack_sockaddr_un): support the longest
+	  path in sockaddr_un.
+	  (sock_s_unpack_sockaddr_un): ditto.
+	  (sock_s_gethostbyaddr): unused variable removed.
+
+	* ext/socket/unixsocket.c (rsock_init_unixsock): support the longest
+	  path in sockaddr_un.
+
+	* ext/socket/rubysocket.h (rsock_unixpath_str): declared.
+	  (rsock_unixpath): removed.
+
+	* test/socket/test_unix.rb: comment out test_nul because abstract unix
+	  sockets may contain NULs.
+
 Thu Apr 26 01:32:33 2012  CHIKANAGA Tomoyuki  <nagachika00@g...>
 
 	* test/optparse/test_summary.rb (test_summary_containing_space): add
Index: ext/socket/rubysocket.h
===================================================================
--- ext/socket/rubysocket.h	(revision 35473)
+++ ext/socket/rubysocket.h	(revision 35474)
@@ -233,7 +233,7 @@
 int rsock_revlookup_flag(VALUE revlookup, int *norevlookup);
 
 #ifdef HAVE_SYS_UN_H
-const char* rsock_unixpath(struct sockaddr_un *sockaddr, socklen_t len);
+VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len);
 VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len);
 #endif
 
Index: ext/socket/raddrinfo.c
===================================================================
--- ext/socket/raddrinfo.c	(revision 35473)
+++ ext/socket/raddrinfo.c	(revision 35474)
@@ -421,20 +421,25 @@
 }
 
 #ifdef HAVE_SYS_UN_H
-const char*
-rsock_unixpath(struct sockaddr_un *sockaddr, socklen_t len)
+VALUE
+rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len)
 {
-    if (sockaddr->sun_path < (char*)sockaddr + len)
-        return sockaddr->sun_path;
+    char *s, *e;
+    s = sockaddr->sun_path;
+    e = (char *)sockaddr + len;
+    while (s < e && *(e-1) == '\0')
+        e--;
+    if (s <= e)
+        return rb_str_new(s, e-s);
     else
-        return "";
+        return rb_str_new2("");
 }
 
 VALUE
 rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len)
 {
     return rb_assoc_new(rb_str_new2("AF_UNIX"),
-                        rb_str_new2(rsock_unixpath(sockaddr, len)));
+                        rsock_unixpath_str(sockaddr, len));
 }
 #endif
 
@@ -767,10 +772,10 @@
 
     StringValue(path);
 
-    if (sizeof(un.sun_path) <= (size_t)RSTRING_LEN(path))
+    if (sizeof(un.sun_path) < (size_t)RSTRING_LEN(path))
         rb_raise(rb_eArgError,
             "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
-            (size_t)RSTRING_LEN(path), sizeof(un.sun_path)-1);
+            (size_t)RSTRING_LEN(path), sizeof(un.sun_path));
 
     MEMZERO(&un, struct sockaddr_un, 1);
 
@@ -998,9 +1003,11 @@
           case AF_UNIX:
           {
             struct sockaddr_un *addr = (struct sockaddr_un *)&rai->addr;
-            char *p, *s, *t, *e;
+            char *p, *s, *e;
             s = addr->sun_path;
             e = (char*)addr + rai->sockaddr_len;
+            while (s < e && *(e-1) == '\0')
+                e--;
             if (e < s)
                 rb_str_cat2(ret, "too-short-AF_UNIX-sockaddr");
             else if (s == e)
@@ -1008,28 +1015,17 @@
             else {
                 int printable_only = 1;
                 p = s;
-                while (p < e && *p != '\0') {
+                while (p < e) {
                     printable_only = printable_only && ISPRINT(*p) && !ISSPACE(*p);
                     p++;
                 }
-                t = p;
-                while (p < e && *p == '\0')
-                    p++;
-                if (printable_only && /* only printable, no space */
-                    t < e && /* NUL terminated */
-                    p == e) { /* no data after NUL */
-		    if (s == t)
-			rb_str_cat2(ret, "empty-path-AF_UNIX-sockaddr");
-		    else if (s[0] == '/') /* absolute path */
-			rb_str_cat2(ret, s);
-		    else
-                        rb_str_catf(ret, "AF_UNIX %s", s);
+                if (printable_only) { /* only printable, no space */
+                    if (s[0] != '/') /* relative path */
+                        rb_str_cat2(ret, "AF_UNIX ");
+                    rb_str_cat(ret, s, p - s);
                 }
                 else {
                     rb_str_cat2(ret, "AF_UNIX");
-                    e = (char *)addr->sun_path + sizeof(addr->sun_path);
-                    while (s < e && *(e-1) == '\0')
-                        e--;
                     while (s < e)
                         rb_str_catf(ret, ":%02x", (unsigned char)*s++);
                 }
@@ -1203,7 +1199,7 @@
         struct sockaddr_un *su = (struct sockaddr_un *)&rai->addr;
         char *s, *e;
         s = su->sun_path;
-        e = (char*)s + sizeof(su->sun_path);
+        e = (char*)su + rai->sockaddr_len;
         while (s < e && *(e-1) == '\0')
             e--;
         sockaddr = rb_str_new(s, e-s);
@@ -1300,14 +1296,14 @@
       case AF_UNIX:
       {
         struct sockaddr_un uaddr;
-        memset(&uaddr, 0, sizeof(uaddr));
+        MEMZERO(&uaddr, struct sockaddr_un, 1);
         uaddr.sun_family = AF_UNIX;
 
         StringValue(v);
-        if (sizeof(uaddr.sun_path) <= (size_t)RSTRING_LEN(v))
+        if (sizeof(uaddr.sun_path) < (size_t)RSTRING_LEN(v))
             rb_raise(rb_eSocket,
                 "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
-                (size_t)RSTRING_LEN(v), sizeof(uaddr.sun_path)-1);
+                (size_t)RSTRING_LEN(v), sizeof(uaddr.sun_path));
         memcpy(uaddr.sun_path, RSTRING_PTR(v), RSTRING_LEN(v));
         len = (socklen_t)sizeof(uaddr);
         memcpy(&ss, &uaddr, len);
Index: ext/socket/socket.c
===================================================================
--- ext/socket/socket.c	(revision 35473)
+++ ext/socket/socket.c	(revision 35474)
@@ -1003,13 +1003,12 @@
 {
     VALUE addr, family;
     struct hostent *h;
-    struct sockaddr *sa;
     char **pch;
     VALUE ary, names;
     int t = AF_INET;
 
     rb_scan_args(argc, argv, "11", &addr, &family);
-    sa = (struct sockaddr*)StringValuePtr(addr);
+    StringValue(addr);
     if (!NIL_P(family)) {
 	t = rsock_family_arg(family);
     }
@@ -1422,17 +1421,16 @@
 sock_s_pack_sockaddr_un(VALUE self, VALUE path)
 {
     struct sockaddr_un sockaddr;
-    char *sun_path;
     VALUE addr;
 
+    StringValue(path);
     MEMZERO(&sockaddr, struct sockaddr_un, 1);
     sockaddr.sun_family = AF_UNIX;
-    sun_path = StringValueCStr(path);
-    if (sizeof(sockaddr.sun_path) <= strlen(sun_path)) {
-        rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)",
-            RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path)-1);
+    if (sizeof(sockaddr.sun_path) <= RSTRING_LEN(path)) {
+        rb_raise(rb_eArgError, "too long unix socket path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
+            (size_t)RSTRING_LEN(path), sizeof(sockaddr.sun_path));
     }
-    strncpy(sockaddr.sun_path, sun_path, sizeof(sockaddr.sun_path)-1);
+    memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
     addr = rb_str_new((char*)&sockaddr, sizeof(sockaddr));
     OBJ_INFECT(addr, path);
 
@@ -1455,7 +1453,6 @@
 sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
 {
     struct sockaddr_un * sockaddr;
-    const char *sun_path;
     VALUE path;
 
     sockaddr = (struct sockaddr_un*)SockAddrStringValuePtr(addr);
@@ -1471,13 +1468,7 @@
 	rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d",
 		 RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
     }
-    sun_path = rsock_unixpath(sockaddr, RSTRING_LENINT(addr));
-    if (sizeof(struct sockaddr_un) == RSTRING_LEN(addr) &&
-        sun_path == sockaddr->sun_path &&
-        sun_path + strlen(sun_path) == RSTRING_PTR(addr) + RSTRING_LEN(addr)) {
-        rb_raise(rb_eArgError, "sockaddr_un.sun_path not NUL terminated");
-    }
-    path = rb_str_new2(sun_path);
+    path = rsock_unixpath_str(sockaddr, RSTRING_LENINT(addr));
     OBJ_INFECT(path, addr);
     return path;
 }
Index: ext/socket/unixsocket.c
===================================================================
--- ext/socket/unixsocket.c	(revision 35473)
+++ ext/socket/unixsocket.c	(revision 35474)
@@ -39,9 +39,9 @@
 
     MEMZERO(&sockaddr, struct sockaddr_un, 1);
     sockaddr.sun_family = AF_UNIX;
-    if (sizeof(sockaddr.sun_path) <= (size_t)RSTRING_LEN(path)) {
+    if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
         rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)",
-            RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path)-1);
+            RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path));
     }
     memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
 
@@ -118,7 +118,7 @@
 	socklen_t len = (socklen_t)sizeof(addr);
 	if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
 	    rb_sys_fail(0);
-	fptr->pathv = rb_obj_freeze(rb_str_new_cstr(rsock_unixpath(&addr, len)));
+	fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len));
     }
     return rb_str_dup(fptr->pathv);
 }
Index: test/socket/test_unix.rb
===================================================================
--- test/socket/test_unix.rb	(revision 35473)
+++ test/socket/test_unix.rb	(revision 35474)
@@ -339,9 +339,10 @@
     assert_raise(ArgumentError) { UNIXServer.new("a" * 300) }
   end
 
-  def test_nul
-    assert_raise(ArgumentError) { Socket.sockaddr_un("a\0b") }
-  end
+  #def test_nul
+  #  # path may contain NULs for abstract unix sockets.  [ruby-core:10288]
+  #  assert_raise(ArgumentError) { Socket.sockaddr_un("a\0b") }
+  #end
 
   def test_dgram_pair
     s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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