diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-11-10 07:17:53 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-11-10 07:17:53 +0000 |
commit | c5789b5075969d314b74014f02c8538e4ae25ebd (patch) | |
tree | 75c314d2451167e53fd86dca2039d096e3209802 | |
parent | dd65b46d652d21325e9f09b1283d56303b992e8f (diff) |
* dir.c (rb_glob2): do not allocate buffer from heap to avoid
memory leaks. use string object for buffering instead.
[ruby-dev:24738]
* dir.c (join_path): ditto.
* io.c (io_read): external input buffer may be modified even after
rb_str_locktmp(). [ruby-dev:24735]
* dir.c (fnmatch): p or s may be NULL. [ruby-dev:24749]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | dir.c | 133 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | ext/socket/socket.c | 4 | ||||
-rw-r--r-- | io.c | 5 | ||||
-rw-r--r-- | lib/shellwords.rb | 4 | ||||
-rw-r--r-- | pack.c | 67 |
7 files changed, 119 insertions, 117 deletions
@@ -13,6 +13,19 @@ Tue Nov 9 14:27:18 2004 Nobuyoshi Nakada <nobu@ruby-lang.org> * lib/optparse.rb (OptionParser::Officious): moved from DefaultList. +Tue Nov 9 01:05:04 2004 Yukihiro Matsumoto <matz@ruby-lang.org> + + * dir.c (rb_glob2): do not allocate buffer from heap to avoid + memory leaks. use string object for buffering instead. + [ruby-dev:24738] + + * dir.c (join_path): ditto. + + * io.c (io_read): external input buffer may be modified even after + rb_str_locktmp(). [ruby-dev:24735] + + * dir.c (fnmatch): p or s may be NULL. [ruby-dev:24749] + Tue Nov 9 00:53:53 2004 WATANABE Hirofumi <eban@ruby-lang.org> * regex.c (slow_match): avoid GCC 3.4.x warnings. @@ -59,6 +72,11 @@ Sat Nov 6 14:58:44 2004 GOTOU Yuuzou <gotoyuzo@notwork.org> ruby 1.9 feature) Sat Nov 6 11:31:04 2004 Tadayoshi Funaba <tadf@dotrb.org> +Sat Nov 6 00:46:27 2004 Yukihiro Matsumoto <matz@ruby-lang.org> + + * string.c (rb_str_locktmp): check STR_TMPLOCK flag before + locking. [ruby-dev:24727] + * lib/date.rb (_parse): checks whether zone was given. @@ -93,6 +111,10 @@ Fri Nov 5 08:52:48 2004 Yukihiro Matsumoto <matz@ruby-lang.org> * gc.c (gc_mark): stricter GC stack check. +Fri Nov 5 08:52:48 2004 Yukihiro Matsumoto <matz@ruby-lang.org> + + * gc.c (gc_mark): stricter GC stack check. + Fri Nov 5 08:34:43 2004 Yukihiro Matsumoto <matz@ruby-lang.org> * string.c (str_gsub): should have removed rb_str_unlocktmp(str). @@ -145,6 +145,8 @@ fnmatch(pat, string, flags) int period = !(flags & FNM_DOTMATCH); int nocase = flags & FNM_CASEFOLD; + if (!pat) pat = ""; + if (!string) string = ""; while (c = *pat++) { switch (c) { case '?': @@ -303,6 +305,7 @@ dir_initialize(dir, dirname) * the block, and <code>Dir::open</code> returns the value of the * block. */ + static VALUE dir_s_open(klass, dirname) VALUE klass, dirname; @@ -880,8 +883,8 @@ remove_backslashes(p) #endif struct glob_args { - void (*func) _((const char*, VALUE)); - const char *c; + void (*func) _((VALUE, VALUE)); + VALUE c; VALUE v; }; @@ -892,14 +895,18 @@ glob_func_caller(val) VALUE val; { struct glob_args *args = (struct glob_args *)val; - (*args->func)(args->c, args->v); + VALUE path = args->c; + + OBJ_TAINT(path); + RSTRING(path)->len = strlen(RSTRING(path)->ptr); + (*args->func)(path, args->v); return Qnil; } static int glob_call_func(func, path, arg) - void (*func) _((const char*, VALUE)); - const char *path; + void (*func) _((VALUE, VALUE)); + VALUE path; VALUE arg; { int status; @@ -913,33 +920,37 @@ glob_call_func(func, path, arg) return status; } +static int glob_helper(VALUE path, char *sub, int flags, void (*func)(VALUE,VALUE), VALUE arg); + static int -glob_helper(path, sub, flags, func, arg) - char *path; +glob_helper(pv, sub, flags, func, arg) + VALUE pv; char *sub; int flags; - void (*func) _((const char*, VALUE)); + void (*func) _((VALUE, VALUE)); VALUE arg; { struct stat st; - char *p, *m; + char *p, *m, *path; int status = 0; + StringValue(pv); + path = RSTRING(pv)->ptr; p = sub ? sub : path; if (!has_magic(p, 0, flags)) { #if defined DOSISH - remove_backslashes(path); + remove_backslashes(RSTRING(path)->ptr); #else if (!(flags & FNM_NOESCAPE)) remove_backslashes(p); #endif - if (lstat(path, &st) == 0) { + if (lstat(RSTRING(path)->ptr, &st) == 0) { status = glob_call_func(func, path, arg); if (status) return status; } else if (errno != ENOENT) { /* In case stat error is other than ENOENT and we may want to know what is wrong. */ - rb_sys_warning(path); + rb_sys_warning(RSTRING(path)->ptr); } return 0; } @@ -948,7 +959,8 @@ glob_helper(path, sub, flags, func, arg) if (*p == '/') p++; m = strchr(p, '/'); if (has_magic(p, m, flags)) { - char *dir, *base, *magic, *buf; + char *dir, *base, *magic; + VALUE buf; DIR *dirp; struct dirent *dp; int recursive = 0; @@ -973,10 +985,9 @@ glob_helper(path, sub, flags, func, arg) if (m && strcmp(magic, "**") == 0) { int n = strlen(base); recursive = 1; - buf = ALLOC_N(char, n+strlen(m)+3); - sprintf(buf, "%s%s", base, *base ? m : m+1); - status = glob_helper(buf, buf+n, flags, func, arg); - free(buf); + buf = rb_str_new(0, n+strlen(m)+3); + sprintf(RSTRING(buf)->ptr, "%s%s", base, *base ? m : m+1); + status = glob_helper(buf, RSTRING(buf)->ptr+n, flags, func, arg); if (status) goto finalize; } dirp = opendir(dir); @@ -1005,36 +1016,32 @@ glob_helper(path, sub, flags, func, arg) continue; if (fnmatch("*", dp->d_name, flags) != 0) continue; - buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+strlen(m)+6); - sprintf(buf, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name); - if (lstat(buf, &st) < 0) { - if (errno != ENOENT) rb_sys_warning(buf); - free(buf); + buf = rb_str_new(0, strlen(base)+NAMLEN(dp)+strlen(m)+6); + sprintf(RSTRING(buf)->ptr, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name); + if (lstat(RSTRING(buf)->ptr, &st) < 0) { + if (errno != ENOENT) rb_sys_warning(RSTRING(buf)->ptr); continue; } if (S_ISDIR(st.st_mode)) { - char *t = buf+strlen(buf); + char *t = RSTRING(buf)->ptr+strlen(RSTRING(buf)->ptr); strcpy(t, "/**"); strcpy(t+3, m); status = glob_helper(buf, t, flags, func, arg); - free(buf); if (status) break; continue; } - free(buf); continue; } if (fnmatch(magic, dp->d_name, flags) == 0) { - buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+2); - sprintf(buf, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name); + buf = rb_str_new(0, strlen(base)+NAMLEN(dp)+2); + sprintf(RSTRING(buf)->ptr, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name); if (!m) { status = glob_call_func(func, buf, arg); - free(buf); if (status) break; continue; } tmp = ALLOC(struct d_link); - tmp->path = buf; + tmp->path = strdup(RSTRING(buf)->ptr); *tail = tmp; tail = &tmp->next; } @@ -1051,11 +1058,10 @@ glob_helper(path, sub, flags, func, arg) if (S_ISDIR(st.st_mode)) { int len = strlen(link->path); int mlen = strlen(m); - char *t = ALLOC_N(char, len+mlen+1); - sprintf(t, "%s%s", link->path, m); - status = glob_helper(t, t+len, flags, func, arg); - free(t); + buf = rb_str_new(0, len+mlen+1); + sprintf(RSTRING(buf)->ptr, "%s%s", link->path, m); + status = glob_helper(buf, RSTRING(buf)->ptr+len, flags, func, arg); } } else { @@ -1077,28 +1083,43 @@ glob_helper(path, sub, flags, func, arg) static int rb_glob2(path, flags, func, arg) - const char *path; + VALUE path; int flags; - void (*func) _((const char*, VALUE)); + void (*func) _((VALUE, VALUE)); VALUE arg; { - char *buf; int status; - buf = ALLOC_N(char, strlen(path)+1); - strcpy(buf, path); - status = glob_helper(buf, 0, flags, func, arg); - free(buf); + status = glob_helper(path, 0, flags, func, arg); return status; } +struct rb_glob_args { + void (*func) _((const char*, VALUE)); + VALUE arg; +}; + +static VALUE +rb_glob_caller(path, a) + VALUE path, a; +{ + struct rb_glob_args *args = (struct rb_glob_args *)a; + (*args->func)(RSTRING(path)->ptr, args->arg); + return Qnil; +} + void rb_glob(path, func, arg) const char *path; void (*func) _((const char*, VALUE)); VALUE arg; { - int status = rb_glob2(path, 0, func, arg); + struct rb_glob_args args; + int status; + + args.func = func; + args.arg = arg; + status = rb_glob2(rb_str_new2(path), 0, func, &args); if (status) rb_jump_tag(status); } @@ -1116,16 +1137,16 @@ rb_globi(path, func, arg) static void push_pattern(path, ary) - const char *path; + VALUE path; VALUE ary; { - rb_ary_push(ary, rb_tainted_str_new2(path)); + rb_ary_push(ary, path); } static int push_globs(ary, s, flags) VALUE ary; - const char *s; + VALUE s; int flags; { return rb_glob2(s, flags, push_pattern, ary); @@ -1137,7 +1158,8 @@ push_braces(ary, s, flags) const char *s; int flags; { - char *buf, *b; + VALUE buf; + char *b; const char *p, *t; const char *lbrace, *rbrace; int nest = 0; @@ -1163,9 +1185,9 @@ push_braces(ary, s, flags) if (lbrace && rbrace) { int len = strlen(s); - buf = xmalloc(len + 1); - memcpy(buf, s, lbrace-s); - b = buf + (lbrace-s); + buf = rb_str_new(0, len+1); + memcpy(RSTRING(buf)->ptr, s, lbrace-s); + b = RSTRING(buf)->ptr + (lbrace-s); p = lbrace; while (*p != '}') { t = p + 1; @@ -1178,7 +1200,6 @@ push_braces(ary, s, flags) status = push_braces(ary, buf, flags); if (status) break; } - free(buf); } else { status = push_globs(ary, s, flags); @@ -1195,7 +1216,7 @@ rb_push_glob(str, flags) int flags; { const char *p, *pend; - char *buf; + volatile VALUE buf; char *t; int nest, maxnest; int status = 0; @@ -1204,13 +1225,12 @@ rb_push_glob(str, flags) ary = rb_ary_new(); SafeStringValue(str); - buf = xmalloc(RSTRING(str)->len + 1); - + buf = rb_str_new(0, RSTRING(str)->len + 1); p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; while (p < pend) { - t = buf; + t = RSTRING(buf)->ptr; nest = maxnest = 0; while (p < pend && isdelim(*p)) p++; while (p < pend && !isdelim(*p)) { @@ -1233,14 +1253,7 @@ rb_push_glob(str, flags) } /* else unmatched braces */ } - free(buf); - if (status) rb_jump_tag(status); - - if (rb_block_given_p()) { - rb_ary_each(ary); - return Qnil; - } return ary; } @@ -1395,6 +1395,7 @@ ruby_finalize_0() static void ruby_finalize_1() { + signal(SIGINT, SIG_DFL); ruby_errinfo = 0; rb_gc_call_finalizer_at_exit(); trace_func = 0; diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 1df7cb988c..ebd8a32270 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1903,8 +1903,6 @@ sock_connect(sock, addr) int fd; StringValue(addr); - rb_str_modify(addr); - GetOpenFile(sock, fptr); fd = fileno(fptr->f); if (ruby_connect(fd, (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len, 0) < 0) { @@ -1921,8 +1919,6 @@ sock_bind(sock, addr) OpenFile *fptr; StringValue(addr); - rb_str_modify(addr); - GetOpenFile(sock, fptr); if (bind(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0) rb_sys_fail("bind(2)"); @@ -320,7 +320,9 @@ io_fflush(f, fptr) rb_io_check_closed(fptr); } for (;;) { + TRAP_BEG; n = fflush(f); + TRAP_END; if (n != EOF) break; if (!rb_io_wait_writable(fileno(f))) rb_sys_fail(fptr->path); @@ -1084,6 +1086,9 @@ io_read(argc, argv, io) rb_str_locktmp(str); READ_CHECK(fptr->f); + if (RSTRING(str)->len != len) { + rb_raise(rb_eRuntimeError, "buffer string modified"); + } n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f); rb_str_unlocktmp(str); if (n == 0) { diff --git a/lib/shellwords.rb b/lib/shellwords.rb index 99c0bf8437..e87b9e656b 100644 --- a/lib/shellwords.rb +++ b/lib/shellwords.rb @@ -41,8 +41,8 @@ module Shellwords snippet = $1 elsif line =~ /\A'/ then raise ArgumentError, "Unmatched single quote: #{line}" - elsif line.sub!(/\A\\(.)/, '') then - snippet = $1 + elsif line.sub!(/\A\\(.)?/, '') then + snippet = $1 || '\\' elsif line.sub!(/\A([^\s\\'"]+)/, '') then snippet = $1 else @@ -24,8 +24,6 @@ #ifdef NATINT_PACK # define OFF16B(p) ((char*)(p) + (natint?0:(sizeof(short) - SIZE16))) # define OFF32B(p) ((char*)(p) + (natint?0:(sizeof(long) - SIZE32))) -# define NATINT_I32(x) (natint?NUM2LONG(x):(NUM2I32(x))) -# define NATINT_U32(x) (natint?NUM2ULONG(x):(NUM2U32(x))) # define NATINT_LEN(type,len) (natint?sizeof(type):(len)) # ifdef WORDS_BIGENDIAN # define OFF16(p) OFF16B(p) @@ -36,8 +34,6 @@ # define NATINT_HTONS(x) (natint?htons(x):hton16(x)) # define NATINT_HTONL(x) (natint?htonl(x):hton32(x)) #else -# define NATINT_I32(x) NUM2I32(x) -# define NATINT_U32(x) NUM2U32(x) # define NATINT_LEN(type,len) sizeof(type) # define NATINT_HTOVS(x) htovs(x) # define NATINT_HTOVL(x) htovl(x) @@ -179,7 +175,7 @@ define_swapx(d, double) #endif /* #if SIZEOF_LONG == 8 */ #else /* SIZEOF_DOUBLE != 8 */ define_swapx(d, double) -#endif /* #if SIZEOF_DPOUBLE == 8 */ +#endif /* #if SIZEOF_DOUBLE == 8 */ #undef define_swapx @@ -252,7 +248,7 @@ endian() #define hton32(x) (x) # endif #else /* LITTLE ENDIAN */ -#ifndef ntohs +#ifdef ntohs #undef ntohs #undef ntohl #undef htons @@ -515,7 +511,7 @@ pack_pack(ary, fmt) continue; } if (*p == '_' || *p == '!') { - char *natstr = "sSiIlL"; + const char *natstr = "sSiIlL"; if (strchr(natstr, type)) { #ifdef NATINT_PACK @@ -708,10 +704,7 @@ pack_pack(ary, fmt) char c; from = NEXTFROM; - if (NIL_P(from)) c = 0; - else { - c = NUM2INT(from); - } + c = NUM2I32(from); rb_str_buf_cat(res, &c, sizeof(char)); } break; @@ -722,10 +715,7 @@ pack_pack(ary, fmt) short s; from = NEXTFROM; - if (NIL_P(from)) s = 0; - else { - s = NUM2INT(from); - } + s = NUM2I32(from); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); } break; @@ -736,13 +726,7 @@ pack_pack(ary, fmt) long i; from = NEXTFROM; - if (NIL_P(from)) i = 0; - else if (type == 'i') { - i = NATINT_I32(from); - } - else { - i = NATINT_U32(from); - } + i = NUM2I32(from); rb_str_buf_cat(res, OFF32(&i), NATINT_LEN(int,4)); } break; @@ -753,13 +737,7 @@ pack_pack(ary, fmt) long l; from = NEXTFROM; - if (NIL_P(from)) l = 0; - else if (type == 'l') { - l = NATINT_I32(from); - } - else { - l = NATINT_U32(from); - } + l = NUM2I32(from); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); } break; @@ -770,7 +748,6 @@ pack_pack(ary, fmt) char tmp[QUAD_SIZE]; from = NEXTFROM; - if (NIL_P(from)) from = INT2FIX(0); rb_quad_pack(tmp, from); rb_str_buf_cat(res, (char*)&tmp, QUAD_SIZE); } @@ -781,10 +758,7 @@ pack_pack(ary, fmt) unsigned short s; from = NEXTFROM; - if (NIL_P(from)) s = 0; - else { - s = NUM2INT(from); - } + s = NUM2I32(from); s = NATINT_HTONS(s); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); } @@ -795,10 +769,7 @@ pack_pack(ary, fmt) unsigned long l; from = NEXTFROM; - if (NIL_P(from)) l = 0; - else { - l = NATINT_U32(from); - } + l = NUM2I32(from); l = NATINT_HTONL(l); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); } @@ -809,10 +780,7 @@ pack_pack(ary, fmt) unsigned short s; from = NEXTFROM; - if (NIL_P(from)) s = 0; - else { - s = NUM2INT(from); - } + s = NUM2I32(from); s = NATINT_HTOVS(s); rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2)); } @@ -823,10 +791,7 @@ pack_pack(ary, fmt) unsigned long l; from = NEXTFROM; - if (NIL_P(from)) l = 0; - else { - l = NATINT_U32(from); - } + l = NUM2I32(from); l = NATINT_HTOVL(l); rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4)); } @@ -938,9 +903,10 @@ pack_pack(ary, fmt) int le; from = NEXTFROM; - if (NIL_P(from)) l = 0; - else { - l = NUM2UINT(from); + from = rb_to_int(from); + l = NUM2INT(from); + if (l < 0) { + rb_raise(rb_eRangeError, "pack(U): value out of range"); } le = uv_to_utf8(buf, l); rb_str_buf_cat(res, (char*)buf, le); @@ -1024,8 +990,7 @@ pack_pack(ary, fmt) } } - if (NIL_P(from)) ul = 0; - else { + { long l = NUM2LONG(from); if (l < 0) { rb_raise(rb_eArgError, "cannot compress negative numbers"); |