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

ruby-changes:34368

From: nagachika <ko1@a...>
Date: Tue, 17 Jun 2014 00:33:23 +0900 (JST)
Subject: [ruby-changes:34368] nagachika:r46449 (ruby_2_1): merge revision(s) r45287, r45288, r45289, r45290: [Backport #9600]

nagachika	2014-06-17 00:33:10 +0900 (Tue, 17 Jun 2014)

  New Revision: 46449

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

  Log:
    merge revision(s) r45287,r45288,r45289,r45290: [Backport #9600]
    
    process.c: tmp buffer instead of alloca
    
    * process.c (OBJ2UID1, OBJ2GID1): separate from OBJ2UID and
      OBJ2GID respectively, need given buffers.
    
    * process.c (OBJ2UID, OBJ2GID): no longer need PREPARE_GETPWNAM
      and PREPARE_GETGRNAM.
    
    * process.c (obj2uid, obj2gid): use tmp buffer instead of alloca
      to get rid of potential stack overflow.
    * process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r()
      may need larger buffers than sysconf values, so retry with
      expanding the buffer when ERANGE is returned.
      [ruby-core:61325] [Bug #9600]

  Modified directories:
    branches/ruby_2_1/
  Modified files:
    branches/ruby_2_1/ChangeLog
    branches/ruby_2_1/process.c
    branches/ruby_2_1/version.h
Index: ruby_2_1/ChangeLog
===================================================================
--- ruby_2_1/ChangeLog	(revision 46448)
+++ ruby_2_1/ChangeLog	(revision 46449)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1
+Tue Jun 17 00:26:59 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r()
+	  may need larger buffers than sysconf values, so retry with
+	  expanding the buffer when ERANGE is returned.
+	  [ruby-core:61325] [Bug #9600]
+
 Wed Jun 11 22:58:30 2014  Eric Wong  <e@8...>
 
 	* gc.c (ruby_gc_set_params): simplify condition
Index: ruby_2_1/process.c
===================================================================
--- ruby_2_1/process.c	(revision 46448)
+++ ruby_2_1/process.c	(revision 46449)
@@ -151,20 +151,36 @@ static void check_gid_switch(void); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L151
 #if defined(HAVE_PWD_H)
 # if defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
 #  define USE_GETPWNAM_R 1
+#  define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX)
+#  define GETPW_R_SIZE_DEFAULT 0x1000
+#  define GETPW_R_SIZE_LIMIT  0x10000
 # endif
 # ifdef USE_GETPWNAM_R
 #   define PREPARE_GETPWNAM \
-    long getpw_buf_len = sysconf(_SC_GETPW_R_SIZE_MAX); \
-    char *getpw_buf = ALLOCA_N(char, (getpw_buf_len < 0 ? (getpw_buf_len = 4096) : getpw_buf_len));
-#   define OBJ2UID(id) obj2uid((id), getpw_buf, getpw_buf_len)
-static rb_uid_t obj2uid(VALUE id, char *getpw_buf, size_t getpw_buf_len);
+    VALUE getpw_buf = 0
+#   define FINISH_GETPWNAM \
+    ALLOCV_END(getpw_buf)
+#   define OBJ2UID1(id) obj2uid((id), &getpw_buf)
+#   define OBJ2UID(id) obj2uid0(id)
+static rb_uid_t obj2uid(VALUE id, VALUE *getpw_buf);
+static inline rb_uid_t
+obj2uid0(VALUE id)
+{
+    rb_uid_t uid;
+    PREPARE_GETPWNAM;
+    uid = OBJ2UID1(id);
+    FINISH_GETPWNAM;
+    return uid;
+}
 # else
 #   define PREPARE_GETPWNAM	/* do nothing */
+#   define FINISH_GETPWNAM	/* do nothing */
 #   define OBJ2UID(id) obj2uid((id))
 static rb_uid_t obj2uid(VALUE id);
 # endif
 #else
 # define PREPARE_GETPWNAM	/* do nothing */
+# define FINISH_GETPWNAM	/* do nothing */
 # define OBJ2UID(id) NUM2UIDT(id)
 # ifdef p_uid_from_name
 #   undef p_uid_from_name
@@ -175,20 +191,37 @@ static rb_uid_t obj2uid(VALUE id); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L191
 #if defined(HAVE_GRP_H)
 # if defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
 #  define USE_GETGRNAM_R
+#  define GETGR_R_SIZE_INIT sysconf(_SC_GETGR_R_SIZE_MAX)
+#  define GETGR_R_SIZE_DEFAULT 0x1000
+#  define GETGR_R_SIZE_LIMIT  0x10000
 # endif
 # ifdef USE_GETGRNAM_R
 #   define PREPARE_GETGRNAM \
-    long getgr_buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); \
-    char *getgr_buf = ALLOCA_N(char, (getgr_buf_len < 0 ? (getgr_buf_len = 4096) : getgr_buf_len));
-#   define OBJ2GID(id) obj2gid((id), getgr_buf, getgr_buf_len)
-static rb_gid_t obj2gid(VALUE id, char *getgr_buf, size_t getgr_buf_len);
+    VALUE getgr_buf = 0
+#   define FINISH_GETGRNAM \
+    ALLOCV_END(getgr_buf)
+#   define OBJ2GID1(id) obj2gid((id), &getgr_buf)
+#   define OBJ2GID(id) obj2gid0(id)
+static rb_gid_t obj2gid(VALUE id, VALUE *getgr_buf);
+static inline rb_gid_t
+obj2gid0(VALUE id)
+{
+    rb_gid_t gid;
+    PREPARE_GETGRNAM;
+    gid = OBJ2GID1(id);
+    FINISH_GETGRNAM;
+    return gid;
+}
+static rb_gid_t obj2gid(VALUE id, VALUE *getgr_buf);
 # else
 #   define PREPARE_GETGRNAM	/* do nothing */
+#   define FINISH_GETGRNAM	/* do nothing */
 #   define OBJ2GID(id) obj2gid((id))
 static rb_gid_t obj2gid(VALUE id);
 # endif
 #else
 # define PREPARE_GETGRNAM	/* do nothing */
+# define FINISH_GETGRNAM	/* do nothing */
 # define OBJ2GID(id) NUM2GIDT(id)
 # ifdef p_gid_from_name
 #   undef p_gid_from_name
@@ -1751,7 +1784,6 @@ rb_execarg_addopt(VALUE execarg_obj, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L1784
 	    }
 	    check_uid_switch();
 	    {
-		PREPARE_GETPWNAM;
 		eargp->uid = OBJ2UID(val);
 		eargp->uid_given = 1;
 	    }
@@ -1767,7 +1799,6 @@ rb_execarg_addopt(VALUE execarg_obj, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L1799
 	    }
 	    check_gid_switch();
 	    {
-		PREPARE_GETGRNAM;
 		eargp->gid = OBJ2GID(val);
 		eargp->gid_given = 1;
 	    }
@@ -4821,7 +4852,7 @@ check_gid_switch(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4852
 static rb_uid_t
 obj2uid(VALUE id
 # ifdef USE_GETPWNAM_R
-	, char *getpw_buf, size_t getpw_buf_len
+	, VALUE *getpw_tmp
 # endif
     )
 {
@@ -4836,8 +4867,28 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4867
 	struct passwd *pwptr;
 #ifdef USE_GETPWNAM_R
 	struct passwd pwbuf;
-	if (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr))
-	    rb_sys_fail("getpwnam_r");
+	char *getpw_buf;
+	long getpw_buf_len;
+	if (!*getpw_tmp) {
+	    getpw_buf_len = GETPW_R_SIZE_INIT;
+	    if (getpw_buf_len < 0) getpw_buf_len = GETPW_R_SIZE_DEFAULT;
+	    getpw_buf = rb_alloc_tmp_buffer(getpw_tmp, getpw_buf_len);
+	}
+	else {
+	    getpw_buf = RSTRING_PTR(*getpw_tmp);
+	    getpw_buf_len = rb_str_capacity(*getpw_tmp);
+	}
+	errno = ERANGE;
+	/* gepwnam_r() on MacOS X doesn't set errno if buffer size is insufficient */
+	while (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr)) {
+	    if (errno != ERANGE || getpw_buf_len >= GETPW_R_SIZE_LIMIT) {
+		rb_free_tmp_buffer(getpw_tmp);
+		rb_sys_fail("getpwnam_r");
+	    }
+	    rb_str_modify_expand(*getpw_tmp, getpw_buf_len);
+	    getpw_buf = RSTRING_PTR(*getpw_tmp);
+	    getpw_buf_len = rb_str_capacity(*getpw_tmp);
+	}
 #else
 	pwptr = getpwnam(usrname);
 #endif
@@ -4870,7 +4921,6 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4921
 static VALUE
 p_uid_from_name(VALUE self, VALUE id)
 {
-    PREPARE_GETPWNAM
     return UIDT2NUM(OBJ2UID(id));
 }
 # endif
@@ -4880,7 +4930,7 @@ p_uid_from_name(VALUE self, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4930
 static rb_gid_t
 obj2gid(VALUE id
 # ifdef USE_GETGRNAM_R
-	, char *getgr_buf, size_t getgr_buf_len
+	, VALUE *getgr_tmp
 # endif
     )
 {
@@ -4895,8 +4945,28 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4945
 	struct group *grptr;
 #ifdef USE_GETGRNAM_R
 	struct group grbuf;
-	if (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr))
-	    rb_sys_fail("getgrnam_r");
+	char *getgr_buf;
+	long getgr_buf_len;
+	if (!*getgr_tmp) {
+	    getgr_buf_len = GETGR_R_SIZE_INIT;
+	    if (getgr_buf_len < 0) getgr_buf_len = GETGR_R_SIZE_DEFAULT;
+	    getgr_buf = rb_alloc_tmp_buffer(getgr_tmp, getgr_buf_len);
+	}
+	else {
+	    getgr_buf = RSTRING_PTR(*getgr_tmp);
+	    getgr_buf_len = rb_str_capacity(*getgr_tmp);
+	}
+	errno = ERANGE;
+	/* gegrnam_r() on MacOS X doesn't set errno if buffer size is insufficient */
+	while (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr)) {
+	    if (errno != ERANGE || getgr_buf_len >= GETGR_R_SIZE_LIMIT) {
+		rb_free_tmp_buffer(getgr_tmp);
+		rb_sys_fail("getgrnam_r");
+	    }
+	    rb_str_modify_expand(*getgr_tmp, getgr_buf_len);
+	    getgr_buf = RSTRING_PTR(*getgr_tmp);
+	    getgr_buf_len = rb_str_capacity(*getgr_tmp);
+	}
 #else
 	grptr = getgrnam(grpname);
 #endif
@@ -4929,7 +4999,6 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4999
 static VALUE
 p_gid_from_name(VALUE self, VALUE id)
 {
-    PREPARE_GETGRNAM;
     return GIDT2NUM(OBJ2GID(id));
 }
 # endif
@@ -4948,7 +5017,6 @@ p_gid_from_name(VALUE self, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5017
 static VALUE
 p_sys_setuid(VALUE obj, VALUE id)
 {
-    PREPARE_GETPWNAM;
     check_uid_switch();
     if (setuid(OBJ2UID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -4971,7 +5039,6 @@ p_sys_setuid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5039
 static VALUE
 p_sys_setruid(VALUE obj, VALUE id)
 {
-    PREPARE_GETPWNAM;
     check_uid_switch();
     if (setruid(OBJ2UID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -4994,7 +5061,6 @@ p_sys_setruid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5061
 static VALUE
 p_sys_seteuid(VALUE obj, VALUE id)
 {
-    PREPARE_GETPWNAM;
     check_uid_switch();
     if (seteuid(OBJ2UID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -5019,9 +5085,13 @@ p_sys_seteuid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5085
 static VALUE
 p_sys_setreuid(VALUE obj, VALUE rid, VALUE eid)
 {
+    rb_uid_t ruid, euid;
     PREPARE_GETPWNAM;
     check_uid_switch();
-    if (setreuid(OBJ2UID(rid), OBJ2UID(eid)) != 0) rb_sys_fail(0);
+    ruid = OBJ2UID1(rid);
+    euid = OBJ2UID1(eid);
+    FINISH_GETPWNAM;
+    if (setreuid(ruid, euid) != 0) rb_sys_fail(0);
     return Qnil;
 }
 #else
@@ -5044,9 +5114,14 @@ p_sys_setreuid(VALUE obj, VALUE rid, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5114
 static VALUE
 p_sys_setresuid(VALUE obj, VALUE rid, VALUE eid, VALUE sid)
 {
+    rb_uid_t ruid, euid, suid;
     PREPARE_GETPWNAM;
     check_uid_switch();
-    if (setresuid(OBJ2UID(rid), OBJ2UID(eid), OBJ2UID(sid)) != 0) rb_sys_fail(0);
+    ruid = OBJ2UID1(rid);
+    euid = OBJ2UID1(eid);
+    suid = OBJ2UID1(sid);
+    FINISH_GETPWNAM;
+    if (setresuid(ruid, euid, suid) != 0) rb_sys_fail(0);
     return Qnil;
 }
 #else
@@ -5086,7 +5161,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5161
 proc_setuid(VALUE obj, VALUE id)
 {
     rb_uid_t uid;
-    PREPARE_GETPWNAM;
 
     check_uid_switch();
 
@@ -5158,7 +5232,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5232
 p_uid_change_privilege(VALUE obj, VALUE id)
 {
     rb_uid_t uid;
-    PREPARE_GETPWNAM;
 
     check_uid_switch();
 
@@ -5328,7 +5401,6 @@ p_uid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5401
 static VALUE
 p_sys_setgid(VALUE obj, VALUE id)
 {
-    PREPARE_GETGRNAM;
     check_gid_switch();
     if (setgid(OBJ2GID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -5351,7 +5423,6 @@ p_sys_setgid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5423
 static VALUE
 p_sys_setrgid(VALUE obj, VALUE id)
 {
-    PREPARE_GETGRNAM;
     check_gid_switch();
     if (setrgid(OBJ2GID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -5374,7 +5445,6 @@ p_sys_setrgid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5445
 static VALUE
 p_sys_setegid(VALUE obj, VALUE id)
 {
-    PREPARE_GETGRNAM;
     check_gid_switch();
     if (setegid(OBJ2GID(id)) != 0) rb_sys_fail(0);
     return Qnil;
@@ -5399,9 +5469,13 @@ p_sys_setegid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5469
 static VALUE
 p_sys_setregid(VALUE obj, VALUE rid, VALUE eid)
 {
+    rb_gid_t rgid, egid;
     PREPARE_GETGRNAM;
     check_gid_switch();
-    if (setregid(OBJ2GID(rid), OBJ2GID(eid)) != 0) rb_sys_fail(0);
+    rgid = OBJ2GID(rid);
+    egid = OBJ2GID(eid);
+    FINISH_GETGRNAM;
+    if (setregid(rgid, egid) != 0) rb_sys_fail(0);
     return Qnil;
 }
 #else
@@ -5423,9 +5497,14 @@ p_sys_setregid(VALUE obj, VALUE rid, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5497
 static VALUE
 p_sys_setresgid(VALUE obj, VALUE rid, VALUE eid, VALUE sid)
 {
+    rb_gid_t rgid, egid, sgid;
     PREPARE_GETGRNAM;
     check_gid_switch();
-    if (setresgid(OBJ2GID(rid), OBJ2GID(eid), OBJ2GID(sid)) != 0) rb_sys_fail(0);
+    rgid = OBJ2GID(rid);
+    egid = OBJ2GID(eid);
+    sgid = OBJ2GID(sid);
+    FINISH_GETGRNAM;
+    if (setresgid(rgid, egid, sgid) != 0) rb_sys_fail(0);
     return Qnil;
 }
 #else
@@ -5493,7 +5572,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5572
 proc_setgid(VALUE obj, VALUE id)
 {
     rb_gid_t gid;
-    PREPARE_GETGRNAM;
 
     check_gid_switch();
 
@@ -5641,8 +5719,9 @@ proc_setgroups(VALUE obj, VALUE ary) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5719
     for (i = 0; i < ngroups; i++) {
 	VALUE g = RARRAY_AREF(ary, i);
 
-	groups[i] = OBJ2GID(g);
+	groups[i] = OBJ2GID1(g);
     }
+    FINISH_GETGRNAM;
 
     if (setgroups(ngroups, groups) == -1) /* ngroups <= maxgroups */
 	rb_sys_fail(0);
@@ -5675,7 +5754,6 @@ proc_setgroups(VALUE obj, VALUE ary) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5754
 static VALUE
 proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp)
 {
-    PREPARE_GETGRNAM;
     if (initgroups(StringValuePtr(uname), OBJ2GID(base_grp)) != 0) {
 	rb_sys_fail(0);
     }
@@ -5857,7 +5935,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5935
 p_gid_change_privilege(VALUE obj, VALUE id)
 {
     rb_gid_t gid;
-    PREPARE_GETGRNAM;
 
     check_gid_switch();
 
@@ -6067,7 +6144,6 @@ proc_seteuid(rb_uid_t uid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6144
 static VALUE
 proc_seteuid_m(VALUE mod, VALUE euid)
 {
-    PREPARE_GETPWNAM;
     check_uid_switch();
     proc_seteuid(OBJ2UID(euid));
     return euid;
@@ -6133,7 +6209,6 @@ rb_seteuid_core(rb_uid_t euid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6209
 static VALUE
 p_uid_grant_privilege(VALUE obj, VALUE id)
 {
-    PREPARE_GETPWNAM;
     rb_seteuid_core(OBJ2UID(id));
     return id;
 }
@@ -6173,7 +6248,6 @@ proc_setegid(VALUE obj, VALUE egid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6248
 {
 #if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID)
     rb_gid_t gid;
-    PREPARE_GETGRNAM;
 #endif
 
     check_gid_switch();
@@ -6265,7 +6339,6 @@ rb_setegid_core(rb_gid_t egid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6339
 static VALUE
 p_gid_grant_privilege(VALUE obj, VALUE id)
 {
-    PREPARE_GETGRNAM;
     rb_setegid_core(OBJ2GID(id));
     return id;
 }
Index: ruby_2_1/version.h
===================================================================
--- ruby_2_1/version.h	(revision 46448)
+++ ruby_2_1/version.h	(revision 46449)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1
 #define RUBY_VERSION "2.1.2"
-#define RUBY_RELEASE_DATE "2014-06-11"
-#define RUBY_PATCHLEVEL 129
+#define RUBY_RELEASE_DATE "2014-06-17"
+#define RUBY_PATCHLEVEL 130
 
 #define RUBY_RELEASE_YEAR 2014
 #define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 11
+#define RUBY_RELEASE_DAY 17
 
 #include "ruby/version.h"
 

Property changes on: ruby_2_1
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r45287-45290


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

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