Project

General

Profile

Feature #13378 ยป 0001-reduce-syscalls-on-require-v2.patch

burke (Burke Libbey), 05/29/2017 06:41 PM

View differences:

file.c
5829 5829
    return rb_find_file_safe(path, rb_safe_level());
5830 5830
}
5831 5831

  
5832
VALUE
5833
rb_find_file_safe(VALUE path, int safe_level)
5832
static VALUE
5833
rb_find_file_safe_internal(VALUE path, int safe_level, int defer_load_check)
5834 5834
{
5835 5835
    VALUE tmp, load_path;
5836 5836
    const char *f = StringValueCStr(path);
......
5850 5850
	if (safe_level >= 1 && !fpath_check(path)) {
5851 5851
	    rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
5852 5852
	}
5853
	if (!rb_file_load_ok(f)) return 0;
5853
	if (!defer_load_check && !rb_file_load_ok(f)) {
5854
	    return 0;
5855
	}
5854 5856
	if (!expanded)
5855 5857
	    path = copy_path_class(file_expand_path_1(path), path);
5856 5858
	return path;
......
5886 5888
    return copy_path_class(tmp, path);
5887 5889
}
5888 5890

  
5891
VALUE
5892
rb_find_file_safe(VALUE path, int safe_level)
5893
{
5894
    return rb_find_file_safe_internal(path, safe_level, 0);
5895
}
5896

  
5897
VALUE
5898
rb_find_file_safe_with_defer_load_check(VALUE path, int safe_level)
5899
{
5900
    return rb_find_file_safe_internal(path, safe_level, 1);
5901
}
5902

  
5889 5903
static void
5890 5904
define_filetest_function(const char *name, VALUE (*func)(ANYARGS), int argc)
5891 5905
{
internal.h
1139 1139
int rb_file_load_ok(const char *);
1140 1140
VALUE rb_file_expand_path_fast(VALUE, VALUE);
1141 1141
VALUE rb_file_expand_path_internal(VALUE, VALUE, int, int, VALUE);
1142
VALUE rb_find_file_safe_with_defer_load_check(VALUE path, int safe_level);
1142 1143
VALUE rb_get_path_check_to_string(VALUE, int);
1143 1144
VALUE rb_get_path_check_convert(VALUE, VALUE, int);
1144 1145
void Init_File(void);
load.c
859 859
		if (loading) *path = rb_filesystem_str_new_cstr(loading);
860 860
		return 'r';
861 861
	    }
862
	    if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
862
	    if ((tmp = rb_find_file_safe_with_defer_load_check(fname, safe_level)) != 0) {
863 863
		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
864 864
		if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
865 865
		    *path = tmp;
ruby.c
1883 1883
}
1884 1884

  
1885 1885
static VALUE
1886
open_load_file(VALUE fname_v, int *xflag)
1886
open_load_file(VALUE fname_v, int *xflag, int script)
1887 1887
{
1888 1888
    const char *fname = StringValueCStr(fname_v);
1889 1889
    long flen = RSTRING_LEN(fname_v);
1890 1890
    VALUE f;
1891
    int e;
1891
    int e = 0;
1892
    int fd = -1;
1892 1893

  
1893 1894
    if (flen == 1 && fname[0] == '-') {
1894 1895
	f = rb_stdin;
1895 1896
    }
1896 1897
    else {
1897
	int fd;
1898 1898
	/* open(2) may block if fname is point to FIFO and it's empty. Let's
1899 1899
	   use O_NONBLOCK. */
1900 1900
#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
......
1920 1920
#endif
1921 1921

  
1922 1922
	if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
1923
	    int e = errno;
1923
	    e = errno;
1924 1924
	    if (!rb_gc_for_fd(e)) {
1925
		rb_load_fail(fname_v, strerror(e));
1925
		goto fail;
1926 1926
	    }
1927 1927
	    if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
1928
		rb_load_fail(fname_v, strerror(errno));
1928
		e = errno;
1929
		goto fail;
1929 1930
	    }
1930 1931
	}
1931 1932
	rb_update_max_fd(fd);
......
1934 1935
	/* disabling O_NONBLOCK */
1935 1936
	if (fcntl(fd, F_SETFL, 0) < 0) {
1936 1937
	    e = errno;
1937
	    (void)close(fd);
1938
	    rb_load_fail(fname_v, strerror(e));
1938
	    goto fail;
1939 1939
	}
1940 1940
#endif
1941 1941

  
1942 1942
	e = ruby_is_fd_loadable(fd);
1943 1943
	if (!e) {
1944 1944
	    e = errno;
1945
	    (void)close(fd);
1946
	    rb_load_fail(fname_v, strerror(e));
1945
	    goto fail;
1947 1946
	}
1948 1947

  
1949 1948
	f = rb_io_fdopen(fd, mode, fname);
......
1956 1955
	}
1957 1956
    }
1958 1957
    return f;
1958
fail:
1959
    if (fd >= 0) (void)close(fd);
1960
    if (script) {
1961
	/* when we reach this from `$ ruby bad.rb`, show the reason */
1962
	rb_load_fail(fname_v, strerror(e));
1963
    } else {
1964
	/* when called from require/load/etc., just show:
1965
	 * "cannot load such file", same as `load_failed`. */
1966
	rb_load_fail(fname_v, "cannot load such file");
1967
    }
1959 1968
}
1960 1969

  
1961 1970
static VALUE
......
1979 1988
    arg.script = script;
1980 1989
    arg.opt = opt;
1981 1990
    arg.xflag = 0;
1982
    arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag);
1991
    arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag, script);
1983 1992
    return (NODE *)rb_ensure(load_file_internal, (VALUE)&arg,
1984 1993
			     restore_load_file, (VALUE)&arg);
1985 1994
}
1986
-