find_file_safe_and_cache.patch

make find_file_safe and find_file_ext_safe concerning about cache - Yura Sokolov, 12/17/2011 09:07 PM

Download (5.34 KB)

View differences:

file.c
2821 2821
    buflen = RSTRING_LEN(result),\
2822 2822
    pend = p + buflen)
2823 2823

  
2824
#define EXPAND_PATH()\
2825
    if ( !(abs_mode & FEP_DIR_EXPANDED) ) { \
2826
	file_expand_path(dname, Qnil, abs_mode, result); \
2827
    } \
2828
    else { \
2829
	size_t dlen = RSTRING_LEN(dname); \
2830
	BUFCHECK(dlen > buflen); \
2831
	strncpy(buf, RSTRING_PTR(dname), dlen + 1); \
2832
    }
2833

  
2824 2834
VALUE
2825 2835
rb_home_dir(const char *user, VALUE result)
2826 2836
{
......
2865 2875
    return result;
2866 2876
}
2867 2877

  
2878
#define FEP_FILE_ABSOLUTE 1
2879
#define FEP_DIR_EXPANDED 2
2868 2880
static VALUE
2869 2881
file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result)
2870 2882
{
......
2877 2889
    BUFINIT();
2878 2890
    tainted = OBJ_TAINTED(fname);
2879 2891

  
2880
    if (s[0] == '~' && abs_mode == 0) {      /* execute only if NOT absolute_path() */
2892
    if (s[0] == '~' && !(abs_mode & FEP_FILE_ABSOLUTE)) {      /* execute only if NOT absolute_path() */
2881 2893
	long userlen = 0;
2882 2894
	tainted = 1;
2883 2895
	if (isdirsep(s[1]) || s[1] == '\0') {
......
2925 2937
	    /* specified drive, but not full path */
2926 2938
	    int same = 0;
2927 2939
	    if (!NIL_P(dname) && !not_same_drive(dname, s[0])) {
2928
		file_expand_path(dname, Qnil, abs_mode, result);
2940
		EXPAND_PATH();
2929 2941
		BUFINIT();
2930 2942
		if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) {
2931 2943
		    /* ok, same drive */
......
2951 2963
#endif
2952 2964
    else if (!rb_is_absolute_path(s)) {
2953 2965
	if (!NIL_P(dname)) {
2954
	    file_expand_path(dname, Qnil, abs_mode, result);
2966
	    EXPAND_PATH();
2955 2967
	    BUFINIT();
2956 2968
	    rb_enc_associate(result, rb_enc_check(result, fname));
2957 2969
	}
......
3235 3247
rb_file_absolute_path(VALUE fname, VALUE dname)
3236 3248
{
3237 3249
    check_expand_path_args(fname, dname);
3238
    return file_expand_path(fname, dname, 1, EXPAND_PATH_BUFFER());
3250
    return file_expand_path(fname, dname, FEP_FILE_ABSOLUTE, EXPAND_PATH_BUFFER());
3239 3251
}
3240 3252

  
3241 3253
/*
......
5109 5121
    return rb_find_file_ext_safe(filep, ext, rb_safe_level());
5110 5122
}
5111 5123

  
5124
#define GET_LOAD_PATH() \
5125
    if (cached_expanded_load_path) { \
5126
	RB_GC_GUARD(load_path) = rb_get_expanded_load_path(); \
5127
	dirs_mode = FEP_DIR_EXPANDED; \
5128
    } \
5129
    else { \
5130
	RB_GC_GUARD(load_path) = rb_get_load_path(); \
5131
	dirs_mode = 0; \
5132
    }
5133

  
5112 5134
int
5113 5135
rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
5114 5136
{
5115 5137
    const char *f = StringValueCStr(*filep);
5116 5138
    VALUE fname = *filep, load_path, tmp;
5117 5139
    long i, j, fnlen;
5118
    int expanded = 0;
5140
    int expanded = 0, dirs_mode;
5119 5141

  
5120 5142
    if (!ext[0]) return 0;
5121 5143

  
......
5150 5172
	rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f);
5151 5173
    }
5152 5174

  
5153
    RB_GC_GUARD(load_path) = rb_get_load_path();
5175
    GET_LOAD_PATH();
5154 5176
    if (!load_path) return 0;
5155 5177

  
5156 5178
    fname = rb_str_dup(*filep);
......
5164 5186

  
5165 5187
	    RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
5166 5188
	    if (RSTRING_LEN(str) == 0) continue;
5167
	    file_expand_path(fname, str, 0, tmp);
5189
	    file_expand_path(fname, str, dirs_mode, tmp);
5168 5190
	    if (file_load_ok(RSTRING_PTR(tmp))) {
5169 5191
		*filep = copy_path_class(tmp, *filep);
5170 5192
		return (int)(j+1);
......
5188 5210
{
5189 5211
    VALUE tmp, load_path;
5190 5212
    const char *f = StringValueCStr(path);
5191
    int expanded = 0;
5213
    int expanded = 0, dirs_mode;
5192 5214

  
5193 5215
    if (f[0] == '~') {
5194 5216
	tmp = file_expand_path_1(path);
......
5214 5236
	rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f);
5215 5237
    }
5216 5238

  
5217
    RB_GC_GUARD(load_path) = rb_get_load_path();
5239
    GET_LOAD_PATH();
5218 5240
    if (load_path) {
5219 5241
	long i;
5220 5242

  
......
5223 5245
	    VALUE str = RARRAY_PTR(load_path)[i];
5224 5246
	    RB_GC_GUARD(str) = rb_get_path_check(str, safe_level);
5225 5247
	    if (RSTRING_LEN(str) > 0) {
5226
		file_expand_path(path, str, 0, tmp);
5248
		file_expand_path(path, str, dirs_mode, tmp);
5227 5249
		f = RSTRING_PTR(tmp);
5228 5250
		if (file_load_ok(f)) goto found;
5229 5251
	    }
internal.h
109 109

  
110 110
/* load.c */
111 111
VALUE rb_get_load_path(void);
112
VALUE rb_get_expanded_load_path(void);
113
RUBY_EXTERN int cached_expanded_load_path;
112 114

  
113 115
/* math.c */
114 116
VALUE rb_math_atan2(VALUE, VALUE);
load.c
36 36

  
37 37
static VALUE rb_checked_expanded_cache();
38 38
static void rb_set_expanded_cache(VALUE);
39
static int cached_expanded_load_path = 1;
39
int cached_expanded_load_path = 1;
40 40

  
41 41
VALUE
42 42
rb_get_expanded_load_path(void)
......
47 47
	VALUE load_path = rb_get_load_path();
48 48
	long i;
49 49

  
50
	if (!load_path) return 0;
51

  
50 52
	expanded = rb_ary_new2(RARRAY_LEN(load_path));
51 53
	for (i = 0; i < RARRAY_LEN(load_path); ++i) {
52 54
	    VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);