mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02: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
151
file.c
151
file.c
|
@ -3429,42 +3429,15 @@ rmext(const char *p, long l1, const char *e)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
const char *
|
||||
ruby_find_basename(const char *name, long *len, long *ext)
|
||||
{
|
||||
VALUE fname, fext, basename;
|
||||
const char *name, *p;
|
||||
const char *p;
|
||||
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
||||
const char *root;
|
||||
#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);
|
||||
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
||||
root = name;
|
||||
|
@ -3503,11 +3476,57 @@ rb_file_s_basename(int argc, VALUE *argv)
|
|||
#else
|
||||
n = chompdirsep(p) - p;
|
||||
#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)))) {
|
||||
f = n;
|
||||
}
|
||||
if (f == RSTRING_LEN(fname)) return rb_str_new_shared(fname);
|
||||
}
|
||||
|
||||
basename = rb_str_new(p, f);
|
||||
rb_enc_copy(basename, fname);
|
||||
OBJ_INFECT(basename, fname);
|
||||
|
@ -3573,27 +3592,22 @@ rb_file_dirname(VALUE fname)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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") #=> ""
|
||||
* accept a String, and return the pointer of the extension.
|
||||
* if len is passed, set the length of extension to it.
|
||||
* returned pointer is in ``name'' or NULL.
|
||||
* returns *len
|
||||
* no dot NULL 0
|
||||
* dotfile top 0
|
||||
* end with dot dot 1
|
||||
* .ext dot len of .ext
|
||||
* .ext:stream dot len of .ext without :stream (NT only)
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_file_s_extname(VALUE klass, VALUE fname)
|
||||
const char *
|
||||
ruby_find_extname(const char *name, long *len)
|
||||
{
|
||||
const char *name, *p, *e;
|
||||
VALUE extname;
|
||||
const char *p, *e;
|
||||
|
||||
FilePathStringValue(fname);
|
||||
name = StringValueCStr(fname);
|
||||
p = strrdirsep(name); /* get the last path component */
|
||||
if (!p)
|
||||
p = name;
|
||||
|
@ -3629,9 +3643,46 @@ rb_file_s_extname(VALUE klass, VALUE fname)
|
|||
break;
|
||||
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);
|
||||
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);
|
||||
OBJ_INFECT(extname, fname);
|
||||
return extname;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue