From 9e77e91a13a8ae1d8bb4bba8974da390fbadedc0 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 6 Jun 2003 09:24:59 +0000 Subject: * eval.c (ruby_cleanup): $SAFE is turned off in the finalization. Each END proc should preserve its own $SAFE level. [ruby-core:01119] * marshal.c (marshal_load): remove unused variable "hash". [ruby-core:01120] * hash.c (env_str_new): freeze strings from ENV. [ruby-talk:72860] * array.c (rb_ary_first): optional argument to retrieve first n elements. * array.c (rb_ary_last): optional argument to retrieve last n elements. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3914 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 16 ++++++++++++++++ array.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- eval.c | 1 + hash.c | 63 +++++++++++++++++++++++++++++++++++++++++++-------------------- io.c | 2 +- marshal.c | 3 +-- 6 files changed, 104 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f047bf599..ea243a0cff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,22 @@ Thu Jun 5 21:31:55 2003 Takaaki Uematsu * wince/stdlib.c: add mblen(). +Fri Jun 6 13:30:57 2003 Yukihiro Matsumoto + + * eval.c (ruby_cleanup): $SAFE is turned off in the finalization. + Each END proc should preserve its own $SAFE level. [ruby-core:01119] + + * marshal.c (marshal_load): remove unused variable "hash". + [ruby-core:01120] + + * hash.c (env_str_new): freeze strings from ENV. [ruby-talk:72860] + + * array.c (rb_ary_first): optional argument to retrieve first n + elements. + + * array.c (rb_ary_last): optional argument to retrieve last n + elements. + Thu Jun 5 18:33:46 2003 WATANABE Hirofumi * ext/curses/curses.c (window_s_allocate,curses_finalize): diff --git a/array.c b/array.c index e0b5af8dce..5aa268bd82 100644 --- a/array.c +++ b/array.c @@ -534,19 +534,53 @@ rb_ary_at(ary, pos) } static VALUE -rb_ary_first(ary) +rb_ary_first(argc, argv, ary) + int argc; + VALUE *argv; VALUE ary; { - if (RARRAY(ary)->len == 0) return Qnil; - return RARRAY(ary)->ptr[0]; + if (argc == 0) { + if (RARRAY(ary)->len == 0) return Qnil; + return RARRAY(ary)->ptr[0]; + } + else { + VALUE nv, result; + long n, i; + + rb_scan_args(argc, argv, "01", &nv); + n = NUM2LONG(nv); + if (n > RARRAY(ary)->len) n = RARRAY(ary)->len; + result = rb_ary_new2(n); + for (i=0; iptr[i]); + } + return result; + } } static VALUE -rb_ary_last(ary) +rb_ary_last(argc, argv, ary) + int argc; + VALUE *argv; VALUE ary; { - if (RARRAY(ary)->len == 0) return Qnil; - return RARRAY(ary)->ptr[RARRAY(ary)->len-1]; + if (argc == 0) { + if (RARRAY(ary)->len == 0) return Qnil; + return RARRAY(ary)->ptr[RARRAY(ary)->len-1]; + } + else { + VALUE nv, result; + long n, i; + + rb_scan_args(argc, argv, "01", &nv); + n = NUM2LONG(nv); + if (n > RARRAY(ary)->len) n = RARRAY(ary)->len; + result = rb_ary_new2(n); + for (i=RARRAY(ary)->len-n; n--; i++) { + rb_ary_push(result, RARRAY(ary)->ptr[i]); + } + return result; + } } static VALUE @@ -1984,8 +2018,8 @@ Init_Array() rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1); rb_define_method(rb_cArray, "at", rb_ary_at, 1); rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1); - rb_define_method(rb_cArray, "first", rb_ary_first, 0); - rb_define_method(rb_cArray, "last", rb_ary_last, 0); + rb_define_method(rb_cArray, "first", rb_ary_first, -1); + rb_define_method(rb_cArray, "last", rb_ary_last, -1); rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); rb_define_method(rb_cArray, "<<", rb_ary_push, 1); rb_define_method(rb_cArray, "push", rb_ary_push_m, -1); diff --git a/eval.c b/eval.c index 46245360c6..7a8d1d5ea9 100644 --- a/eval.c +++ b/eval.c @@ -1330,6 +1330,7 @@ ruby_cleanup(ex) { int state; + ruby_safe_level = 0; PUSH_TAG(PROT_NONE); PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { diff --git a/hash.c b/hash.c index ebb1cbcbc0..6207bacdb8 100644 --- a/hash.c +++ b/hash.c @@ -982,6 +982,24 @@ extern char **environ; #define FREE_ENVIRON(e) #endif +static VALUE +env_str_new(ptr, len) + const char *ptr; + long len; +{ + VALUE str = rb_tainted_str_new(ptr, len); + + rb_obj_freeze(str); + return str; +} + +static VALUE +env_str_new2(ptr) + const char *ptr; +{ + return env_str_new(ptr, strlen(ptr)); +} + static VALUE env_delete(obj, name) VALUE obj, name; @@ -996,7 +1014,7 @@ env_delete(obj, name) } val = getenv(nam); if (val) { - VALUE value = rb_tainted_str_new2(val); + VALUE value = env_str_new2(val); ruby_setenv(nam, 0); #ifdef __BORLANDC__ @@ -1040,8 +1058,13 @@ rb_f_getenv(obj, name) #else if (strcmp(nam, "PATH") == 0 && !rb_env_path_tainted()) #endif - return rb_str_new2(env); - return rb_tainted_str_new2(env); + { + VALUE str = rb_str_new2(env); + + rb_obj_freeze(str); + return str; + } + return env_str_new2(env); } return Qnil; } @@ -1079,7 +1102,7 @@ env_fetch(argc, argv) if (strcmp(nam, "PATH") == 0 && !rb_env_path_tainted()) #endif return rb_str_new2(env); - return rb_tainted_str_new2(env); + return env_str_new2(env); } static void @@ -1259,7 +1282,7 @@ env_keys() while (*env) { char *s = strchr(*env, '='); if (s) { - rb_ary_push(ary, rb_tainted_str_new(*env, s-*env)); + rb_ary_push(ary, env_str_new(*env, s-*env)); } env++; } @@ -1277,7 +1300,7 @@ env_each_key(hash) while (*env) { char *s = strchr(*env, '='); if (s) { - rb_yield(rb_tainted_str_new(*env, s-*env)); + rb_yield(env_str_new(*env, s-*env)); } env++; } @@ -1295,7 +1318,7 @@ env_values() while (*env) { char *s = strchr(*env, '='); if (s) { - rb_ary_push(ary, rb_tainted_str_new2(s+1)); + rb_ary_push(ary, env_str_new2(s+1)); } env++; } @@ -1313,7 +1336,7 @@ env_each_value(hash) while (*env) { char *s = strchr(*env, '='); if (s) { - rb_yield(rb_tainted_str_new2(s+1)); + rb_yield(env_str_new2(s+1)); } env++; } @@ -1331,8 +1354,8 @@ env_each(hash) while (*env) { char *s = strchr(*env, '='); if (s) { - rb_yield_values(2, rb_tainted_str_new(*env, s-*env), - rb_tainted_str_new2(s+1)); + rb_yield_values(2, env_str_new(*env, s-*env), + env_str_new2(s+1)); } env++; } @@ -1410,8 +1433,8 @@ env_select(argc, argv) while (*env) { char *s = strchr(*env, '='); if (s) { - VALUE k = rb_tainted_str_new(*env, s-*env); - VALUE v = rb_tainted_str_new2(s+1); + VALUE k = env_str_new(*env, s-*env); + VALUE v = env_str_new2(s+1); if (RTEST(rb_yield_values(2, k, v))) { rb_ary_push(result, rb_assoc_new(k, v)); } @@ -1491,8 +1514,8 @@ env_to_a() while (*env) { char *s = strchr(*env, '='); if (s) { - rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(*env, s-*env), - rb_tainted_str_new2(s+1))); + rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env), + env_str_new2(s+1))); } env++; } @@ -1581,7 +1604,7 @@ env_index(dmy, value) char *s = strchr(*env, '=')+1; if (s) { if (strncmp(s, RSTRING(value)->ptr, strlen(s)) == 0) { - str = rb_tainted_str_new(*env, s-*env-1); + str = env_str_new(*env, s-*env-1); FREE_ENVIRON(environ); return str; } @@ -1608,7 +1631,7 @@ env_indexes(argc, argv) v = getenv(RSTRING(argv[i])->ptr); } if (v) { - RARRAY(indexes)->ptr[i] = rb_tainted_str_new2(v); + RARRAY(indexes)->ptr[i] = env_str_new2(v); } else { RARRAY(indexes)->ptr[i] = Qnil; @@ -1629,8 +1652,8 @@ env_to_hash() while (*env) { char *s = strchr(*env, '='); if (s) { - rb_hash_aset(hash, rb_tainted_str_new(*env, s-*env), - rb_tainted_str_new2(s+1)); + rb_hash_aset(hash, env_str_new(*env, s-*env), + env_str_new2(s+1)); } env++; } @@ -1653,8 +1676,8 @@ env_shift() if (*env) { char *s = strchr(*env, '='); if (s) { - VALUE key = rb_tainted_str_new(*env, s-*env); - VALUE val = rb_tainted_str_new2(getenv(RSTRING(key)->ptr)); + VALUE key = env_str_new(*env, s-*env); + VALUE val = env_str_new2(getenv(RSTRING(key)->ptr)); env_delete(Qnil, key); return rb_assoc_new(key, val); } diff --git a/io.c b/io.c index e5504b02da..79c2ea3461 100644 --- a/io.c +++ b/io.c @@ -411,12 +411,12 @@ io_write(io, str) rb_secure(4); if (TYPE(str) != T_STRING) str = rb_obj_as_string(str); - if (RSTRING(str)->len == 0) return INT2FIX(0); if (TYPE(io) != T_FILE) { /* port is not IO, call write method for it. */ return rb_funcall(io, id_write, 1, str); } + if (RSTRING(str)->len == 0) return INT2FIX(0); GetOpenFile(io, fptr); rb_io_check_writable(fptr); diff --git a/marshal.c b/marshal.c index a0c4680a1e..4718f79209 100644 --- a/marshal.c +++ b/marshal.c @@ -1284,7 +1284,6 @@ marshal_load(argc, argv) int major, minor; VALUE v; struct load_arg arg; - volatile VALUE hash; /* protect from GC */ rb_scan_args(argc, argv, "11", &port, &proc); if (rb_respond_to(port, rb_intern("to_str"))) { @@ -1319,7 +1318,7 @@ marshal_load(argc, argv) } arg.symbol = st_init_numtable(); - arg.data = hash = rb_hash_new(); + arg.data = rb_hash_new(); if (NIL_P(proc)) arg.proc = 0; else arg.proc = proc; v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg); -- cgit v1.2.3