1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* string.c: use StringValueCStr to retrieve paths to system calls.

* string.c (rb_string_value_cstr): check null byte in the string
  before retrieving C ptr.  accessed via macro StringValueCStr.

* file.c (sys_fail2): raise error for two operand system calls
  such as rename, link, symlink.  (ruby-bugs PR#1047)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4107 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-07-20 17:17:52 +00:00
parent 6a867d33b5
commit e4de8e7566
5 changed files with 84 additions and 41 deletions

View file

@ -1,3 +1,13 @@
Mon Jul 21 01:53:43 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c: use StringValueCStr to retrieve paths to system calls.
* string.c (rb_string_value_cstr): check null byte in the string
before retrieving C ptr. accessed via macro StringValueCStr.
* file.c (sys_fail2): raise error for two operand system calls
such as rename, link, symlink. (ruby-bugs PR#1047)
Sun Jul 20 11:03:25 2003 UENO Katsuhiro <katsu@blue.sky.or.jp> Sun Jul 20 11:03:25 2003 UENO Katsuhiro <katsu@blue.sky.or.jp>
* ext/zlib/zlib.c (gzfile_read_header): gz->z.input may be nil after * ext/zlib/zlib.c (gzfile_read_header): gz->z.input may be nil after

View file

@ -507,7 +507,12 @@ rb_str_to_inum(str, base, badcheck)
long len; long len;
StringValue(str); StringValue(str);
s = RSTRING(str)->ptr; if (badcheck) {
s = StringValueCStr(str);
}
else {
s = RSTRING(str)->ptr;
}
if (s) { if (s) {
len = RSTRING(str)->len; len = RSTRING(str)->len;
if (s[len]) { /* no sentinel somehow */ if (s[len]) { /* no sentinel somehow */
@ -517,9 +522,6 @@ rb_str_to_inum(str, base, badcheck)
p[len] = '\0'; p[len] = '\0';
s = p; s = p;
} }
if (badcheck && len != strlen(s)) {
rb_raise(rb_eArgError, "string for Integer contains null byte");
}
} }
return rb_cstr_to_inum(s, base, badcheck); return rb_cstr_to_inum(s, base, badcheck);
} }

90
file.c
View file

@ -85,7 +85,7 @@ apply2files(func, vargs, arg)
for (i=0; i<args->len; i++) { for (i=0; i<args->len; i++) {
path = args->ptr[i]; path = args->ptr[i];
SafeStringValue(path); SafeStringValue(path);
(*func)(RSTRING(path)->ptr, arg); (*func)(StringValueCStr(path), arg);
} }
return args->len; return args->len;
@ -357,7 +357,7 @@ rb_stat(file, st)
return fstat(fileno(fptr->f), st); return fstat(fileno(fptr->f), st);
} }
SafeStringValue(file); SafeStringValue(file);
return stat(StringValuePtr(file), st); return stat(StringValueCStr(file), st);
} }
static VALUE static VALUE
@ -368,7 +368,7 @@ rb_file_s_stat(klass, fname)
SafeStringValue(fname); SafeStringValue(fname);
if (rb_stat(fname, &st) < 0) { if (rb_stat(fname, &st) < 0) {
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(StringValueCStr(fname));
} }
return stat_new(&st); return stat_new(&st);
} }
@ -395,7 +395,7 @@ rb_file_s_lstat(klass, fname)
struct stat st; struct stat st;
SafeStringValue(fname); SafeStringValue(fname);
if (lstat(RSTRING(fname)->ptr, &st) == -1) { if (lstat(StringValueCStr(fname), &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(RSTRING(fname)->ptr);
} }
return stat_new(&st); return stat_new(&st);
@ -560,7 +560,7 @@ test_l(obj, fname)
struct stat st; struct stat st;
SafeStringValue(fname); SafeStringValue(fname);
if (lstat(RSTRING(fname)->ptr, &st) < 0) return Qfalse; if (lstat(StringValueCStr(fname), &st) < 0) return Qfalse;
if (S_ISLNK(st.st_mode)) return Qtrue; if (S_ISLNK(st.st_mode)) return Qtrue;
#endif #endif
@ -656,7 +656,7 @@ test_r(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (eaccess(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse; if (eaccess(StringValueCStr(fname), R_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -665,7 +665,7 @@ test_R(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (access(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse; if (access(StringValueCStr(fname), R_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -674,7 +674,7 @@ test_w(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (eaccess(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse; if (eaccess(StringValueCStr(fname), W_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -683,7 +683,7 @@ test_W(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (access(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse; if (access(StringValueCStr(fname), W_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -692,7 +692,7 @@ test_x(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (eaccess(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse; if (eaccess(StringValueCStr(fname), X_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -701,7 +701,7 @@ test_X(obj, fname)
VALUE obj, fname; VALUE obj, fname;
{ {
SafeStringValue(fname); SafeStringValue(fname);
if (access(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse; if (access(StringValueCStr(fname), X_OK) < 0) return Qfalse;
return Qtrue; return Qtrue;
} }
@ -786,7 +786,7 @@ check3rdbyte(fname, mode)
struct stat st; struct stat st;
SafeStringValue(fname); SafeStringValue(fname);
if (stat(RSTRING(fname)->ptr, &st) < 0) return Qfalse; if (stat(StringValueCStr(fname), &st) < 0) return Qfalse;
if (st.st_mode & mode) return Qtrue; if (st.st_mode & mode) return Qtrue;
return Qfalse; return Qfalse;
} }
@ -832,7 +832,7 @@ rb_file_s_size(klass, fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) if (rb_stat(fname, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(StringValueCStr(fname));
return OFFT2NUM(st.st_size); return OFFT2NUM(st.st_size);
} }
@ -885,7 +885,7 @@ rb_file_s_ftype(klass, fname)
struct stat st; struct stat st;
SafeStringValue(fname); SafeStringValue(fname);
if (lstat(RSTRING(fname)->ptr, &st) == -1) { if (lstat(StringValueCStr(fname), &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(RSTRING(fname)->ptr);
} }
@ -899,7 +899,7 @@ rb_file_s_atime(klass, fname)
struct stat st; struct stat st;
if (rb_stat(fname, &st) < 0) if (rb_stat(fname, &st) < 0)
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(StringValueCStr(fname));
return rb_time_new(st.st_atime, 0); return rb_time_new(st.st_atime, 0);
} }
@ -1234,6 +1234,20 @@ rb_file_s_utime(argc, argv)
#endif #endif
NORETURN(static void syserr2 _((VALUE,VALUE)));
static void
sys_fail2(s1, s2)
VALUE s1, s2;
{
char *buf;
int len;
len = RSTRING(s1)->len + RSTRING(s2)->len + 5;
buf = ALLOCA_N(char, len);
snprintf(buf, len, "%s or %s", RSTRING(s1)->ptr, RSTRING(s2)->ptr);
rb_sys_fail(buf);
}
static VALUE static VALUE
rb_file_s_link(klass, from, to) rb_file_s_link(klass, from, to)
VALUE klass, from, to; VALUE klass, from, to;
@ -1241,8 +1255,9 @@ rb_file_s_link(klass, from, to)
SafeStringValue(from); SafeStringValue(from);
SafeStringValue(to); SafeStringValue(to);
if (link(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) if (link(StringValueCStr(from), StringValueCStr(to)) < 0) {
rb_sys_fail(RSTRING(from)->ptr); sys_fail2(from, to);
}
return INT2FIX(0); return INT2FIX(0);
} }
@ -1254,8 +1269,9 @@ rb_file_s_symlink(klass, from, to)
SafeStringValue(from); SafeStringValue(from);
SafeStringValue(to); SafeStringValue(to);
if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) if (symlink(StringValueCStr(from), StringValueCStr(to)) < 0) {
rb_sys_fail(RSTRING(from)->ptr); sys_fail2(from, to);
}
return INT2FIX(0); return INT2FIX(0);
#else #else
rb_notimplement(); rb_notimplement();
@ -1275,7 +1291,7 @@ rb_file_s_readlink(klass, path)
SafeStringValue(path); SafeStringValue(path);
buf = xmalloc(size); buf = xmalloc(size);
while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { while ((rv = readlink(StringValueCStr(path), buf, size)) == size) {
size *= 2; size *= 2;
buf = xrealloc(buf, size); buf = xrealloc(buf, size);
} }
@ -1319,12 +1335,12 @@ rb_file_s_rename(klass, from, to)
SafeStringValue(from); SafeStringValue(from);
SafeStringValue(to); SafeStringValue(to);
if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) { if (rename(StringValueCStr(from), StringValueCStr(to)) < 0) {
#if defined __CYGWIN__ #if defined __CYGWIN__
extern unsigned long __attribute__((stdcall)) GetLastError(); extern unsigned long __attribute__((stdcall)) GetLastError();
errno = GetLastError(); /* This is a Cygwin bug */ errno = GetLastError(); /* This is a Cygwin bug */
#endif #endif
rb_sys_fail(RSTRING(from)->ptr); sys_fail2(from, to);
} }
return INT2FIX(0); return INT2FIX(0);
@ -1520,7 +1536,7 @@ file_expand_path(fname, dname, result)
long buflen; long buflen;
int tainted; int tainted;
s = StringValuePtr(fname); s = StringValueCStr(fname);
BUFINIT(); BUFINIT();
tainted = OBJ_TAINTED(fname); tainted = OBJ_TAINTED(fname);
@ -1756,7 +1772,7 @@ rb_file_s_basename(argc, argv)
int f; int f;
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) { if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
ext = StringValuePtr(fext); ext = StringValueCStr(fext);
} }
StringValue(fname); StringValue(fname);
if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr)) if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
@ -1796,7 +1812,7 @@ rb_file_s_dirname(klass, fname)
char *name, *root, *p; char *name, *root, *p;
VALUE dirname; VALUE dirname;
name = StringValuePtr(fname); name = StringValueCStr(fname);
root = skiproot(name); root = skiproot(name);
#ifdef DOSISH_UNC #ifdef DOSISH_UNC
if (root > name + 2 && isdirsep(*name)) if (root > name + 2 && isdirsep(*name))
@ -1827,7 +1843,7 @@ rb_file_s_extname(klass, fname)
char *name, *p, *e; char *name, *p, *e;
VALUE extname; VALUE extname;
name = StringValuePtr(fname); name = StringValueCStr(fname);
p = strrdirsep(name); /* get the last path component */ p = strrdirsep(name); /* get the last path component */
if (!p) if (!p)
p = name; p = name;
@ -1908,7 +1924,7 @@ rb_file_join(ary, sep)
default: default:
tmp = rb_obj_as_string(tmp); tmp = rb_obj_as_string(tmp);
} }
name = StringValuePtr(result); name = StringValueCStr(result);
if (i > 0 && !NIL_P(sep) && !*chompdirsep(name)) if (i > 0 && !NIL_P(sep) && !*chompdirsep(name))
rb_str_buf_append(result, sep); rb_str_buf_append(result, sep);
rb_str_buf_append(result, tmp); rb_str_buf_append(result, tmp);
@ -1934,7 +1950,7 @@ rb_file_s_truncate(klass, path, len)
SafeStringValue(path); SafeStringValue(path);
#ifdef HAVE_TRUNCATE #ifdef HAVE_TRUNCATE
if (truncate(RSTRING(path)->ptr, NUM2OFFT(len)) < 0) if (truncate(StringValueCStr(path), NUM2OFFT(len)) < 0)
rb_sys_fail(RSTRING(path)->ptr); rb_sys_fail(RSTRING(path)->ptr);
#else #else
# ifdef HAVE_CHSIZE # ifdef HAVE_CHSIZE
@ -1942,11 +1958,11 @@ rb_file_s_truncate(klass, path, len)
int tmpfd; int tmpfd;
# ifdef _WIN32 # ifdef _WIN32
if ((tmpfd = open(RSTRING(path)->ptr, O_RDWR)) < 0) { if ((tmpfd = open(StringValueCStr(path), O_RDWR)) < 0) {
rb_sys_fail(RSTRING(path)->ptr); rb_sys_fail(RSTRING(path)->ptr);
} }
# else # else
if ((tmpfd = open(RSTRING(path)->ptr, 0)) < 0) { if ((tmpfd = open(StringValueCStr(path), 0)) < 0) {
rb_sys_fail(RSTRING(path)->ptr); rb_sys_fail(RSTRING(path)->ptr);
} }
# endif # endif
@ -2245,7 +2261,7 @@ rb_stat_init(obj, fname)
SafeStringValue(fname); SafeStringValue(fname);
if (stat(RSTRING(fname)->ptr, &st) == -1) { if (stat(StringValueCStr(fname), &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr); rb_sys_fail(RSTRING(fname)->ptr);
} }
if (DATA_PTR(obj)) { if (DATA_PTR(obj)) {
@ -2586,7 +2602,7 @@ path_check_1(path)
VALUE path; VALUE path;
{ {
struct stat st; struct stat st;
char *p0 = RSTRING(path)->ptr; char *p0 = StringValueCStr(path);
char *p = 0, *s; char *p = 0, *s;
if (!is_absolute_path(p0)) { if (!is_absolute_path(p0)) {
@ -2690,7 +2706,7 @@ rb_find_file_ext(filep, ext)
if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {
rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
} }
f = StringValuePtr(fname); f = StringValueCStr(fname);
*filep = fname; *filep = fname;
} }
@ -2698,7 +2714,7 @@ rb_find_file_ext(filep, ext)
for (i=0; ext[i]; i++) { for (i=0; ext[i]; i++) {
fname = rb_str_dup(*filep); fname = rb_str_dup(*filep);
rb_str_cat2(fname, ext[i]); rb_str_cat2(fname, ext[i]);
if (file_load_ok(RSTRING(fname)->ptr)) { if (file_load_ok(StringValueCStr(fname))) {
*filep = fname; *filep = fname;
return i+1; return i+1;
} }
@ -2718,7 +2734,7 @@ rb_find_file_ext(filep, ext)
for (j=0; ext[j]; j++) { for (j=0; ext[j]; j++) {
fname = rb_str_dup(*filep); fname = rb_str_dup(*filep);
rb_str_cat2(fname, ext[j]); rb_str_cat2(fname, ext[j]);
found = dln_find_file(RSTRING(fname)->ptr, path); found = dln_find_file(StringValueCStr(fname), path);
if (found && file_load_ok(found)) { if (found && file_load_ok(found)) {
*filep = fname; *filep = fname;
return j+1; return j+1;
@ -2733,7 +2749,7 @@ rb_find_file(path)
VALUE path; VALUE path;
{ {
VALUE tmp; VALUE tmp;
char *f = RSTRING(path)->ptr; char *f = StringValueCStr(path);
char *lpath; char *lpath;
if (f[0] == '~') { if (f[0] == '~') {
@ -2741,7 +2757,7 @@ rb_find_file(path)
if (rb_safe_level() >= 1 && OBJ_TAINTED(path)) { if (rb_safe_level() >= 1 && OBJ_TAINTED(path)) {
rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
} }
f = StringValuePtr(path); f = StringValueCStr(path);
} }
#if defined(__MACOS__) || defined(riscos) #if defined(__MACOS__) || defined(riscos)

2
ruby.h
View file

@ -213,9 +213,11 @@ void rb_check_type _((VALUE,int));
VALUE rb_str_to_str _((VALUE)); VALUE rb_str_to_str _((VALUE));
VALUE rb_string_value _((volatile VALUE*)); VALUE rb_string_value _((volatile VALUE*));
char *rb_string_value_ptr _((volatile VALUE*)); char *rb_string_value_ptr _((volatile VALUE*));
char *rb_string_value_cstr _((volatile VALUE*));
#define StringValue(v) rb_string_value(&(v)) #define StringValue(v) rb_string_value(&(v))
#define StringValuePtr(v) rb_string_value_ptr(&(v)) #define StringValuePtr(v) rb_string_value_ptr(&(v))
#define StringValueCStr(v) rb_string_value_cstr(&(v))
void rb_check_safe_obj _((VALUE)); void rb_check_safe_obj _((VALUE));
void rb_check_safe_str _((VALUE)); void rb_check_safe_str _((VALUE));

View file

@ -473,6 +473,19 @@ rb_string_value_ptr(ptr)
return RSTRING(rb_string_value(ptr))->ptr; return RSTRING(rb_string_value(ptr))->ptr;
} }
char *
rb_string_value_cstr(ptr)
volatile VALUE *ptr;
{
VALUE str = rb_string_value(ptr);
char *s = RSTRING(str)->ptr;
if (!s || RSTRING(str)->len != strlen(s)) {
rb_raise(rb_eArgError, "string contains null byte");
}
return s;
}
VALUE VALUE
rb_check_string_type(str) rb_check_string_type(str)
VALUE str; VALUE str;