mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* io.c (argf_inplace_mode_set): prohibits an assignment
of a tainted value. Patch by unak. * util.c, file.c: prevents a buffer over-run on windows. Patch by unak. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@28522 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
318deef393
commit
ec4ca0fcbb
5 changed files with 166 additions and 97 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Fri Jul 2 19:07:09 2010 Yuki Sonoda (Yugui) <yugui@yugui.jp>
|
||||||
|
|
||||||
|
* io.c (argf_inplace_mode_set): prohibits an assignment
|
||||||
|
of a tainted value. Patch by unak.
|
||||||
|
|
||||||
|
* util.c, file.c: prevents a buffer over-run on windows.
|
||||||
|
Patch by unak.
|
||||||
|
|
||||||
Tue Jun 29 19:39:59 2010 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
Tue Jun 29 19:39:59 2010 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||||
|
|
||||||
* test/win32ole/test_win32ole_method.rb (is_ruby64): check
|
* test/win32ole/test_win32ole_method.rb (is_ruby64): check
|
||||||
|
|
151
file.c
151
file.c
|
@ -3429,42 +3429,15 @@ rmext(const char *p, long l1, const char *e)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
const char *
|
||||||
* call-seq:
|
ruby_find_basename(const char *name, long *len, long *ext)
|
||||||
* File.basename(file_name [, suffix] ) -> base_name
|
|
||||||
*
|
|
||||||
* Returns the last component of the filename given in <i>file_name</i>,
|
|
||||||
* which must be formed using forward slashes (``<code>/</code>'')
|
|
||||||
* regardless of the separator used on the local file system. If
|
|
||||||
* <i>suffix</i> is given and present at the end of <i>file_name</i>,
|
|
||||||
* it is removed.
|
|
||||||
*
|
|
||||||
* File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
|
|
||||||
* File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
|
|
||||||
*/
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
rb_file_s_basename(int argc, VALUE *argv)
|
|
||||||
{
|
{
|
||||||
VALUE fname, fext, basename;
|
const char *p;
|
||||||
const char *name, *p;
|
|
||||||
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
||||||
const char *root;
|
const char *root;
|
||||||
#endif
|
#endif
|
||||||
long f, n;
|
long f, n = -1;
|
||||||
|
|
||||||
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
|
||||||
rb_encoding *enc;
|
|
||||||
StringValue(fext);
|
|
||||||
if (!rb_enc_asciicompat(enc = rb_enc_get(fext))) {
|
|
||||||
rb_raise(rb_eEncCompatError, "ascii incompatible character encodings: %s",
|
|
||||||
rb_enc_name(enc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FilePathStringValue(fname);
|
|
||||||
if (!NIL_P(fext)) rb_enc_check(fname, fext);
|
|
||||||
if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname)))
|
|
||||||
return rb_str_new_shared(fname);
|
|
||||||
name = skipprefix(name);
|
name = skipprefix(name);
|
||||||
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
||||||
root = name;
|
root = name;
|
||||||
|
@ -3503,11 +3476,57 @@ rb_file_s_basename(int argc, VALUE *argv)
|
||||||
#else
|
#else
|
||||||
n = chompdirsep(p) - p;
|
n = chompdirsep(p) - p;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
*len = f;
|
||||||
|
if (ext)
|
||||||
|
*ext = n;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* File.basename(file_name [, suffix] ) -> base_name
|
||||||
|
*
|
||||||
|
* Returns the last component of the filename given in <i>file_name</i>,
|
||||||
|
* which must be formed using forward slashes (``<code>/</code>'')
|
||||||
|
* regardless of the separator used on the local file system. If
|
||||||
|
* <i>suffix</i> is given and present at the end of <i>file_name</i>,
|
||||||
|
* it is removed.
|
||||||
|
*
|
||||||
|
* File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
|
||||||
|
* File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_file_s_basename(int argc, VALUE *argv)
|
||||||
|
{
|
||||||
|
VALUE fname, fext, basename;
|
||||||
|
const char *name, *p;
|
||||||
|
long f, n;
|
||||||
|
|
||||||
|
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
||||||
|
rb_encoding *enc;
|
||||||
|
StringValue(fext);
|
||||||
|
if (!rb_enc_asciicompat(enc = rb_enc_get(fext))) {
|
||||||
|
rb_raise(rb_eEncCompatError, "ascii incompatible character encodings: %s",
|
||||||
|
rb_enc_name(enc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FilePathStringValue(fname);
|
||||||
|
if (!NIL_P(fext)) rb_enc_check(fname, fext);
|
||||||
|
if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname)))
|
||||||
|
return rb_str_new_shared(fname);
|
||||||
|
|
||||||
|
p = ruby_find_basename(name, &f, &n);
|
||||||
|
if (n >= 0) {
|
||||||
if (NIL_P(fext) || !(f = rmext(p, n, StringValueCStr(fext)))) {
|
if (NIL_P(fext) || !(f = rmext(p, n, StringValueCStr(fext)))) {
|
||||||
f = n;
|
f = n;
|
||||||
}
|
}
|
||||||
if (f == RSTRING_LEN(fname)) return rb_str_new_shared(fname);
|
if (f == RSTRING_LEN(fname)) return rb_str_new_shared(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
basename = rb_str_new(p, f);
|
basename = rb_str_new(p, f);
|
||||||
rb_enc_copy(basename, fname);
|
rb_enc_copy(basename, fname);
|
||||||
OBJ_INFECT(basename, fname);
|
OBJ_INFECT(basename, fname);
|
||||||
|
@ -3573,27 +3592,22 @@ rb_file_dirname(VALUE fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* accept a String, and return the pointer of the extension.
|
||||||
* File.extname(path) -> string
|
* if len is passed, set the length of extension to it.
|
||||||
*
|
* returned pointer is in ``name'' or NULL.
|
||||||
* Returns the extension (the portion of file name in <i>path</i>
|
* returns *len
|
||||||
* after the period).
|
* no dot NULL 0
|
||||||
*
|
* dotfile top 0
|
||||||
* File.extname("test.rb") #=> ".rb"
|
* end with dot dot 1
|
||||||
* File.extname("a/b/d/test.rb") #=> ".rb"
|
* .ext dot len of .ext
|
||||||
* File.extname("test") #=> ""
|
* .ext:stream dot len of .ext without :stream (NT only)
|
||||||
* File.extname(".profile") #=> ""
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
const char *
|
||||||
static VALUE
|
ruby_find_extname(const char *name, long *len)
|
||||||
rb_file_s_extname(VALUE klass, VALUE fname)
|
|
||||||
{
|
{
|
||||||
const char *name, *p, *e;
|
const char *p, *e;
|
||||||
VALUE extname;
|
|
||||||
|
|
||||||
FilePathStringValue(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;
|
||||||
|
@ -3629,9 +3643,46 @@ rb_file_s_extname(VALUE klass, VALUE fname)
|
||||||
break;
|
break;
|
||||||
p = CharNext(p);
|
p = CharNext(p);
|
||||||
}
|
}
|
||||||
if (!e || e == name || e+1 == p) /* no dot, or the only dot is first or end? */
|
|
||||||
|
if (len) {
|
||||||
|
/* no dot, or the only dot is first or end? */
|
||||||
|
if (!e || e == name)
|
||||||
|
*len = 0;
|
||||||
|
else if (e+1 == p)
|
||||||
|
*len = 1;
|
||||||
|
else
|
||||||
|
*len = p - e;
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* File.extname(path) -> string
|
||||||
|
*
|
||||||
|
* Returns the extension (the portion of file name in <i>path</i>
|
||||||
|
* after the period).
|
||||||
|
*
|
||||||
|
* File.extname("test.rb") #=> ".rb"
|
||||||
|
* File.extname("a/b/d/test.rb") #=> ".rb"
|
||||||
|
* File.extname("test") #=> ""
|
||||||
|
* File.extname(".profile") #=> ""
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_file_s_extname(VALUE klass, VALUE fname)
|
||||||
|
{
|
||||||
|
const char *name, *e;
|
||||||
|
long len;
|
||||||
|
VALUE extname;
|
||||||
|
|
||||||
|
FilePathStringValue(fname);
|
||||||
|
name = StringValueCStr(fname);
|
||||||
|
e = ruby_find_extname(name, &len);
|
||||||
|
if (len <= 1)
|
||||||
return rb_str_new(0, 0);
|
return rb_str_new(0, 0);
|
||||||
extname = rb_str_new(e, p - e); /* keep the dot, too! */
|
extname = rb_str_new(e, len); /* keep the dot, too! */
|
||||||
rb_enc_copy(extname, fname);
|
rb_enc_copy(extname, fname);
|
||||||
OBJ_INFECT(extname, fname);
|
OBJ_INFECT(extname, fname);
|
||||||
return extname;
|
return extname;
|
||||||
|
|
3
io.c
3
io.c
|
@ -9548,6 +9548,9 @@ opt_i_get(ID id, VALUE *var)
|
||||||
static VALUE
|
static VALUE
|
||||||
argf_inplace_mode_set(VALUE argf, VALUE val)
|
argf_inplace_mode_set(VALUE argf, VALUE val)
|
||||||
{
|
{
|
||||||
|
if (rb_safe_level() >= 1 && OBJ_TAINTED(val))
|
||||||
|
rb_insecure_operation();
|
||||||
|
|
||||||
if (!RTEST(val)) {
|
if (!RTEST(val)) {
|
||||||
if (ARGF.inplace) free(ARGF.inplace);
|
if (ARGF.inplace) free(ARGF.inplace);
|
||||||
ARGF.inplace = 0;
|
ARGF.inplace = 0;
|
||||||
|
|
97
util.c
97
util.c
|
@ -258,77 +258,85 @@ static int valid_filename(const char *s);
|
||||||
static const char suffix1[] = ".$$$";
|
static const char suffix1[] = ".$$$";
|
||||||
static const char suffix2[] = ".~~~";
|
static const char suffix2[] = ".~~~";
|
||||||
|
|
||||||
#define ext (&buf[1000])
|
|
||||||
|
|
||||||
#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
|
#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
|
||||||
|
|
||||||
|
extern const char *ruby_find_basename(const char *, long *, long *);
|
||||||
|
extern const char *ruby_find_extname(const char *, long *);
|
||||||
|
|
||||||
void
|
void
|
||||||
ruby_add_suffix(VALUE str, const char *suffix)
|
ruby_add_suffix(VALUE str, const char *suffix)
|
||||||
{
|
{
|
||||||
int baselen;
|
int baselen;
|
||||||
int extlen = strlen(suffix);
|
int extlen = strlen(suffix);
|
||||||
char *s, *t, *p;
|
char *p, *q;
|
||||||
long slen;
|
long slen;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *const bufend = buf + sizeof(buf);
|
const char *name;
|
||||||
|
const char *ext;
|
||||||
|
long len;
|
||||||
|
|
||||||
if (RSTRING_LEN(str) > 1000)
|
name = StringValueCStr(str);
|
||||||
rb_fatal("Cannot do inplace edit on long filename (%ld characters)",
|
slen = strlen(name);
|
||||||
RSTRING_LEN(str));
|
if (slen > sizeof(buf) - 1)
|
||||||
|
rb_fatal("Cannot do inplace edit on long filename (%ld characters)",
|
||||||
|
slen);
|
||||||
|
|
||||||
#if defined(__CYGWIN32__) || defined(_WIN32)
|
|
||||||
/* Style 0 */
|
/* Style 0 */
|
||||||
slen = RSTRING_LEN(str);
|
|
||||||
rb_str_cat(str, suffix, extlen);
|
rb_str_cat(str, suffix, extlen);
|
||||||
if (valid_filename(RSTRING_PTR(str))) return;
|
if (valid_filename(RSTRING_PTR(str))) return;
|
||||||
|
|
||||||
/* Fooey, style 0 failed. Fix str before continuing. */
|
/* Fooey, style 0 failed. Fix str before continuing. */
|
||||||
rb_str_resize(str, slen);
|
rb_str_resize(str, slen);
|
||||||
#endif
|
name = StringValueCStr(str);
|
||||||
|
ext = ruby_find_extname(name, &len);
|
||||||
slen = extlen;
|
|
||||||
t = buf; baselen = 0; s = RSTRING_PTR(str);
|
|
||||||
while ((*t = *s) && *s != '.') {
|
|
||||||
baselen++;
|
|
||||||
if (*s == '\\' || *s == '/') baselen = 0;
|
|
||||||
s++; t++;
|
|
||||||
}
|
|
||||||
p = t;
|
|
||||||
|
|
||||||
t = ext; extlen = 0;
|
|
||||||
while ((*t++ = *s++) != 0) extlen++;
|
|
||||||
if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; }
|
|
||||||
|
|
||||||
if (*suffix == '.') { /* Style 1 */
|
if (*suffix == '.') { /* Style 1 */
|
||||||
if (strEQ(ext, suffix)) goto fallback;
|
if (ext) {
|
||||||
strlcpy(p, suffix, bufend - p);
|
if (strEQ(ext, suffix)) goto fallback;
|
||||||
|
slen = ext - name;
|
||||||
|
}
|
||||||
|
rb_str_resize(str, slen);
|
||||||
|
rb_str_cat(str, suffix, extlen);
|
||||||
}
|
}
|
||||||
else if (suffix[1] == '\0') { /* Style 2 */
|
else {
|
||||||
if (extlen < 4) {
|
strncpy(buf, name, slen);
|
||||||
ext[extlen] = *suffix;
|
if (ext)
|
||||||
ext[++extlen] = '\0';
|
p = buf + (ext - name);
|
||||||
}
|
else
|
||||||
else if (baselen < 8) {
|
p = buf + slen;
|
||||||
*p++ = *suffix;
|
p[len] = '\0';
|
||||||
|
if (suffix[1] == '\0') { /* Style 2 */
|
||||||
|
if (len <= 3) {
|
||||||
|
p[len] = *suffix;
|
||||||
|
p[++len] = '\0';
|
||||||
|
}
|
||||||
|
else if ((q = (char *)ruby_find_basename(buf, &baselen, 0)) &&
|
||||||
|
baselen < 8) {
|
||||||
|
q += baselen;
|
||||||
|
*q++ = *suffix;
|
||||||
|
if (ext) {
|
||||||
|
strncpy(q, ext, ext - name);
|
||||||
|
q[ext - name + 1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*q = '\0';
|
||||||
|
}
|
||||||
|
else if (len == 4 && p[3] != *suffix)
|
||||||
|
p[3] = *suffix;
|
||||||
|
else if (baselen == 8 && q[7] != *suffix)
|
||||||
|
q[7] = *suffix;
|
||||||
|
else
|
||||||
|
goto fallback;
|
||||||
}
|
}
|
||||||
else if (ext[3] != *suffix) {
|
else { /* Style 3: Panic */
|
||||||
ext[3] = *suffix;
|
fallback:
|
||||||
|
(void)memcpy(p, !ext || strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
|
||||||
}
|
}
|
||||||
else if (buf[7] != *suffix) {
|
|
||||||
buf[7] = *suffix;
|
|
||||||
}
|
|
||||||
else goto fallback;
|
|
||||||
strlcpy(p, ext, bufend - p);
|
|
||||||
}
|
|
||||||
else { /* Style 3: Panic */
|
|
||||||
fallback:
|
|
||||||
(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
|
|
||||||
}
|
}
|
||||||
rb_str_resize(str, strlen(buf));
|
rb_str_resize(str, strlen(buf));
|
||||||
memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str));
|
memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__CYGWIN32__) || defined(_WIN32)
|
|
||||||
static int
|
static int
|
||||||
valid_filename(const char *s)
|
valid_filename(const char *s)
|
||||||
{
|
{
|
||||||
|
@ -350,7 +358,6 @@ valid_filename(const char *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* mm.c */
|
/* mm.c */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#define RUBY_VERSION "1.9.2"
|
#define RUBY_VERSION "1.9.2"
|
||||||
#define RUBY_RELEASE_DATE "2010-07-01"
|
#define RUBY_RELEASE_DATE "2010-07-02"
|
||||||
#define RUBY_PATCHLEVEL -1
|
#define RUBY_PATCHLEVEL -1
|
||||||
|
|
||||||
#define RUBY_VERSION_MAJOR 1
|
#define RUBY_VERSION_MAJOR 1
|
||||||
|
@ -7,7 +7,7 @@
|
||||||
#define RUBY_VERSION_TEENY 1
|
#define RUBY_VERSION_TEENY 1
|
||||||
#define RUBY_RELEASE_YEAR 2010
|
#define RUBY_RELEASE_YEAR 2010
|
||||||
#define RUBY_RELEASE_MONTH 7
|
#define RUBY_RELEASE_MONTH 7
|
||||||
#define RUBY_RELEASE_DAY 1
|
#define RUBY_RELEASE_DAY 2
|
||||||
|
|
||||||
#include "ruby/version.h"
|
#include "ruby/version.h"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue