diff options
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | eval.c | 42 | ||||
-rw-r--r-- | file.c | 91 | ||||
-rw-r--r-- | io.c | 9 | ||||
-rw-r--r-- | regex.c | 58 |
5 files changed, 164 insertions, 58 deletions
@@ -1,3 +1,25 @@ +Mon Jun 18 17:38:50 2001 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_f_require): searches ".rb" and ".so" at the same + time. previous behavior (search ".rb", then ".so") has a + security risk (ruby-bugs#PR140). + +Mon Jun 18 00:43:20 2001 Yukihiro Matsumoto <matz@ruby-lang.org> + + * regex.c (re_compile_pattern): avoid pushing unnecessary + option_set. + +Sat Jun 16 10:58:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_load): tainted string is OK if wrapped *and* + $SAFE >= 4. + +Thu Jun 14 16:27:07 2001 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_thread_start_0): should not nail down higher blocks + before preserving original context (i.e. should not alter + original context). + Tue Jun 12 14:24:02 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp> * lib/mkmf.rb: target_prefix is only for installation, not for @@ -5128,7 +5128,12 @@ rb_load(fname, wrap) NODE *saved_cref = ruby_cref; TMP_PROTECT; - Check_SafeStr(fname); + if (wrap && ruby_safe_level >= 4) { + Check_Type(fname, T_STRING); + } + else { + Check_SafeStr(fname); + } file = rb_find_file(RSTRING(fname)->ptr); if (!file) { rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); @@ -5373,28 +5378,20 @@ rb_f_require(obj, fname) } buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5); strcpy(buf, RSTRING(fname)->ptr); - strcat(buf, ".rb"); - if (rb_find_file(buf)) { + switch (rb_find_file_noext(buf)) { + case 0: + break; + + case 1: fname = rb_str_new2(buf); - feature = buf; + file = feature = buf; goto load_rb; - } - strcpy(buf, RSTRING(fname)->ptr); - strcat(buf, DLEXT); - file = rb_find_file(buf); - if (file) { - feature = buf; - goto load_dyna; - } -#ifdef DLEXT2 - strcpy(buf, RSTRING(fname)->ptr); - strcat(buf, DLEXT2); - file = rb_find_file(buf); - if (file) { + + default: feature = buf; + file = rb_find_file(buf); goto load_dyna; } -#endif rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); @@ -8145,6 +8142,11 @@ rb_thread_start_0(fn, arg, th_arg) } #endif + FL_SET(ruby_scope, SCOPE_SHARED); + if (THREAD_SAVE_CONTEXT(curr_thread)) { + return thread; + } + if (ruby_block) { /* should nail down higher scopes */ struct BLOCK dummy; @@ -8153,10 +8155,6 @@ rb_thread_start_0(fn, arg, th_arg) saved_block = ruby_block = dummy.prev; } scope_dup(ruby_scope); - FL_SET(ruby_scope, SCOPE_SHARED); - if (THREAD_SAVE_CONTEXT(curr_thread)) { - return thread; - } if (!th->next) { /* merge in thread list */ @@ -2124,40 +2124,100 @@ is_macos_native_path(path) } #endif +static char* +file_load_ok(file) + char *file; +{ + FILE *f; + + f = fopen(file, "r"); + if (f == NULL) return 0; + fclose(f); + return file; +} + +extern VALUE rb_load_path; + +int +rb_find_file_noext(file) + char *file; +{ + char *path, *e, *found; + char *fend = file + strlen(file); + VALUE fname; + int i, j; + + static char *ext[] = { + ".rb", DLEXT, +#ifdef DLEXT2 + DLEXT2, +#endif + 0 + }; + + if (file[0] == '~') { + fname = rb_str_new2(file); + fname = rb_file_s_expand_path(1, &fname); + file = STR2CSTR(fname); + } + + if (is_absolute_path(file)) { + for (i=0; ext[i]; i++) { + strcpy(fend, ext[i]); + if (file_load_ok(file)) return i+1; + } + return 0; + } + + if (!rb_load_path) return 0; + + Check_Type(rb_load_path, T_ARRAY); + for (i=0;i<RARRAY(rb_load_path)->len;i++) { + VALUE str = RARRAY(rb_load_path)->ptr[i]; + + Check_SafeStr(str); + path = RSTRING(str)->ptr; + for (j=0; ext[j]; j++) { + strcpy(fend, ext[j]); + found = dln_find_file(file, path); + if (found && file_load_ok(found)) return j+1; + } + } + return 0; +} + char* rb_find_file(file) char *file; { - extern VALUE rb_load_path; volatile VALUE vpath; VALUE fname; char *path; struct stat st; + if (file[0] == '~') { + fname = rb_str_new2(file); + fname = rb_file_s_expand_path(1, &fname); + if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { + rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); + } + file = STR2CSTR(fname); + } + #if defined(__MACOS__) || defined(riscos) if (is_macos_native_path(file)) { - FILE *f; - if (rb_safe_level() >= 2 && !rb_path_check(file)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); } - f= fopen(file, "r"); - if (f == NULL) return 0; - fclose(f); - return file; + return file_load_ok(file); } #endif if (is_absolute_path(file)) { - FILE *f; - if (rb_safe_level() >= 2 && !rb_path_check(file)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", file); } - f = fopen(file, "r"); - if (f == NULL) return 0; - fclose(f); - return file; + return file_load_ok(file); } if (file[0] == '~') { @@ -2192,10 +2252,7 @@ rb_find_file(file) } path = dln_find_file(file, path); - if (path && stat(path, &st) == 0) { - return path; - } - return 0; + return file_load_ok(path); } static void @@ -3346,12 +3346,17 @@ static void opt_i_set(val) VALUE val; { - if (ruby_inplace_mode) free(ruby_inplace_mode); + long len; + if (!RTEST(val)) { + if (ruby_inplace_mode) free(ruby_inplace_mode); ruby_inplace_mode = 0; return; } - ruby_inplace_mode = strdup(STR2CSTR(val)); + STR2CSTR(val); + len = RSTRING(val)->len; + REALLOC_N(ruby_inplace_mode, char, len + 1); + ((char *)MEMCPY(ruby_inplace_mode, RSTRING(val)->ptr, char, len))[len] = '\0'; } void @@ -1260,7 +1260,6 @@ re_compile_pattern(pattern, size, bufp) int had_char_class = 0; int options = bufp->options; - int old_options = 0; bufp->fastmap_accurate = 0; bufp->must = 0; @@ -1683,11 +1682,15 @@ re_compile_pattern(pattern, size, bufp) break; case '(': - old_options = options; + { + int old_options = options; + int push_option = 0; + int casefold = 0; + PATFETCH(c); if (c == '?') { int negative = 0; - int push_option = 0; + PATFETCH_RAW(c); switch (c) { case 'x': case 'p': case 'm': case 'i': case '-': @@ -1736,13 +1739,12 @@ re_compile_pattern(pattern, size, bufp) if (negative) { if (options&RE_OPTION_IGNORECASE) { options &= ~RE_OPTION_IGNORECASE; - BUFPUSH(casefold_off); } } else if (!(options&RE_OPTION_IGNORECASE)) { options |= RE_OPTION_IGNORECASE; - BUFPUSH(casefold_on); } + casefold = 1; break; default: @@ -1774,16 +1776,24 @@ re_compile_pattern(pattern, size, bufp) default: FREE_AND_RETURN(stackb, "undefined (?...) sequence"); } + } + else { + PATUNFETCH; + c = '('; + } + if (c == '#') { if (push_option) { BUFPUSH(option_set); BUFPUSH(options); } + if (casefold) { + if (options & RE_OPTION_IGNORECASE) + BUFPUSH(casefold_on); + else + BUFPUSH(casefold_off); } - else { - PATUNFETCH; - c = '('; + break; } - if (c == '#') break; if (stackp+8 >= stacke) { DOUBLE_STACK(int); } @@ -1826,24 +1836,28 @@ re_compile_pattern(pattern, size, bufp) default: break; } + if (push_option) { + BUFPUSH(option_set); + BUFPUSH(options); + } + if (casefold) { + if (options & RE_OPTION_IGNORECASE) + BUFPUSH(casefold_on); + else + BUFPUSH(casefold_off); + } *stackp++ = c; *stackp++ = old_options; fixup_alt_jump = 0; laststart = 0; begalt = b; + } break; case ')': if (stackp == stackb) FREE_AND_RETURN(stackb, "unmatched )"); - if (options != stackp[-1]) { - if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) { - BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on); - } - BUFPUSH(option_set); - BUFPUSH(stackp[-1]); - } pending_exact = 0; if (fixup_alt_jump) { /* Push a dummy failure point at the end of the @@ -1856,6 +1870,15 @@ re_compile_pattern(pattern, size, bufp) to `fixup_alt_jump', in the `handle_alt' case below. */ store_jump(fixup_alt_jump, jump, b); } + if (options != stackp[-1]) { + if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) { + BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on); + } + if ((options ^ stackp[-1]) != RE_OPTION_IGNORECASE) { + BUFPUSH(option_set); + BUFPUSH(stackp[-1]); + } + } p0 = b; options = *--stackp; switch (c = *--stackp) { @@ -3241,7 +3264,8 @@ re_search(bufp, string, size, startpos, range, regs) } if (startpos > size) return -1; - if (anchor && size > 0 && startpos == size) return -1; + if ((anchor || !bufp->can_be_null) && size > 0 && startpos == size) + return -1; val = re_match(bufp, string, size, startpos, regs); if (val >= 0) return startpos; if (val == -2) return -2; |