diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-31 04:24:57 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-31 04:24:57 +0000 |
commit | 1d5847d1af2d9422a7d10963ee8819d41ca046bf (patch) | |
tree | d0d8b9bc5231f58ee74f284baafcf51dec1f3208 /io.c | |
parent | 80d74ea732b31f0a5eba5e2569f832388a95c0f4 (diff) | |
download | ruby-1d5847d1af2d9422a7d10963ee8819d41ca046bf.tar.gz |
io.c: pipe_register_fptr
* io.c (pipe_register_fptr): get rid of double registration which
causes access after free and segfault.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -6194,6 +6194,20 @@ pipe_finalize(rb_io_t *fptr, int noraise) #endif pipe_del_fptr(fptr); } + +static void +pipe_register_fptr(rb_io_t *fptr) +{ + struct pipe_list *list; + + if (fptr->finalize != pipe_finalize) return; + + for (list = pipe_list; list; list = list->next) { + if (list->fptr == fptr) return; + } + + pipe_add_fptr(fptr); +} #endif void @@ -7146,8 +7160,7 @@ io_reopen(VALUE io, VALUE nfile) else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil; fptr->finalize = orig->finalize; #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK) - if (fptr->finalize == pipe_finalize) - pipe_add_fptr(fptr); + pipe_register_fptr(fptr); #endif fd = fptr->fd; @@ -7329,8 +7342,7 @@ rb_io_init_copy(VALUE dest, VALUE io) if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv; fptr->finalize = orig->finalize; #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK) - if (fptr->finalize == pipe_finalize) - pipe_add_fptr(fptr); + pipe_register_fptr(fptr); #endif fd = ruby_dup(orig->fd); |