mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	merge revision(s) 59322,59325: [Backport #13744]
process.c: handle dynamic :rlimit_* symbols in spawn execopts * process.c (rb_execarg_addopt_rlimit): hoist out of rb_execarg_addopt (rlimit_type_by_sym): new wrapper for dynamic symbol (rb_execarg_addopt): check for dsym via rlimit_type_by_sym * test/ruby/test_process.rb (test_execopts_rlimit): check dsym w/o pindown Add extra check for bogus rlimit args, too. [ruby-core:82033] [Bug #13744] process.c: null bytes * process.c (rlimit_type_by_sym): prohibit null bytes in key names. [ruby-core:82033] [Bug #13744] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@59809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									428687e96d
								
							
						
					
					
						commit
						2d054e4088
					
				
					 3 changed files with 86 additions and 43 deletions
				
			
		
							
								
								
									
										111
									
								
								process.c
									
										
									
									
									
								
							
							
						
						
									
										111
									
								
								process.c
									
										
									
									
									
								
							|  | @ -1634,7 +1634,35 @@ check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp) | |||
| } | ||||
| 
 | ||||
| #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) | ||||
| static int rlimit_type_by_lname(const char *name); | ||||
| static int rlimit_type_by_sym(VALUE key); | ||||
| 
 | ||||
| static void | ||||
| rb_execarg_addopt_rlimit(struct rb_execarg *eargp, int rtype, VALUE val) | ||||
| { | ||||
|     VALUE ary = eargp->rlimit_limits; | ||||
|     VALUE tmp, softlim, hardlim; | ||||
|     if (eargp->rlimit_limits == Qfalse) | ||||
| 	ary = eargp->rlimit_limits = hide_obj(rb_ary_new()); | ||||
|     else | ||||
| 	ary = eargp->rlimit_limits; | ||||
|     tmp = rb_check_array_type(val); | ||||
|     if (!NIL_P(tmp)) { | ||||
| 	if (RARRAY_LEN(tmp) == 1) | ||||
| 	    softlim = hardlim = rb_to_int(rb_ary_entry(tmp, 0)); | ||||
| 	else if (RARRAY_LEN(tmp) == 2) { | ||||
| 	    softlim = rb_to_int(rb_ary_entry(tmp, 0)); | ||||
| 	    hardlim = rb_to_int(rb_ary_entry(tmp, 1)); | ||||
| 	} | ||||
| 	else { | ||||
| 	    rb_raise(rb_eArgError, "wrong exec rlimit option"); | ||||
| 	} | ||||
|     } | ||||
|     else { | ||||
| 	softlim = hardlim = rb_to_int(val); | ||||
|     } | ||||
|     tmp = hide_obj(rb_ary_new3(3, INT2NUM(rtype), softlim, hardlim)); | ||||
|     rb_ary_push(ary, tmp); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int | ||||
|  | @ -1643,12 +1671,19 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val) | |||
|     struct rb_execarg *eargp = rb_execarg_get(execarg_obj); | ||||
| 
 | ||||
|     ID id; | ||||
| #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) | ||||
|     int rtype; | ||||
| #endif | ||||
| 
 | ||||
|     switch (TYPE(key)) { | ||||
|       case T_SYMBOL: | ||||
| #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) | ||||
|         { | ||||
|             int rtype = rlimit_type_by_sym(key); | ||||
|             if (rtype != -1) { | ||||
|                 rb_execarg_addopt_rlimit(eargp, rtype, val); | ||||
|                 RB_GC_GUARD(execarg_obj); | ||||
|                 return ST_CONTINUE; | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|         if (!(id = rb_check_id(&key))) return ST_STOP; | ||||
| #ifdef HAVE_SETPGID | ||||
|         if (id == id_pgroup) { | ||||
|  | @ -1680,35 +1715,6 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val) | |||
|             eargp->new_pgroup_flag = RTEST(val) ? 1 : 0; | ||||
|         } | ||||
|         else | ||||
| #endif | ||||
| #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) | ||||
|         if (strncmp("rlimit_", rb_id2name(id), 7) == 0 && | ||||
|             (rtype = rlimit_type_by_lname(rb_id2name(id)+7)) != -1) { | ||||
|             VALUE ary = eargp->rlimit_limits; | ||||
|             VALUE tmp, softlim, hardlim; | ||||
|             if (eargp->rlimit_limits == Qfalse) | ||||
|                 ary = eargp->rlimit_limits = hide_obj(rb_ary_new()); | ||||
|             else | ||||
|                 ary = eargp->rlimit_limits; | ||||
|             tmp = rb_check_array_type(val); | ||||
|             if (!NIL_P(tmp)) { | ||||
|                 if (RARRAY_LEN(tmp) == 1) | ||||
|                     softlim = hardlim = rb_to_int(rb_ary_entry(tmp, 0)); | ||||
|                 else if (RARRAY_LEN(tmp) == 2) { | ||||
|                     softlim = rb_to_int(rb_ary_entry(tmp, 0)); | ||||
|                     hardlim = rb_to_int(rb_ary_entry(tmp, 1)); | ||||
|                 } | ||||
|                 else { | ||||
|                     rb_raise(rb_eArgError, "wrong exec rlimit option"); | ||||
|                 } | ||||
|             } | ||||
|             else { | ||||
|                 softlim = hardlim = rb_to_int(val); | ||||
|             } | ||||
|             tmp = hide_obj(rb_ary_new3(3, INT2NUM(rtype), softlim, hardlim)); | ||||
|             rb_ary_push(ary, tmp); | ||||
|         } | ||||
|         else | ||||
| #endif | ||||
|         if (id == id_unsetenv_others) { | ||||
|             if (eargp->unsetenv_others_given) { | ||||
|  | @ -1811,7 +1817,7 @@ check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg) | |||
|     VALUE execarg_obj = (VALUE)arg; | ||||
|     if (rb_execarg_addopt(execarg_obj, key, val) != ST_CONTINUE) { | ||||
| 	if (SYMBOL_P(key)) | ||||
| 	    rb_raise(rb_eArgError, "wrong exec option symbol: %"PRIsVALUE, | ||||
| 	    rb_raise(rb_eArgError, "wrong exec option symbol: % "PRIsVALUE, | ||||
| 		     key); | ||||
| 	rb_raise(rb_eArgError, "wrong exec option"); | ||||
|     } | ||||
|  | @ -4670,13 +4676,13 @@ proc_setpriority(VALUE obj, VALUE which, VALUE who, VALUE prio) | |||
| 
 | ||||
| #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) | ||||
| static int | ||||
| rlimit_resource_name2int(const char *name, int casetype) | ||||
| rlimit_resource_name2int(const char *name, long len, int casetype) | ||||
| { | ||||
|     int resource; | ||||
|     const char *p; | ||||
| #define RESCHECK(r) \ | ||||
|     do { \ | ||||
|         if (STRCASECMP(name, #r) == 0) { \ | ||||
|         if (len == rb_strlen_lit(#r) && STRCASECMP(name, #r) == 0) { \ | ||||
|             resource = RLIMIT_##r; \ | ||||
|             goto found; \ | ||||
|         } \ | ||||
|  | @ -4779,21 +4785,40 @@ rlimit_resource_name2int(const char *name, int casetype) | |||
| } | ||||
| 
 | ||||
| static int | ||||
| rlimit_type_by_hname(const char *name) | ||||
| rlimit_type_by_hname(const char *name, long len) | ||||
| { | ||||
|     return rlimit_resource_name2int(name, 0); | ||||
|     return rlimit_resource_name2int(name, len, 0); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| rlimit_type_by_lname(const char *name) | ||||
| rlimit_type_by_lname(const char *name, long len) | ||||
| { | ||||
|     return rlimit_resource_name2int(name, 1); | ||||
|     return rlimit_resource_name2int(name, len, 1); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| rlimit_type_by_sym(VALUE key) | ||||
| { | ||||
|     VALUE name = rb_sym2str(key); | ||||
|     const char *rname = RSTRING_PTR(name); | ||||
|     long len = RSTRING_LEN(name); | ||||
|     int rtype = -1; | ||||
|     static const char prefix[] = "rlimit_"; | ||||
|     enum {prefix_len = sizeof(prefix)-1}; | ||||
| 
 | ||||
|     if (len > prefix_len && strncmp(prefix, rname, prefix_len) == 0) { | ||||
| 	rtype = rlimit_type_by_lname(rname + prefix_len, len - prefix_len); | ||||
|     } | ||||
| 
 | ||||
|     RB_GC_GUARD(key); | ||||
|     return rtype; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| rlimit_resource_type(VALUE rtype) | ||||
| { | ||||
|     const char *name; | ||||
|     long len; | ||||
|     VALUE v; | ||||
|     int r; | ||||
| 
 | ||||
|  | @ -4801,6 +4826,7 @@ rlimit_resource_type(VALUE rtype) | |||
|       case T_SYMBOL: | ||||
| 	v = rb_sym2str(rtype); | ||||
| 	name = RSTRING_PTR(v); | ||||
| 	len = RSTRING_LEN(v); | ||||
|         break; | ||||
| 
 | ||||
|       default: | ||||
|  | @ -4809,6 +4835,7 @@ rlimit_resource_type(VALUE rtype) | |||
|             rtype = v; | ||||
|       case T_STRING: | ||||
|             name = StringValueCStr(rtype); | ||||
| 	    len = RSTRING_LEN(rtype); | ||||
|             break; | ||||
|         } | ||||
|         /* fall through */ | ||||
|  | @ -4818,11 +4845,11 @@ rlimit_resource_type(VALUE rtype) | |||
|         return NUM2INT(rtype); | ||||
|     } | ||||
| 
 | ||||
|     r = rlimit_type_by_hname(name); | ||||
|     r = rlimit_type_by_hname(name, len); | ||||
|     if (r != -1) | ||||
|         return r; | ||||
| 
 | ||||
|     rb_raise(rb_eArgError, "invalid resource name: %"PRIsVALUE, rtype); | ||||
|     rb_raise(rb_eArgError, "invalid resource name: % "PRIsVALUE, rtype); | ||||
| 
 | ||||
|     UNREACHABLE; | ||||
| } | ||||
|  |  | |||
|  | @ -242,6 +242,22 @@ class TestProcess < Test::Unit::TestCase | |||
|       :rlimit_core=>n, :rlimit_cpu=>3600]) {|io| | ||||
|       assert_equal("[#{n}, #{n}]\n[3600, 3600]", io.read.chomp) | ||||
|     } | ||||
| 
 | ||||
|     assert_raise(ArgumentError) do | ||||
|       system(RUBY, '-e', 'exit',  'rlimit_bogus'.to_sym => 123) | ||||
|     end | ||||
|     assert_separately([],<<-"end;") # [ruby-core:82033] [Bug #13744] | ||||
|       assert(system("#{RUBY}", "-e", | ||||
|                  "exit([3600,3600] == Process.getrlimit(:CPU))", | ||||
|              'rlimit_cpu'.to_sym => 3600)) | ||||
|       assert_raise(ArgumentError) do | ||||
|         system("#{RUBY}", '-e', 'exit',  :rlimit_bogus => 123) | ||||
|       end | ||||
|     end; | ||||
| 
 | ||||
|     assert_raise(ArgumentError, /rlimit_cpu/) { | ||||
|       system(RUBY, '-e', 'exit', "rlimit_cpu\0".to_sym => 3600) | ||||
|     } | ||||
|   end | ||||
| 
 | ||||
|   MANDATORY_ENVS = %w[RUBYLIB] | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #define RUBY_VERSION "2.4.2" | ||||
| #define RUBY_RELEASE_DATE "2017-09-10" | ||||
| #define RUBY_PATCHLEVEL 186 | ||||
| #define RUBY_PATCHLEVEL 187 | ||||
| 
 | ||||
| #define RUBY_RELEASE_YEAR 2017 | ||||
| #define RUBY_RELEASE_MONTH 9 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 nagachika
						nagachika