mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 09:33:59 +02:00
merge revision(s) 35595: [Backport #6446]
* include/ruby/win32.h (FD_SET): change function to macro. To avoid buffer overflow when smaller FD_SETSISE is used in ext libraries. * win32/win32.c (rb_w32_fdset): this function is not used anymore. But we leave this for compatibility. * win32/win32.c (rb_w32_select_with_thread): fix SEGV when smaller FD_SETSISE is used in ext libraries. Dereference of fd_set pointer causes SEGV. * test/-ext-/win32/test_fd_setsize.rb(TestFdSetSize): add tests for above. * ext/-test-/win32/fd_setsize/depend: ditto. * ext/-test-/win32/fd_setsize/extconf.rb: ditto. * ext/-test-/win32/fd_setsize/fd_setsize.c: ditto. [ruby-core:44588] [Bug #6352] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@35783 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cb1a793510
commit
2b8e9ece0f
8 changed files with 135 additions and 24 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
Fri May 25 10:40:31 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
|
||||||
|
|
||||||
|
* include/ruby/win32.h (FD_SET): change function to macro.
|
||||||
|
To avoid buffer overflow when smaller FD_SETSISE is used in ext
|
||||||
|
libraries.
|
||||||
|
|
||||||
|
* win32/win32.c (rb_w32_fdset): this function is not used anymore.
|
||||||
|
But we leave this for compatibility.
|
||||||
|
|
||||||
|
* win32/win32.c (rb_w32_select_with_thread): fix SEGV when smaller
|
||||||
|
FD_SETSISE is used in ext libraries. Dereference of fd_set pointer
|
||||||
|
causes SEGV.
|
||||||
|
|
||||||
|
* test/-ext-/win32/test_fd_setsize.rb(TestFdSetSize): add tests for
|
||||||
|
above.
|
||||||
|
* ext/-test-/win32/fd_setsize/depend: ditto.
|
||||||
|
* ext/-test-/win32/fd_setsize/extconf.rb: ditto.
|
||||||
|
* ext/-test-/win32/fd_setsize/fd_setsize.c: ditto.
|
||||||
|
|
||||||
|
[ruby-core:44588] [Bug #6352]
|
||||||
|
|
||||||
Fri May 25 10:38:06 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Fri May 25 10:38:06 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* io.c (io_strip_bom): check EOF. [Bug #6487][ruby-core:45203]
|
* io.c (io_strip_bom): check EOF. [Bug #6487][ruby-core:45203]
|
||||||
|
|
2
ext/-test-/win32/fd_setsize/depend
Normal file
2
ext/-test-/win32/fd_setsize/depend
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
fd_setsize.o: $(top_srcdir)/win32/win32.c \
|
||||||
|
$(hdrdir)/ruby/ruby.h
|
3
ext/-test-/win32/fd_setsize/extconf.rb
Normal file
3
ext/-test-/win32/fd_setsize/extconf.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
if $mingw or $mswin
|
||||||
|
create_makefile("-test-/win32/fd_setsize")
|
||||||
|
end
|
55
ext/-test-/win32/fd_setsize/fd_setsize.c
Normal file
55
ext/-test-/win32/fd_setsize/fd_setsize.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#undef FD_SETSIZE
|
||||||
|
/* redefine smaller size then default 64 */
|
||||||
|
#define FD_SETSIZE 32
|
||||||
|
#include <ruby.h>
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
test_select(VALUE self)
|
||||||
|
{
|
||||||
|
int sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
struct timeval zero;
|
||||||
|
fd_set read;
|
||||||
|
fd_set write;
|
||||||
|
fd_set error;
|
||||||
|
|
||||||
|
zero.tv_sec = 0;
|
||||||
|
zero.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&read);
|
||||||
|
FD_ZERO(&write);
|
||||||
|
FD_ZERO(&error);
|
||||||
|
|
||||||
|
FD_SET(sd, &read);
|
||||||
|
FD_SET(sd, &write);
|
||||||
|
FD_SET(sd, &error);
|
||||||
|
|
||||||
|
select(sd+1, &read, &write, &error, &zero);
|
||||||
|
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
test_fdset(VALUE self)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
fd_set set;
|
||||||
|
|
||||||
|
FD_ZERO(&set);
|
||||||
|
|
||||||
|
for (i = 0; i < FD_SETSIZE * 2; i++) {
|
||||||
|
int sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
FD_SET(sd, &set);
|
||||||
|
if (set.fd_count > FD_SETSIZE) {
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_fd_setsize(void)
|
||||||
|
{
|
||||||
|
VALUE m = rb_define_module_under(rb_define_module("Bug"), "Win32");
|
||||||
|
rb_define_module_function(m, "test_select", test_select, 0);
|
||||||
|
rb_define_module_function(m, "test_fdset", test_fdset, 0);
|
||||||
|
}
|
|
@ -574,7 +574,22 @@ extern char *rb_w32_strerror(int);
|
||||||
#define O_NONBLOCK 1
|
#define O_NONBLOCK 1
|
||||||
|
|
||||||
#undef FD_SET
|
#undef FD_SET
|
||||||
#define FD_SET(f, s) rb_w32_fdset(f, s)
|
#define FD_SET(fd, set) do {\
|
||||||
|
unsigned int i;\
|
||||||
|
SOCKET s = _get_osfhandle(fd);\
|
||||||
|
\
|
||||||
|
for (i = 0; i < (set)->fd_count; i++) {\
|
||||||
|
if ((set)->fd_array[i] == s) {\
|
||||||
|
break;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
if (i == (set)->fd_count) {\
|
||||||
|
if ((set)->fd_count < FD_SETSIZE) {\
|
||||||
|
(set)->fd_array[i] = s;\
|
||||||
|
(set)->fd_count++;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#undef FD_CLR
|
#undef FD_CLR
|
||||||
#define FD_CLR(f, s) rb_w32_fdclr(f, s)
|
#define FD_CLR(f, s) rb_w32_fdclr(f, s)
|
||||||
|
|
25
test/-ext-/win32/test_fd_setsize.rb
Normal file
25
test/-ext-/win32/test_fd_setsize.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require_relative '../../ruby/envutil'
|
||||||
|
|
||||||
|
module Bug
|
||||||
|
module Win32
|
||||||
|
class TestFdSetSize < Test::Unit::TestCase
|
||||||
|
def test_select_with_unmatched_fd_setsize
|
||||||
|
bug6532 = '[ruby-core:44588]'
|
||||||
|
assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
|
||||||
|
require '-test-/win32/fd_setsize'
|
||||||
|
Bug::Win32.test_select
|
||||||
|
p :ok
|
||||||
|
INPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fdset_with_unmatched_fd_setsize
|
||||||
|
bug6532 = '[ruby-core:44588]'
|
||||||
|
assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
|
||||||
|
require '-test-/win32/fd_setsize'
|
||||||
|
p :ok if Bug::Win32.test_fdset
|
||||||
|
INPUT
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end if /mswin|mingw/ =~ RUBY_PLATFORM
|
|
@ -1,5 +1,5 @@
|
||||||
#define RUBY_VERSION "1.9.3"
|
#define RUBY_VERSION "1.9.3"
|
||||||
#define RUBY_PATCHLEVEL 228
|
#define RUBY_PATCHLEVEL 229
|
||||||
|
|
||||||
#define RUBY_RELEASE_DATE "2012-05-25"
|
#define RUBY_RELEASE_DATE "2012-05-25"
|
||||||
#define RUBY_RELEASE_YEAR 2012
|
#define RUBY_RELEASE_YEAR 2012
|
||||||
|
|
|
@ -2316,25 +2316,10 @@ ioctl(int i, int u, ...)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef FD_SET
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_w32_fdset(int fd, fd_set *set)
|
rb_w32_fdset(int fd, fd_set *set)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
FD_SET(fd, set);
|
||||||
SOCKET s = TO_SOCKET(fd);
|
|
||||||
|
|
||||||
for (i = 0; i < set->fd_count; i++) {
|
|
||||||
if (set->fd_array[i] == s) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == set->fd_count) {
|
|
||||||
if (set->fd_count < FD_SETSIZE) {
|
|
||||||
set->fd_array[i] = s;
|
|
||||||
set->fd_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef FD_CLR
|
#undef FD_CLR
|
||||||
|
@ -2718,14 +2703,19 @@ rb_w32_select_with_thread(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
||||||
fd_set orig_rd;
|
fd_set orig_rd;
|
||||||
fd_set orig_wr;
|
fd_set orig_wr;
|
||||||
fd_set orig_ex;
|
fd_set orig_ex;
|
||||||
if (rd) orig_rd = *rd;
|
|
||||||
if (wr) orig_wr = *wr;
|
FD_ZERO(&orig_rd);
|
||||||
if (ex) orig_ex = *ex;
|
FD_ZERO(&orig_wr);
|
||||||
|
FD_ZERO(&orig_ex);
|
||||||
|
|
||||||
|
if (rd) copy_fd(&orig_rd, rd);
|
||||||
|
if (wr) copy_fd(&orig_wr, wr);
|
||||||
|
if (ex) copy_fd(&orig_ex, ex);
|
||||||
r = do_select(nfds, rd, wr, ex, &zero); // polling
|
r = do_select(nfds, rd, wr, ex, &zero); // polling
|
||||||
if (r != 0) break; // signaled or error
|
if (r != 0) break; // signaled or error
|
||||||
if (rd) *rd = orig_rd;
|
if (rd) copy_fd(rd, &orig_rd);
|
||||||
if (wr) *wr = orig_wr;
|
if (wr) copy_fd(wr, &orig_wr);
|
||||||
if (ex) *ex = orig_ex;
|
if (ex) copy_fd(ex, &orig_ex);
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue