mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (rb_feature_p): match by classified suffix.
* eval.c (rb_require_safe): require library in the specified safe level. * variable.c (rb_autoload, rb_autoload_load): restore safe level when autoload was called. [ruby-dev:21338] * intern.h: prototypes; rb_require_safe. * test/runner.rb: accept non-option arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1b8c124c8d
commit
4de0bb549b
5 changed files with 203 additions and 162 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
Mon Oct 13 23:57:29 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_feature_p): match by classified suffix.
|
||||||
|
|
||||||
|
* eval.c (rb_require_safe): require library in the specified safe
|
||||||
|
level.
|
||||||
|
|
||||||
|
* variable.c (rb_autoload, rb_autoload_load): restore safe level
|
||||||
|
when autoload was called. [ruby-dev:21338]
|
||||||
|
|
||||||
|
* intern.h: prototypes; rb_require_safe.
|
||||||
|
|
||||||
|
Mon Oct 13 23:57:29 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* test/runner.rb: accept non-option arguments.
|
||||||
|
|
||||||
Mon Oct 13 20:49:51 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Mon Oct 13 20:49:51 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (str_new4): should not preserve FL_TAINT status in the
|
* string.c (str_new4): should not preserve FL_TAINT status in the
|
||||||
|
|
288
eval.c
288
eval.c
|
@ -5739,6 +5739,8 @@ rb_mod_module_eval(argc, argv, mod)
|
||||||
|
|
||||||
VALUE rb_load_path;
|
VALUE rb_load_path;
|
||||||
|
|
||||||
|
NORETURN(static void load_failed _((VALUE)));
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_load(fname, wrap)
|
rb_load(fname, wrap)
|
||||||
VALUE fname;
|
VALUE fname;
|
||||||
|
@ -5761,7 +5763,7 @@ rb_load(fname, wrap)
|
||||||
}
|
}
|
||||||
tmp = rb_find_file(fname);
|
tmp = rb_find_file(fname);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
|
load_failed(fname);
|
||||||
}
|
}
|
||||||
fname = tmp;
|
fname = tmp;
|
||||||
|
|
||||||
|
@ -5871,49 +5873,47 @@ VALUE ruby_dln_librefs;
|
||||||
static VALUE rb_features;
|
static VALUE rb_features;
|
||||||
static st_table *loading_tbl;
|
static st_table *loading_tbl;
|
||||||
|
|
||||||
static int
|
#define IS_SOEXT(e) (strcmp(e, ".so") == 0 || strcmp(e, ".o") == 0)
|
||||||
rb_feature_p(feature, wait)
|
#ifdef DLEXT2
|
||||||
const char *feature;
|
#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0 || strcmp(e, DLEXT2) == 0)
|
||||||
int wait;
|
#else
|
||||||
|
#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *
|
||||||
|
rb_feature_p(feature, ext, rb)
|
||||||
|
const char *feature, *ext;
|
||||||
|
int rb;
|
||||||
{
|
{
|
||||||
VALUE v;
|
VALUE v;
|
||||||
char *f;
|
char *f, *e;
|
||||||
long i, len = strlen(feature);
|
long i, len, elen;
|
||||||
|
|
||||||
|
if (ext) {
|
||||||
|
len = ext - feature;
|
||||||
|
elen = strlen(ext);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = strlen(feature);
|
||||||
|
elen = 0;
|
||||||
|
}
|
||||||
for (i = 0; i < RARRAY(rb_features)->len; ++i) {
|
for (i = 0; i < RARRAY(rb_features)->len; ++i) {
|
||||||
v = RARRAY(rb_features)->ptr[i];
|
v = RARRAY(rb_features)->ptr[i];
|
||||||
f = StringValuePtr(v);
|
f = StringValuePtr(v);
|
||||||
if (strcmp(f, feature) == 0) {
|
if (strncmp(f, feature, len) != 0) continue;
|
||||||
goto load_wait;
|
if (!*(e = f + len)) {
|
||||||
|
if (ext) continue;
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
if (strncmp(f, feature, len) == 0) {
|
if (*e != '.') continue;
|
||||||
if (strcmp(f+len, ".so") == 0) {
|
if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
|
||||||
return Qtrue;
|
return e;
|
||||||
}
|
}
|
||||||
if (strcmp(f+len, ".rb") == 0) {
|
if ((rb || !ext) && (strcmp(e, ".rb") == 0)) {
|
||||||
if (wait) goto load_wait;
|
return e;
|
||||||
return Qtrue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
return Qfalse;
|
|
||||||
|
|
||||||
load_wait:
|
|
||||||
if (loading_tbl) {
|
|
||||||
char *ext = strrchr(f, '.');
|
|
||||||
if (ext && strcmp(ext, ".rb") == 0) {
|
|
||||||
rb_thread_t th;
|
|
||||||
|
|
||||||
while (st_lookup(loading_tbl, (st_data_t)f, (st_data_t *)&th)) {
|
|
||||||
if (th == curr_thread) {
|
|
||||||
return Qtrue;
|
|
||||||
}
|
|
||||||
CHECK_INTS;
|
|
||||||
rb_thread_schedule();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Qtrue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *const loadable_ext[] = {
|
static const char *const loadable_ext[] = {
|
||||||
|
@ -5928,14 +5928,7 @@ int
|
||||||
rb_provided(feature)
|
rb_provided(feature)
|
||||||
const char *feature;
|
const char *feature;
|
||||||
{
|
{
|
||||||
VALUE f = rb_str_new2(feature);
|
return rb_feature_p(feature, 0, Qfalse) ? Qtrue : Qfalse;
|
||||||
|
|
||||||
if (strrchr(feature, '.') == 0) {
|
|
||||||
if (rb_find_file_ext(&f, loadable_ext) == 0) {
|
|
||||||
return rb_feature_p(feature, Qfalse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rb_feature_p(RSTRING(f)->ptr, Qfalse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -5952,76 +5945,83 @@ rb_provide(feature)
|
||||||
rb_provide_feature(rb_str_new2(feature));
|
rb_provide_feature(rb_str_new2(feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN(static void load_failed _((VALUE)));
|
static void
|
||||||
static VALUE load_dyna _((VALUE, VALUE));
|
load_wait(ftptr)
|
||||||
static VALUE load_rb _((VALUE, VALUE));
|
char *ftptr;
|
||||||
|
{
|
||||||
|
st_data_t th;
|
||||||
|
|
||||||
|
if (!loading_tbl) return;
|
||||||
|
if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return;
|
||||||
|
if ((rb_thread_t)th == curr_thread) return;
|
||||||
|
do {
|
||||||
|
CHECK_INTS;
|
||||||
|
rb_thread_schedule();
|
||||||
|
} while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_f_require(obj, fname)
|
rb_f_require(obj, fname)
|
||||||
VALUE obj, fname;
|
VALUE obj, fname;
|
||||||
{
|
{
|
||||||
VALUE feature, tmp;
|
return rb_require_safe(fname, ruby_safe_level);
|
||||||
char *ext; /* OK */
|
}
|
||||||
|
|
||||||
if (OBJ_TAINTED(fname)) {
|
static int
|
||||||
rb_check_safe_obj(fname);
|
search_required(fname, featurep, path)
|
||||||
}
|
VALUE fname, *featurep, *path;
|
||||||
StringValue(fname);
|
{
|
||||||
ext = strrchr(RSTRING(fname)->ptr, '.');
|
VALUE tmp;
|
||||||
if (ext && strchr(ext, '/')) ext = 0;
|
char *ext, *ftptr;
|
||||||
if (ext) {
|
|
||||||
|
*featurep = fname;
|
||||||
|
*path = 0;
|
||||||
|
ext = strrchr(ftptr = RSTRING(fname)->ptr, '.');
|
||||||
|
if (ext && !strchr(ext, '/')) {
|
||||||
if (strcmp(".rb", ext) == 0) {
|
if (strcmp(".rb", ext) == 0) {
|
||||||
feature = rb_str_dup(fname);
|
if (rb_feature_p(ftptr, ext, Qtrue)) return 'r';
|
||||||
tmp = rb_find_file(fname);
|
if (*path = rb_find_file(fname)) return 'r';
|
||||||
if (tmp) {
|
return 0;
|
||||||
return load_rb(feature, tmp);
|
|
||||||
}
|
}
|
||||||
load_failed(fname);
|
else if (IS_SOEXT(ext)) {
|
||||||
}
|
if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
|
||||||
else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) {
|
|
||||||
tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
|
tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
|
||||||
|
*featurep = tmp;
|
||||||
#ifdef DLEXT2
|
#ifdef DLEXT2
|
||||||
if (rb_find_file_ext(&tmp, loadable_ext+1)) {
|
if (rb_find_file_ext(&tmp, loadable_ext+1)) {
|
||||||
return load_dyna(tmp, rb_find_file(tmp));
|
*path = rb_find_file(tmp);
|
||||||
|
return 's';
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
feature = tmp;
|
|
||||||
rb_str_cat2(tmp, DLEXT);
|
rb_str_cat2(tmp, DLEXT);
|
||||||
tmp = rb_find_file(tmp);
|
if (*path = rb_find_file(tmp)) {
|
||||||
if (tmp) {
|
return 's';
|
||||||
return load_dyna(feature, tmp);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (strcmp(DLEXT, ext) == 0) {
|
else if (IS_DLEXT(ext)) {
|
||||||
tmp = rb_find_file(fname);
|
if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
|
||||||
if (tmp) {
|
if (*path = rb_find_file(fname)) return 's';
|
||||||
return load_dyna(fname, tmp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DLEXT2
|
if ((ext = rb_feature_p(ftptr, 0, Qfalse)) != 0) {
|
||||||
else if (strcmp(DLEXT2, ext) == 0) {
|
return strcmp(ext, ".rb") == 0 ? 'r' : 's';
|
||||||
tmp = rb_find_file(fname);
|
|
||||||
if (tmp) {
|
|
||||||
return load_dyna(fname, tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
tmp = fname;
|
tmp = fname;
|
||||||
switch (rb_find_file_ext(&tmp, loadable_ext)) {
|
switch (rb_find_file_ext(&tmp, loadable_ext)) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
return 0;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return load_rb(tmp, tmp);
|
*featurep = tmp;
|
||||||
|
*path = rb_find_file(tmp);
|
||||||
|
return 'r';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return load_dyna(tmp, rb_find_file(tmp));
|
*featurep = tmp;
|
||||||
|
*path = rb_find_file(tmp);
|
||||||
|
return 's';
|
||||||
}
|
}
|
||||||
if (!rb_feature_p(RSTRING(fname)->ptr, Qfalse))
|
|
||||||
load_failed(fname);
|
|
||||||
return Qfalse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -6031,85 +6031,101 @@ load_failed(fname)
|
||||||
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
|
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
load_dyna(feature, fname)
|
rb_require_safe(fname, safe)
|
||||||
VALUE feature, fname;
|
VALUE fname;
|
||||||
|
int safe;
|
||||||
{
|
{
|
||||||
|
VALUE result = Qnil;
|
||||||
int state;
|
int state;
|
||||||
volatile int safe = ruby_safe_level;
|
struct {
|
||||||
|
NODE *node;
|
||||||
|
ID func;
|
||||||
|
int vmode, safe;
|
||||||
|
} volatile saved;
|
||||||
|
char *volatile ftptr = 0;
|
||||||
|
|
||||||
if (rb_feature_p(RSTRING(feature)->ptr, Qfalse))
|
if (OBJ_TAINTED(fname)) {
|
||||||
return Qfalse;
|
rb_check_safe_obj(fname);
|
||||||
rb_provide_feature(feature);
|
}
|
||||||
{
|
StringValue(fname);
|
||||||
volatile int old_vmode = scope_vmode;
|
saved.vmode = scope_vmode;
|
||||||
NODE *const volatile old_node = ruby_current_node;
|
saved.node = ruby_current_node;
|
||||||
const volatile ID old_func = ruby_frame->last_func;
|
saved.func = ruby_frame->last_func;
|
||||||
|
saved.safe = ruby_safe_level;
|
||||||
ruby_safe_level = 0;
|
|
||||||
ruby_current_node = 0;
|
|
||||||
ruby_sourcefile = rb_source_filename(RSTRING(fname)->ptr);
|
|
||||||
ruby_sourceline = 0;
|
|
||||||
ruby_frame->last_func = 0;
|
|
||||||
PUSH_TAG(PROT_NONE);
|
PUSH_TAG(PROT_NONE);
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
void *handle;
|
VALUE feature, path;
|
||||||
|
long handle;
|
||||||
|
int found;
|
||||||
|
|
||||||
SCOPE_SET(SCOPE_PUBLIC);
|
|
||||||
handle = dln_load(RSTRING(fname)->ptr);
|
|
||||||
rb_ary_push(ruby_dln_librefs, LONG2NUM((long)handle));
|
|
||||||
}
|
|
||||||
POP_TAG();
|
|
||||||
ruby_current_node = old_node;
|
|
||||||
ruby_set_current_source();
|
|
||||||
ruby_frame->last_func = old_func;
|
|
||||||
SCOPE_SET(old_vmode);
|
|
||||||
}
|
|
||||||
ruby_safe_level = safe;
|
ruby_safe_level = safe;
|
||||||
if (state) JUMP_TAG(state);
|
found = search_required(fname, &feature, &path);
|
||||||
ruby_errinfo = Qnil;
|
if (found) {
|
||||||
|
ftptr = RSTRING(feature)->ptr;
|
||||||
return Qtrue;
|
if (!path) {
|
||||||
|
load_wait(ftptr);
|
||||||
|
result = Qfalse;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
static VALUE
|
|
||||||
load_rb(feature, fname)
|
|
||||||
VALUE feature, fname;
|
|
||||||
{
|
|
||||||
int state;
|
|
||||||
char *ftptr;
|
|
||||||
volatile int safe = ruby_safe_level;
|
|
||||||
|
|
||||||
if (rb_feature_p(RSTRING(feature)->ptr, Qtrue))
|
|
||||||
return Qfalse;
|
|
||||||
ruby_safe_level = 0;
|
ruby_safe_level = 0;
|
||||||
rb_provide_feature(feature);
|
rb_provide_feature(feature);
|
||||||
|
switch (found) {
|
||||||
|
case 'r':
|
||||||
/* loading ruby library should be serialized. */
|
/* loading ruby library should be serialized. */
|
||||||
if (!loading_tbl) {
|
if (!loading_tbl) {
|
||||||
loading_tbl = st_init_strtable();
|
loading_tbl = st_init_strtable();
|
||||||
}
|
}
|
||||||
/* partial state */
|
/* partial state */
|
||||||
ftptr = ruby_strdup(RSTRING(feature)->ptr);
|
st_insert(loading_tbl,
|
||||||
st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
|
(st_data_t)(ftptr = ruby_strdup(ftptr)),
|
||||||
|
(st_data_t)curr_thread);
|
||||||
|
if (feature == fname && !OBJ_FROZEN(feature)) {
|
||||||
|
feature = rb_str_dup(feature);
|
||||||
|
OBJ_FREEZE(feature);
|
||||||
|
}
|
||||||
|
rb_load(path, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
PUSH_TAG(PROT_NONE);
|
case 's':
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
ruby_current_node = 0;
|
||||||
rb_load(fname, 0);
|
ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
|
||||||
|
ruby_sourceline = 0;
|
||||||
|
ruby_frame->last_func = 0;
|
||||||
|
SCOPE_SET(SCOPE_PUBLIC);
|
||||||
|
handle = (long)dln_load(RSTRING(path)->ptr);
|
||||||
|
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = Qtrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
st_delete(loading_tbl, (st_data_t *)&ftptr, 0); /* loading done */
|
ruby_current_node = saved.node;
|
||||||
|
ruby_set_current_source();
|
||||||
|
ruby_frame->last_func = saved.func;
|
||||||
|
SCOPE_SET(saved.vmode);
|
||||||
|
ruby_safe_level = saved.safe;
|
||||||
|
if (ftptr) {
|
||||||
|
if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
|
||||||
free(ftptr);
|
free(ftptr);
|
||||||
ruby_safe_level = safe;
|
}
|
||||||
|
}
|
||||||
if (state) JUMP_TAG(state);
|
if (state) JUMP_TAG(state);
|
||||||
|
if (NIL_P(result)) {
|
||||||
|
load_failed(fname);
|
||||||
|
}
|
||||||
|
ruby_errinfo = Qnil;
|
||||||
|
|
||||||
return Qtrue;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_require(fname)
|
rb_require(fname)
|
||||||
const char *fname;
|
const char *fname;
|
||||||
{
|
{
|
||||||
return rb_f_require(Qnil, rb_str_new2(fname));
|
return rb_require_safe(rb_str_new2(fname), ruby_safe_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
1
intern.h
1
intern.h
|
@ -176,6 +176,7 @@ NORETURN(void rb_jump_tag _((int)));
|
||||||
int rb_provided _((const char*));
|
int rb_provided _((const char*));
|
||||||
void rb_provide _((const char*));
|
void rb_provide _((const char*));
|
||||||
VALUE rb_f_require _((VALUE, VALUE));
|
VALUE rb_f_require _((VALUE, VALUE));
|
||||||
|
VALUE rb_require_safe _((VALUE, int));
|
||||||
void rb_obj_call_init _((VALUE, int, VALUE*));
|
void rb_obj_call_init _((VALUE, int, VALUE*));
|
||||||
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
||||||
VALUE rb_block_proc _((void));
|
VALUE rb_block_proc _((void));
|
||||||
|
|
|
@ -4,4 +4,7 @@ rcsid = %w$Id$
|
||||||
Version = rcsid[2].scan(/\d+/).collect!(&method(:Integer)).freeze
|
Version = rcsid[2].scan(/\d+/).collect!(&method(:Integer)).freeze
|
||||||
Release = rcsid[3].freeze
|
Release = rcsid[3].freeze
|
||||||
|
|
||||||
Test::Unit::AutoRunner.run(false, File.dirname(__FILE__))
|
runner = Test::Unit::AutoRunner.new(true)
|
||||||
|
runner.to_run.concat(ARGV)
|
||||||
|
runner.to_run << File.dirname(__FILE__) if runner.to_run.empty?
|
||||||
|
runner.run
|
||||||
|
|
27
variable.c
27
variable.c
|
@ -1147,7 +1147,7 @@ rb_autoload(mod, id, file)
|
||||||
ID id;
|
ID id;
|
||||||
const char *file;
|
const char *file;
|
||||||
{
|
{
|
||||||
VALUE av;
|
VALUE av, fn;
|
||||||
struct st_table *tbl;
|
struct st_table *tbl;
|
||||||
|
|
||||||
if (!rb_is_const_id(id)) {
|
if (!rb_is_const_id(id)) {
|
||||||
|
@ -1170,21 +1170,25 @@ rb_autoload(mod, id, file)
|
||||||
st_add_direct(tbl, autoload, av);
|
st_add_direct(tbl, autoload, av);
|
||||||
DATA_PTR(av) = tbl = st_init_numtable();
|
DATA_PTR(av) = tbl = st_init_numtable();
|
||||||
}
|
}
|
||||||
st_insert(tbl, id, rb_str_new2(file));
|
fn = rb_str_new2(file);
|
||||||
|
FL_UNSET(fn, FL_TAINT);
|
||||||
|
OBJ_FREEZE(fn);
|
||||||
|
st_insert(tbl, id, (st_data_t)rb_node_newnode(NODE_MEMO, fn, ruby_safe_level, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static NODE*
|
||||||
autoload_delete(mod, id)
|
autoload_delete(mod, id)
|
||||||
VALUE mod;
|
VALUE mod;
|
||||||
ID id;
|
ID id;
|
||||||
{
|
{
|
||||||
VALUE val, file = Qnil;
|
VALUE val;
|
||||||
|
st_data_t load = 0;
|
||||||
|
|
||||||
st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);
|
st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);
|
||||||
if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
|
if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
|
||||||
struct st_table *tbl = check_autoload_table(val);
|
struct st_table *tbl = check_autoload_table(val);
|
||||||
|
|
||||||
if (!st_delete(tbl, (st_data_t*)&id, &file)) file = Qnil;
|
st_delete(tbl, (st_data_t*)&id, &load);
|
||||||
|
|
||||||
if (tbl->num_entries == 0) {
|
if (tbl->num_entries == 0) {
|
||||||
DATA_PTR(val) = 0;
|
DATA_PTR(val) = 0;
|
||||||
|
@ -1196,7 +1200,7 @@ autoload_delete(mod, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return (NODE *)load;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1205,13 +1209,12 @@ rb_autoload_load(klass, id)
|
||||||
ID id;
|
ID id;
|
||||||
{
|
{
|
||||||
VALUE file;
|
VALUE file;
|
||||||
|
NODE *load = autoload_delete(klass, id);
|
||||||
|
|
||||||
file = autoload_delete(klass, id);
|
if (!load || !(file = load->nd_lit) || rb_provided(RSTRING(file)->ptr)) {
|
||||||
if (NIL_P(file) || rb_provided(RSTRING(file)->ptr)) {
|
|
||||||
const_missing(klass, id);
|
const_missing(klass, id);
|
||||||
}
|
}
|
||||||
FL_UNSET(file, FL_TAINT);
|
rb_require_safe(file, load->nd_nth);
|
||||||
rb_f_require(Qnil, file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1221,11 +1224,13 @@ autoload_file(mod, id)
|
||||||
{
|
{
|
||||||
VALUE val, file;
|
VALUE val, file;
|
||||||
struct st_table *tbl;
|
struct st_table *tbl;
|
||||||
|
st_data_t load;
|
||||||
|
|
||||||
if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||
|
if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||
|
||||||
!(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &file)) {
|
!(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &load)) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
file = ((NODE *)load)->nd_lit;
|
||||||
Check_Type(file, T_STRING);
|
Check_Type(file, T_STRING);
|
||||||
if (!RSTRING(file)->ptr) {
|
if (!RSTRING(file)->ptr) {
|
||||||
rb_raise(rb_eArgError, "empty file name");
|
rb_raise(rb_eArgError, "empty file name");
|
||||||
|
|
Loading…
Reference in a new issue