-
-
Save burke/95f05cc9878e8564bad76eb0fed9876e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/file.c b/file.c | |
index e299244..0979fb9 100644 | |
--- a/file.c | |
+++ b/file.c | |
@@ -5800,11 +5800,11 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level) | |
VALUE | |
rb_find_file(VALUE path) | |
{ | |
- return rb_find_file_safe(path, rb_safe_level()); | |
+ return rb_find_file_safe(path, rb_safe_level(), NULL); | |
} | |
VALUE | |
-rb_find_file_safe(VALUE path, int safe_level) | |
+rb_find_file_safe(VALUE path, int safe_level, int * defer_load_check) | |
{ | |
VALUE tmp, load_path; | |
const char *f = StringValueCStr(path); | |
@@ -5824,7 +5824,11 @@ rb_find_file_safe(VALUE path, int safe_level) | |
if (safe_level >= 1 && !fpath_check(path)) { | |
rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); | |
} | |
- if (!rb_file_load_ok(f)) return 0; | |
+ if (defer_load_check != NULL) { | |
+ *defer_load_check = 1; | |
+ } else if (!rb_file_load_ok(f)) { | |
+ return 0; | |
+ } | |
if (!expanded) | |
path = copy_path_class(file_expand_path_1(path), path); | |
return path; | |
diff --git a/include/ruby/intern.h b/include/ruby/intern.h | |
index aec2d52..ce11e66 100644 | |
--- a/include/ruby/intern.h | |
+++ b/include/ruby/intern.h | |
@@ -478,7 +478,7 @@ VALUE rb_file_s_absolute_path(int, const VALUE *); | |
VALUE rb_file_absolute_path(VALUE, VALUE); | |
VALUE rb_file_dirname(VALUE fname); | |
int rb_find_file_ext_safe(VALUE*, const char* const*, int); | |
-VALUE rb_find_file_safe(VALUE, int); | |
+VALUE rb_find_file_safe(VALUE, int, int*); | |
int rb_find_file_ext(VALUE*, const char* const*); | |
VALUE rb_find_file(VALUE); | |
VALUE rb_file_directory_p(VALUE,VALUE); | |
diff --git a/load.c b/load.c | |
index 70c7345..1f3444d 100644 | |
--- a/load.c | |
+++ b/load.c | |
@@ -578,7 +578,7 @@ NORETURN(static void load_failed(VALUE)); | |
const rb_iseq_t *rb_iseq_load_iseq(VALUE fname); | |
static int | |
-rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap) | |
+rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap, int deferred_load_check) | |
{ | |
int state; | |
volatile VALUE wrapper = th->top_wrapper; | |
@@ -611,6 +611,14 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap) | |
/* OK */ | |
} | |
else { | |
+ if (deferred_load_check) { | |
+ const char *f = StringValueCStr(fname); | |
+ if (!rb_file_load_ok(f)) { | |
+ rb_protect((VALUE (*)(VALUE))load_failed, fname, &state); | |
+ goto error; | |
+ } | |
+ } | |
+ | |
th->mild_compile_error++; | |
node = (NODE *)rb_load_file_str(fname); | |
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), NULL); | |
@@ -618,6 +626,7 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap) | |
} | |
rb_iseq_eval(iseq); | |
} | |
+error: | |
TH_POP_TAG(); | |
#if !defined __GNUC__ | |
@@ -646,7 +655,7 @@ static void | |
rb_load_internal(VALUE fname, int wrap) | |
{ | |
rb_thread_t *curr_th = GET_THREAD(); | |
- int state = rb_load_internal0(curr_th, fname, wrap); | |
+ int state = rb_load_internal0(curr_th, fname, wrap, 0); | |
if (state) { | |
if (state == TAG_RAISE) rb_exc_raise(curr_th->errinfo); | |
JUMP_TAG(state); | |
@@ -678,7 +687,7 @@ rb_load_protect(VALUE fname, int wrap, int *state) | |
path = file_to_load(fname); | |
} | |
POP_TAG(); | |
- if (!status) status = rb_load_internal0(GET_THREAD(), path, wrap); | |
+ if (!status) status = rb_load_internal0(GET_THREAD(), path, wrap, 0); | |
if (state) | |
*state = status; | |
} | |
@@ -848,7 +857,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level) | |
{ | |
VALUE tmp; | |
char *ext, *ftptr; | |
- int type, ft = 0; | |
+ int type, ft, defer_load_check = 0; | |
const char *loading; | |
*path = 0; | |
@@ -859,11 +868,14 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level) | |
if (loading) *path = rb_filesystem_str_new_cstr(loading); | |
return 'r'; | |
} | |
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { | |
+ if ((tmp = rb_find_file_safe(fname, safe_level, &defer_load_check)) != 0) { | |
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); | |
if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading) | |
*path = tmp; | |
- return 'r'; | |
+ if (defer_load_check) | |
+ return 'd'; | |
+ else | |
+ return 'r'; | |
} | |
return 0; | |
} | |
@@ -884,7 +896,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level) | |
#else | |
rb_str_cat2(tmp, DLEXT); | |
OBJ_FREEZE(tmp); | |
- if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) { | |
+ if ((tmp = rb_find_file_safe(tmp, safe_level, NULL)) != 0) { | |
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); | |
if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading) | |
*path = tmp; | |
@@ -897,7 +909,7 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level) | |
if (loading) *path = rb_filesystem_str_new_cstr(loading); | |
return 's'; | |
} | |
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { | |
+ if ((tmp = rb_find_file_safe(fname, safe_level, NULL)) != 0) { | |
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); | |
if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading) | |
*path = tmp; | |
@@ -994,8 +1006,12 @@ rb_require_internal(VALUE fname, int safe) | |
} | |
else { | |
switch (found) { | |
+ case 'd': | |
+ state = rb_load_internal0(th, path, 0, 1); | |
+ break; | |
+ | |
case 'r': | |
- state = rb_load_internal0(th, path, 0); | |
+ state = rb_load_internal0(th, path, 0, 0); | |
break; | |
case 's': |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment