diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-11-22 07:21:34 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-11-22 07:21:34 +0000 |
commit | d5e7bf424e08f21a6dbc6291e50590a969c6f6db (patch) | |
tree | e80041f9f8966c28b12fd3dc221ca467e74a6cdd /util.c | |
parent | b8f2ee898450661a6568f0fd27a9f2266b55239a (diff) |
Fri, 2 Jul 2010 14:35:10 +0000 usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
merge revision(s) 28525:28568:
* file.c (ruby_find_basename, ruby_find_extname): split from
rb_file_s_basename() and rb_file_s_extname().
* util.c (ruby_add_suffix): support arbitrary length of the suffix
to get rid of the potential buffer overflow.
reported by tarui.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@28526 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Signed-off-by: URABE, Shyouhei <shyouhei@ruby-lang.org>
merge from trunk (r28565)
* file.c (ruby_find_basename): set correct baselen.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@28566 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Signed-off-by: URABE, Shyouhei <shyouhei@ruby-lang.org>
merge from trunk (r28565)
* file.c (ruby_find_basename): set correct baselen.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@28568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Signed-off-by: URABE, Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@29855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 108 |
1 files changed, 56 insertions, 52 deletions
@@ -155,79 +155,83 @@ static int valid_filename(char *s); static const char suffix1[] = ".$$$"; static const char suffix2[] = ".~~~"; -#define ext (&buf[1000]) - #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 -ruby_add_suffix(str, suffix) - VALUE str; - char *suffix; +ruby_add_suffix(VALUE str, const char *suffix) { int baselen; int extlen = strlen(suffix); - char *s, *t, *p; + char *p, *q; long slen; char buf[1024]; + const char *name; + const char *ext; + long len; - if (RSTRING(str)->len > 1000) - rb_fatal("Cannot do inplace edit on long filename (%ld characters)", - RSTRING(str)->len); + name = StringValueCStr(str); + slen = strlen(name); + if (slen > sizeof(buf) - 1) + rb_fatal("Cannot do inplace edit on long filename (%ld characters)", + slen); -#if defined(DJGPP) || defined(__CYGWIN32__) || defined(_WIN32) /* Style 0 */ - slen = RSTRING(str)->len; rb_str_cat(str, suffix, extlen); -#if defined(DJGPP) - if (_USE_LFN) return; -#else - if (valid_filename(RSTRING(str)->ptr)) return; -#endif + if (valid_filename(RSTRING_PTR(str))) return; /* Fooey, style 0 failed. Fix str before continuing. */ - RSTRING(str)->ptr[RSTRING(str)->len = slen] = '\0'; -#endif - - slen = extlen; - t = buf; baselen = 0; s = RSTRING(str)->ptr; - while ((*t = *s) && *s != '.') { - baselen++; - if (*s == '\\' || *s == '/') baselen = 0; - s++; t++; - } - p = t; - - t = ext; extlen = 0; - while (*t++ = *s++) extlen++; - if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; } + rb_str_resize(str, slen); + name = StringValueCStr(str); + ext = ruby_find_extname(name, &len); if (*suffix == '.') { /* Style 1 */ - if (strEQ(ext, suffix)) goto fallback; - strcpy(p, suffix); - } - else if (suffix[1] == '\0') { /* Style 2 */ - if (extlen < 4) { - ext[extlen] = *suffix; - ext[++extlen] = '\0'; - } - else if (baselen < 8) { - *p++ = *suffix; + if (ext) { + if (strEQ(ext, suffix)) goto fallback; + slen = ext - name; } - else if (ext[3] != *suffix) { - ext[3] = *suffix; + rb_str_resize(str, slen); + rb_str_cat(str, suffix, extlen); + } + else { + strncpy(buf, name, slen); + if (ext) + p = buf + (ext - name); + else + p = buf + slen; + 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 (buf[7] != *suffix) { - buf[7] = *suffix; + else { /* Style 3: Panic */ + fallback: + (void)memcpy(p, !ext || strEQ(ext, suffix1) ? suffix2 : suffix1, 5); } - else goto fallback; - strcpy(p, ext); - } - else { /* Style 3: Panic */ -fallback: - (void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5); } rb_str_resize(str, strlen(buf)); - memcpy(RSTRING(str)->ptr, buf, RSTRING(str)->len); + memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str)); } #if defined(__CYGWIN32__) || defined(_WIN32) |