diff --git a/.travis.yml b/.travis.yml index 8db00587d67f3a..ddf394779e7945 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,8 @@ compiler: # far since the 1.9.1 release. before_install: - "sudo apt-get -qq update" + # Travis ships an outdated, broken version of libssl by default + - "sudo apt-get -qq --only-upgrade install '^libssl.*'" - "sudo apt-get -qq install $CC" # upgrade if any install: "sudo apt-get -qq build-dep ruby1.9.1 2>/dev/null" diff --git a/ChangeLog b/ChangeLog index 128f1fe1383852..e56df12ff6fcf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,403 @@ +Tue Aug 18 21:40:43 2015 SHIBATA Hiroshi + + * lib/rubygems.rb: bump version to 2.4.5.1. this version fixed + CVE-2015-3900. + + * lib/rubygems/remote_fetcher.rb: ditto. + + * test/rubygems/test_gem_remote_fetcher.rb: added testcase for CVE-2015-3900 + +Mon Aug 17 23:27:45 2015 Nobuyoshi Nakada + + * ext/win32/lib/win32/registry.rb (API#SetValue): data size should + be in bytes, not in chars. [ruby-core:70365] [Bug #11439] + +Mon Aug 17 23:27:45 2015 Nobuyoshi Nakada + + * ext/win32/lib/win32/registry.rb (API#SetValue): add terminator + size, not 1 byte. [ruby-core:70365] [Bug #11439] + +Mon Aug 17 17:57:12 2015 Nobuyoshi Nakada + + * re.c (rb_memsearch): should match only char boundaries in wide + character encodings. [ruby-core:70220] [Bug #11413] + +Mon Aug 17 17:54:33 2015 Nobuyoshi Nakada + + * transcode.c (rb_econv_set_replacement): target encoding name can + be empty now. [ruby-core:69841] [Bug #11324] + +Mon Aug 17 17:52:11 2015 Nobuyoshi Nakada + + * hash.c (rb_any_hash): fix Float hash. rb_dbl_hash() returns a + Fixnum, but not a long. [Bug #9381] + +Mon Aug 17 17:43:56 2015 Eric Wong + + * io.c (rb_io_oflags_modestr): handle O_TRUNC correctly + * test/ruby/test_io.rb (test_reopen_stdio): new test + Patch-by: cremno phobia + [ruby-core:69779] [Bug #11319] + +Mon Aug 17 17:42:18 2015 Benoit Daloze + + * lib/net/ftp.rb (makeport): close the TCPServer + when sending the port fails. + + * test/net/ftp/test_ftp.rb: test for above. + +Mon Aug 17 17:38:15 2015 Kazuki Tsujimoto + + * lib/net/http/response.rb (Net::HTTPResponse::Inflater#finish): + fix a bug that empty gzipped response body causes Zlib::BufError. + [ruby-core:68846] [Bug #11058] + + * test/net/http/test_httpresponse.rb: tests for the above. + +Mon Aug 17 17:38:15 2015 Kazuki Tsujimoto + + * lib/net/http/response.rb (Net::HTTPResponse#inflater): + fix TypeError. An exception object might be nil. + [ruby-core:68846] [Bug #11058] + +Mon Aug 17 17:38:15 2015 NARUSE, Yui + + * lib/net/http/response.rb (Net::HTTPResponse.each_response_header): + raise first exception even if inflate_body_io.finish raises error. + when begin block raises error, finish usually raises error too. + +Mon Aug 17 17:16:22 2015 Aaron Patterson + + * .travis.yml: update libssl before running tests. + Thanks to Chris Sinjakli for figuring out the + travis settings! + +Mon Aug 17 17:16:22 2015 Aaron Patterson + + * ext/openssl/lib/openssl/ssl.rb (module OpenSSL): raise a more + helpful exception when verifying the peer connection and an + anonymous cipher has been selected. [ruby-core:68330] [Bug #10910] + Thanks to Chris Sinjakli for the patch. + + * test/openssl/test_ssl.rb (class OpenSSL): test for change + +Mon Aug 17 17:12:46 2015 NAKAMURA Usaku + + * win32/win32.c (waitpid): return immediately if interrupted. + reported by [ruby-dev:49176] [Bug #11340] + +Mon Aug 17 17:09:02 2015 Nobuyoshi Nakada + + * parse.y (lambda_body): pop cmdarg stack for lookahead + token. [ruby-core:70067] [Bug #11380] + +Mon Aug 17 17:04:57 2015 Jeremy Evans + + * test/openssl/test_ssl.rb: Fix LocalJumpErrors being raised + in OpenSSL tests. [ruby-core:70020][Bug #11368] + +Mon Aug 17 16:51:45 2015 CHIKANAGA Tomoyuki + + * lib/timeout.rb (ExitException): leave Timeout::ExitException as an + alias of Timeout::Error for backward compatibility in stable branch. + [ruby-dev:49179] [Bug #11344] + +Mon Aug 17 16:51:45 2015 Nobuyoshi Nakada + + * lib/timeout.rb (ExitException): removed internal exception class + and use Timeout::Error instead, as using throw/catch to isolate + each timeouts now. [ruby-dev:49179] [Bug #11344] + +Mon Aug 17 16:49:00 2015 Kazuhiro NISHIYAMA + + * test/net/http/test_httpresponse.rb + (HTTPResponseTest#test_read_body_content_encoding_deflate_uppercase): + fix a failure without zlib. + +Mon Aug 17 16:49:00 2015 NARUSE, Yui + + * lib/net/http/response.rb (inflater): CONTENT_ENCODING can be upper + case. [ruby-core:69670] [Bug #11285] patched by Andy Chu + +Mon Aug 17 16:46:28 2015 Nobuyoshi Nakada + + * vm.c (m_core_hash_merge_ptr): copy the arguments to the machine + stack before rewinding the control frame pointer and leaving the + arguments outside valid region of the value stack. + [ruby-core:69969] [Bug #11352] + + * vm.c (REWIND_CFP): keep the arguments region inside the valid + value stack. [ruby-core:69969] [Bug #11352] + +Mon Aug 17 16:44:01 2015 Nobuyoshi Nakada + + * string.c (rb_str_reverse): reversed string is not a substring, + and should not set coderange of the original string. + [ruby-dev:49189] [Bug #11387] + +Mon Aug 17 16:24:10 2015 Tanaka Akira + + * lib/time.rb (strptime): Support %s.%N. + [ruby-core:68301] [Bug #10904] Patch by Sadayuki Furuhashi. + +Mon Aug 17 16:22:28 2015 Nobuyoshi Nakada + + * transcode.c (load_transcoder_entry): fix transcoder loading race + condition, by waiting in require. [ruby-dev:49106] [Bug #11277] + +Mon Aug 17 16:18:13 2015 Nobuyoshi Nakada + + * array.c (ary_ensure_room_for_push): check if array size will + exceed maximum size to get rid of buffer overflow. + [ruby-dev:49043] [Bug #11235] + + * array.c (ary_ensure_room_for_unshift, rb_ary_splice): ditto. + +Mon Aug 17 16:14:38 2015 Nobuyoshi Nakada + + * ext/win32/lib/win32/registry.rb (Win32::Registry::API): use wide + versions of RegDeleteValue and RegDeleteKey. + [ruby-core:67958] [Bug #10820] + +Tue Jul 7 13:39:46 2015 SHIBATA Hiroshi + + * ext/zlib/zlib.c: Fix indentation for rdoc. + [Bug #11221][ruby-core:69465] + +Tue Jul 7 13:37:34 2015 SHIBATA Hiroshi + + * ext/bigdecimal/bigdecimal.gemspec: Fix require paths for released gem. + [fix GH-929] Patch by @voxik + * ext/io/console/io-console.gemspec: ditto. + +Fri Jul 3 21:54:46 2015 NAKAMURA Usaku + + * test/ruby/test_require.rb (TestRequire#test_loading_fifo_threading): + fix previous commit. [Bug #11060] + +Fri Jul 3 19:28:51 2015 NAKAMURA Usaku + + * test/ruby/test_require.rb (TestRequire#test_loading_fifo_threading): + ignore Errno::ENOENT on unlinking. [Bug #11060] + +Fri Jul 3 18:40:48 2015 Nobuyoshi Nakada + + * lib/mkmf.rb (pkg_config): split --libs if --libs-only-l option + is not available. patch in [ruby-core:69428] by Hans Mackowiak. + [ruby-core:69421] [Bug #11201] + +Fri Jul 3 18:32:37 2015 Nobuyoshi Nakada + + * compile.c (iseq_compile_each): out of range NTH_REF is always + nil. + + * parse.y (parse_numvar): check overflow of NTH_REF and range. + [ruby-core:69393] [Bug #11192] + + * util.c (ruby_scan_digits): make public and add length parameter. + +Fri Jul 3 17:53:43 2015 Nobuyoshi Nakada + + * vm_eval.c (rb_method_call_status): resolve refined method entry + to check if undefined. [ruby-core:69064] [Bug #11117] + +Fri Jul 3 17:53:43 2015 Nobuyoshi Nakada + + * vm_eval.c (rb_method_call_status): undefined refined method is + not callable unless using. [ruby-core:69064] [Bug #11117] + +Fri Jul 3 17:44:27 2015 Nobuyoshi Nakada + + * file.c (rb_file_load_ok): try opening file without gvl not to + lock entire process. [Bug #11060] + +Tue Jun 30 11:56:24 2015 Eric Wong + + * numeric.c (bit_coerce): use original value for error message + [ruby-core:67405] [Bug #10711] + * test/ruby/test_numeric.rb (test_coerce): check error message + +Mon Jun 29 13:22:14 2015 Shota Fukumori + + * ext/objspace/objspace_dump.c(dump_object): Return empty JSON object when + passed object is a special const, instead of SEGV. + Based patch by Kohei Suzuki (eagletmt). [ruby-core:69692] [Bug #11291] + + * test/objspace/test_objspace.rb(test_dump_special_consts): Test for above fix. + + +Wed Jun 17 11:39:15 2015 Koichi Sasada + + * vm_insnhelper.c (lep_svar_set): add WBs. + +Tue Jun 9 16:29:49 2015 Eric Wong + + * ext/socket/ancdata.c: use RB_GC_GUARD instead of volatile + [ruby-core:69419] [Feature #11198] + +Tue Jun 9 16:26:48 2015 Eric Wong + + * ext/openssl/ossl_asn1.c (ossl_asn1_traverse, ossl_asn1_decode, + ossl_asn1_decode_all): use RB_GC_GUARD instead of volatile + [ruby-core:69371] [Bug #11185] + +Tue Jun 9 16:24:25 2015 NARUSE, Yui + + * win32/win32.c (setup_overlapped): seek to the file end only when + writing (mode:a), not reading (mode:a+, read). + +Tue Jun 9 16:15:31 2015 Aaron Patterson + + * load.c (loaded_feature_path): stop returning false negatives for + filenames which are trailing substrings of file extensions. For + example, 'b', which a trailing substring of ".rb" should not return + false. [Bug #11155][ruby-core:69206] + + * test/ruby/test_autoload.rb: test for fix + +Fri May 29 14:03:33 2015 Matt Hoyle + + * ext/bigdecimal/bigdecimal.c (VpSetPTR): fix a typo, 'expoennt' + to 'exponent'. [ruby-core:67980] [Bug #10823] [Fix GH-825] + +Fri May 29 14:00:16 2015 Nobuyoshi Nakada + + * win32/file.c (rb_file_expand_path_internal): neither the drive + of base directory nor the current drive are involved in the + result if different than the drive of path. + [ruby-core:68130] [Bug #10858] + +Fri May 29 14:00:16 2015 Nobuyoshi Nakada + + * win32/file.c (rb_file_expand_path_internal): do not make invalid + (or ADS) path if the path has a drive letter, the result also + should have be under it. [ruby-core:68130] [Bug #10858] + +Fri May 29 13:41:44 2015 NAKAMURA Usaku + + * marshal.c (r_symreal): register the symbol name first so that + r_symlink always returns valid names. [Bug #10991] + +Thu May 28 09:51:28 2015 Nobuyoshi Nakada + + * hash.c (rb_any_hash): use same hash values with Float#hash so + that -0.0 and +0.0 will be identical. + [ruby-core:68541] [Bug #10979] + +Thu May 21 14:15:10 2015 Eric Wong + + * ext/socket/ancdata.c (bsock_recvmsg_internal): GC guard + [Bug #11123] + +Thu May 21 14:11:50 2015 Shugo Maeda + + * lib/net/imap.rb (body_ext_mpart): should work even if body-fld-dsp + is omitted. [ruby-core:69093] [Bug #11128] + +Thu May 21 14:08:15 2015 SHIBATA Hiroshi + + * string.c: added documentation for character sequence \' with String#sub + [Bug #11132][ruby-core:69121][fix GH-900][ci skip] Patch by @shishir127 + +Thu May 21 14:04:06 2015 Nobuyoshi Nakada + + * range.c (linear_object_p, range_include): test if covered for + linear objects. [ruby-core:69052] [Bug #11113] + +Thu May 21 14:01:40 2015 SHIBATA Hiroshi + + * rational.c: Added documentation for rational literal. + [Bug #11075][fix GH-885][ci skip] Patch by @shishir127 + +Thu May 21 13:57:47 2015 Nobuyoshi Nakada + + * ext/socket/ipsocket.c (init_inetsock_internal): preserve errno + before other library calls and use rb_syserr_fail. + [ruby-core:68531] [Bug #10975] + +Thu May 21 13:32:52 2015 Nobuyoshi Nakada + + * ext/-test-/printf/printf.c (uint_to_str): renamed to get rid of + conflict on cygwin. [ruby-core:68877] [Bug #11065] + +Thu May 21 13:28:03 2015 Koichi Sasada + + * vm.c (vm_exec): check other events when RETURN is thrown. + [Bug #10724] + + * test/ruby/test_settracefunc.rb: add a test. + +Thu May 21 13:23:44 2015 Masahiro Tomita + + * ext/socket/raddrinfo.c (addrinfo_mload): fix memory leak of + addrinfo. [ruby-dev:48923] [Bug #11051] + +Thu May 21 13:19:52 2015 Kenta Murata + + * bigdecimal: conform to ruby's license. [ruby-core:68466] [Bug #10952] + +Thu May 21 09:49:01 2015 Nobuyoshi Nakada + + * gc.c (id2ref): prohibit from accessing internal objects. + [ruby-core:68348] [Bug #10918] + +Thu May 21 09:46:58 2015 Rei Odaira + + * ext/pty/pty.c: AIX supports autopush. + Patch by Perry Smith [ruby-core:58539] [Bug #9144] + +Wed May 20 17:34:43 2015 Nobuyoshi Nakada + + * iseq.c (rb_iseq_compile_with_option): check source type, must be + an IO or a String. [ruby-core:69219] [Bug #11159] + +Wed May 13 14:32:13 2015 Tanaka Akira + + * lib/resolv.rb (Resolv::DNS::Label::Str#==): Check class equality. + (Resolv::DNS::Name#initialize): Normalize labels as + Resolv::DNS::Label::Str objects. + +Tue May 12 16:11:55 2015 NAKAMURA Usaku + + * ext/tk/extconf.rb: support Tcl/Tk8.6. + + * ext/tk/tcltklib.c, ext/tk/lib/tk.rb: get rid of SEGV with Tcl/Tk8.6. + [Backport #10401] + +Mon May 11 11:09:08 2015 Nobuyoshi Nakada + + * dln.c (dln_load): check if a different libruby is loaded by the + extension library, and then bail out to get rid of very frequent + reported stale bug reports. + + * dln.c (dln_load): raise fatal error on OSX not other extension + libraries to refer different libruby. + +Mon May 11 10:59:53 2015 Nobuyoshi Nakada + + * parse.y (lambda): push and reset cmdarg_stack in lambda body. + [ruby-core:69017] [Bug #11107] + +Tue Apr 28 14:15:49 2015 Nobuyoshi Nakada + + * lib/fileutils.rb (FileUtils#mv): show the exact target path in + the error message instead of the destination parent directory + name. patched by Joao Britto at + [ruby-core:68706]. [Bug #11021] + +Tue Apr 28 14:14:16 2015 Nobuyoshi Nakada + + * thread_pthread.c (reserve_stack): keep sp safe zone to get rid + of crash by -fstack-check. [ruby-core:68740] [Bug #11030] + +Fri Apr 24 17:27:31 2015 Koichi Sasada + + * test/fiddle/test_handle.rb: fix syntax. + +Tue Apr 14 16:02:07 2015 NAKAMURA Usaku + + * version.h (RUBY_VERSION): bump RUBY_VERSION to 2.1.7. + Mon Apr 13 22:17:59 2015 CHIKANAGA Tomoyuki * ext/openssl/lib/openssl/ssl.rb: stricter hostname verification diff --git a/array.c b/array.c index 7760e3313e196d..3e49d5cd365f25 100644 --- a/array.c +++ b/array.c @@ -354,9 +354,13 @@ rb_ary_modify(VALUE ary) static void ary_ensure_room_for_push(VALUE ary, long add_len) { - long new_len = RARRAY_LEN(ary) + add_len; + long old_len = RARRAY_LEN(ary); + long new_len = old_len + add_len; long capa; + if (old_len > ARY_MAX_SIZE - add_len) { + rb_raise(rb_eIndexError, "index %ld too big", new_len); + } if (ARY_SHARED_P(ary)) { if (new_len > RARRAY_EMBED_LEN_MAX) { VALUE shared = ARY_SHARED(ary); @@ -1078,6 +1082,10 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) long capa; const VALUE *head, *sharedp; + if (len > ARY_MAX_SIZE - argc) { + rb_raise(rb_eIndexError, "index %ld too big", new_len); + } + if (ARY_SHARED_P(ary)) { VALUE shared = ARY_SHARED(ary); capa = RARRAY_LEN(shared); @@ -1569,6 +1577,9 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl) else { long alen; + if (olen - len > ARY_MAX_SIZE - rlen) { + rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len); + } rb_ary_modify(ary); alen = olen + rlen - len; if (alen >= ARY_CAPA(ary)) { diff --git a/common.mk b/common.mk index 1e1e9d04d2cfbf..0bc8f119679817 100644 --- a/common.mk +++ b/common.mk @@ -678,7 +678,7 @@ load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \ {$(VPATH)}dln.h {$(VPATH)}internal.h $(PROBES_H_INCLUDES) {$(VPATH)}vm_opts.h file.$(OBJEXT): {$(VPATH)}file.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \ $(ENCODING_H_INCLUDES) {$(VPATH)}util.h {$(VPATH)}dln.h \ - {$(VPATH)}internal.h + {$(VPATH)}internal.h {$(VPATH)}thread.h gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \ {$(VPATH)}regex.h $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \ {$(VPATH)}gc.h {$(VPATH)}io.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \ @@ -836,7 +836,8 @@ utf_8.$(OBJEXT): {$(VPATH)}utf_8.c {$(VPATH)}regenc.h {$(VPATH)}config.h \ win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}dln.h {$(VPATH)}dln_find.c \ {$(VPATH)}internal.h $(RUBY_H_INCLUDES) $(PLATFORM_D) -win32/file.$(OBJEXT): {$(VPATH)}win32/file.c $(RUBY_H_INCLUDES) $(PLATFORM_D) +win32/file.$(OBJEXT): {$(VPATH)}win32/file.c {$(VPATH)}thread.h \ + $(RUBY_H_INCLUDES) $(PLATFORM_D) $(NEWLINE_C): $(srcdir)/enc/trans/newline.trans $(srcdir)/tool/transcode-tblgen.rb $(Q) $(BASERUBY) "$(srcdir)/tool/transcode-tblgen.rb" -vo $@ $(srcdir)/enc/trans/newline.trans diff --git a/compar.c b/compar.c index 2f4db291a4ee88..0cfce8f4edd585 100644 --- a/compar.c +++ b/compar.c @@ -20,7 +20,7 @@ rb_cmperr(VALUE x, VALUE y) { const char *classname; - if (SPECIAL_CONST_P(y)) { + if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) { y = rb_inspect(y); classname = StringValuePtr(y); } diff --git a/compile.c b/compile.c index 1c0309ac8502aa..b18ab0c09f2608 100644 --- a/compile.c +++ b/compile.c @@ -4812,6 +4812,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) } case NODE_NTH_REF:{ if (!poped) { + if (!node->nd_nth) { + ADD_INSN(ret, line, putnil); + break; + } ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */, INT2FIX(node->nd_nth << 1)); } diff --git a/dln.c b/dln.c index 85ebe27caee3e7..d2c2de8bacc5be 100644 --- a/dln.c +++ b/dln.c @@ -107,10 +107,11 @@ dln_loaderror(const char *format, ...) #ifndef FUNCNAME_PATTERN # if defined(__hp9000s300) || ((defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(__ELF__)) || defined(__BORLANDC__) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD) -# define FUNCNAME_PREFIX "_Init_" +# define EXTERNAL_PREFIX "_" # else -# define FUNCNAME_PREFIX "Init_" +# define EXTERNAL_PREFIX "" # endif +# define FUNCNAME_PREFIX EXTERNAL_PREFIX"Init_" #endif #if defined __CYGWIN__ || defined DOSISH @@ -1340,6 +1341,24 @@ dln_load(const char *file) goto failed; } +# if defined RUBY_EXPORT + { + static const char incompatible[] = "incompatible library version"; + void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc"); + if (ex && ex != ruby_xmalloc) { + +# if defined __APPLE__ + /* dlclose() segfaults */ + rb_fatal("%s - %s", incompatible, file); +# else + dlclose(handle); + error = incompatible; + goto failed; +# endif + } + } +# endif + init_fct = (void(*)())(VALUE)dlsym(handle, buf); #ifdef __native_client__ strcpy(file, orig); diff --git a/ext/-test-/win32/dln/empty/empty.c b/ext/-test-/dln/empty/empty.c similarity index 100% rename from ext/-test-/win32/dln/empty/empty.c rename to ext/-test-/dln/empty/empty.c diff --git a/ext/-test-/dln/empty/extconf.rb b/ext/-test-/dln/empty/extconf.rb new file mode 100644 index 00000000000000..6110887b3ddef0 --- /dev/null +++ b/ext/-test-/dln/empty/extconf.rb @@ -0,0 +1 @@ +create_makefile("-test-/dln/empty") diff --git a/ext/-test-/printf/printf.c b/ext/-test-/printf/printf.c index 1ebe80411bd38e..68e46d21735233 100644 --- a/ext/-test-/printf/printf.c +++ b/ext/-test-/printf/printf.c @@ -28,7 +28,7 @@ printf_test_q(VALUE self, VALUE obj) } static char * -utoa(char *p, char *e, unsigned int x) +uint_to_str(char *p, char *e, unsigned int x) { char *e0 = e; if (e <= p) return p; @@ -79,12 +79,12 @@ printf_test_call(int argc, VALUE *argv, VALUE self) *p++ = '0'; } if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("width"))))) { - p = utoa(p, format + sizeof(format), NUM2UINT(v)); + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); } if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("prec"))))) { *p++ = '.'; if (FIXNUM_P(v)) - p = utoa(p, format + sizeof(format), NUM2UINT(v)); + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); } } *p++ = cnv; diff --git a/ext/-test-/win32/dln/empty/extconf.rb b/ext/-test-/win32/dln/empty/extconf.rb deleted file mode 100644 index a4efed90c9a3ea..00000000000000 --- a/ext/-test-/win32/dln/empty/extconf.rb +++ /dev/null @@ -1,3 +0,0 @@ -if $mingw or $mswin - create_makefile("-test-/win32/dln/empty") -end diff --git a/ext/bigdecimal/README b/ext/bigdecimal/README deleted file mode 100644 index 7a4362826ceb53..00000000000000 --- a/ext/bigdecimal/README +++ /dev/null @@ -1,60 +0,0 @@ - - Ruby BIGDECIMAL(Variable Precision) extension library. - Copyright (C) 1999 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) - -BigDecimal is copyrighted free software by Shigeo Kobayashi . -You can redistribute it and/or modify it under either the terms of the GPL -(see COPYING file), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or executable - form, provided that you do at least ONE of the following: - - a) distribute the executables and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard executables non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). - - 5. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - PURPOSE. - -* The Author - -Feel free to send comments and bug reports to the ruby-core team. - - http://bugs.ruby-lang.org - -------------------------------------------------------- -created at: Thu Dec 22 1999 -updated at: Wed Sep 28 2011 diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 6425a17db2cd7e..7c1e6bd2f3f930 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -4,13 +4,6 @@ * * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the README file - * of this BigDecimal distribution. - * - * NOTE: Change log in this source removed to reduce source code size. - * See rev. 1.25 if needed. - * */ /* #define BIGDECIMAL_DEBUG 1 */ @@ -4393,7 +4386,7 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; - assert(a->exponent >= b->expoennt); + assert(a->exponent >= b->exponent); c->frac[0] = 0; *av = *bv = 0; diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec index 7be9d7275bd2fa..690b77c9f364fd 100644 --- a/ext/bigdecimal/bigdecimal.gemspec +++ b/ext/bigdecimal/bigdecimal.gemspec @@ -6,17 +6,17 @@ Gem::Specification.new do |s| s.name = "bigdecimal" s.version = _VERSION s.date = date + s.license = 'ruby' s.summary = "Arbitrary-precision decimal floating-point number library." s.homepage = "http://www.ruby-lang.org" s.email = "mrkn@mrkn.jp" s.description = "This library provides arbitrary-precision decimal floating-point number class." s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"] - s.require_path = %[.] + s.require_path = %[lib] s.files = %w[ bigdecimal.gemspec bigdecimal.c bigdecimal.h - README depend extconf.rb lib/bigdecimal/jacobian.rb lib/bigdecimal/ludcmp.rb diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h index 805990d99cd8f0..16aa141dadb67f 100644 --- a/ext/bigdecimal/bigdecimal.h +++ b/ext/bigdecimal/bigdecimal.h @@ -4,13 +4,6 @@ * * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the README file - * of this BigDecimal distribution. - * - * NOTES: - * 2003-03-28 V1.0 checked in. - * */ #ifndef RUBY_BIG_DECIMAL_H diff --git a/ext/io/console/io-console.gemspec b/ext/io/console/io-console.gemspec index 309b9bd85b7bcb..52ecdd960364fa 100644 --- a/ext/io/console/io-console.gemspec +++ b/ext/io/console/io-console.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.0.0" s.homepage = "http://www.ruby-lang.org" s.authors = ["Nobu Nakada"] - s.require_path = %[.] + s.require_path = %[lib] s.files = %w[console.c extconf.rb lib/console/size.rb] s.extensions = %w[extconf.rb] s.licenses = "ruby" diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c index e3ce7e727d6123..f61c3de249a228 100644 --- a/ext/objspace/objspace_dump.c +++ b/ext/objspace/objspace_dump.c @@ -152,6 +152,11 @@ dump_object(VALUE obj, struct dump_config *dc) ID flags[RB_OBJ_GC_FLAGS_MAX]; size_t n, i; + if (SPECIAL_CONST_P(obj)) { + dump_append(dc, "{}"); + return; + } + dc->cur_obj = obj; dc->cur_obj_references = 0; dc->cur_obj_klass = BUILTIN_TYPE(obj) == T_NODE ? 0 : RBASIC_CLASS(obj); diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index b91dce312a89d4..ec7a223bb27bc7 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -228,6 +228,14 @@ class SSLSocket # This method MUST be called after calling #connect to ensure that the # hostname of a remote peer has been verified. def post_connection_check(hostname) + if peer_cert.nil? + msg = "Peer verification enabled, but no certificate received." + if using_anon_cipher? + msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification." + end + raise SSLError, msg + end + unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" end @@ -239,6 +247,14 @@ def session rescue SSL::Session::SessionError nil end + + private + + def using_anon_cipher? + ctx = OpenSSL::SSL::SSLContext.new + ctx.ciphers = "aNULL" + ctx.ciphers.include?(cipher) + end end ## diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index efdfbfc8aa232b..ae8c894261f659 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -1029,7 +1029,7 @@ static VALUE ossl_asn1_traverse(VALUE self, VALUE obj) { unsigned char *p; - volatile VALUE tmp; + VALUE tmp; long len, read = 0, offset = 0; obj = ossl_to_der_if_possible(obj); @@ -1037,6 +1037,7 @@ ossl_asn1_traverse(VALUE self, VALUE obj) p = (unsigned char *)RSTRING_PTR(tmp); len = RSTRING_LEN(tmp); ossl_asn1_decode0(&p, len, &offset, 0, 1, &read); + RB_GC_GUARD(tmp); int_ossl_decode_sanity_check(len, read, offset); return Qnil; } @@ -1058,7 +1059,7 @@ ossl_asn1_decode(VALUE self, VALUE obj) { VALUE ret; unsigned char *p; - volatile VALUE tmp; + VALUE tmp; long len, read = 0, offset = 0; obj = ossl_to_der_if_possible(obj); @@ -1066,6 +1067,7 @@ ossl_asn1_decode(VALUE self, VALUE obj) p = (unsigned char *)RSTRING_PTR(tmp); len = RSTRING_LEN(tmp); ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read); + RB_GC_GUARD(tmp); int_ossl_decode_sanity_check(len, read, offset); return ret; } @@ -1089,7 +1091,7 @@ ossl_asn1_decode_all(VALUE self, VALUE obj) VALUE ary, val; unsigned char *p; long len, tmp_len = 0, read = 0, offset = 0; - volatile VALUE tmp; + VALUE tmp; obj = ossl_to_der_if_possible(obj); tmp = rb_str_new4(StringValue(obj)); @@ -1104,6 +1106,7 @@ ossl_asn1_decode_all(VALUE self, VALUE obj) read += tmp_read; tmp_len -= tmp_read; } + RB_GC_GUARD(tmp); int_ossl_decode_sanity_check(len, read, offset); return ary; } diff --git a/ext/pty/pty.c b/ext/pty/pty.c index f54bbb52e58a91..fa8b86923c0575 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -262,7 +262,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, if ((slavefd = rb_cloexec_open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error; rb_update_max_fd(slavefd); -#if defined(I_PUSH) && !defined(__linux__) +#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX) if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error; if (ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error; if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) goto error; @@ -346,7 +346,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, if (no_mesg(slavedevice, nomesg) == -1) goto error; if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error; rb_update_max_fd(slavefd); -#if defined(I_PUSH) && !defined(__linux__) +#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX) if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error; if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error; ioctl(slavefd, I_PUSH, "ttcompat"); diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index bbbf985e2834e1..cb7fca413a351f 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1133,7 +1133,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) struct msghdr mh; struct iovec iov; #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - volatile VALUE controls_str = 0; + VALUE controls_str = 0; VALUE *controls_ptr = NULL; int family; #endif @@ -1289,6 +1289,9 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block"); rb_sys_fail("sendmsg(2)"); } +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) + RB_GC_GUARD(controls_str); +#endif return SSIZET2NUM(ss); } @@ -1705,6 +1708,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0); rb_ary_push(ret, ctl); } + RB_GC_GUARD(ctl_str); } #endif diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index ef5ce763ec3f46..16a83734bb514f 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -41,6 +41,7 @@ inetsock_cleanup(struct inetsock_arg *arg) static VALUE init_inetsock_internal(struct inetsock_arg *arg) { + int error = 0; int type = arg->type; struct addrinfo *res, *lres; int fd, status = 0, local = 0; @@ -80,6 +81,7 @@ init_inetsock_internal(struct inetsock_arg *arg) syscall = "socket(2)"; fd = status; if (fd < 0) { + error = errno; continue; } arg->fd = fd; @@ -107,6 +109,7 @@ init_inetsock_internal(struct inetsock_arg *arg) } if (status < 0) { + error = errno; close(fd); arg->fd = fd = -1; continue; @@ -124,7 +127,7 @@ init_inetsock_internal(struct inetsock_arg *arg) port = arg->remote.serv; } - rsock_sys_fail_host_port(syscall, host, port); + rsock_syserr_fail_host_port(error, syscall, host, port); } arg->fd = -1; @@ -132,8 +135,9 @@ init_inetsock_internal(struct inetsock_arg *arg) if (type == INET_SERVER) { status = listen(fd, SOMAXCONN); if (status < 0) { + error = errno; close(fd); - rb_sys_fail("listen(2)"); + rb_syserr_fail(error, "listen(2)"); } } diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index e4cb9c379fcfc3..66b59760026134 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -1644,6 +1644,7 @@ addrinfo_mload(VALUE self, VALUE ary) len = res->ai->ai_addrlen; memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen); + rb_freeaddrinfo(res); break; } } diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 8bfccbd5598a65..05924323bab807 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -23,10 +23,8 @@ rsock_syserr_fail_host_port(int err, const char *mesg, VALUE host, VALUE port) { VALUE message; - port = rb_String(port); - - message = rb_sprintf("%s for \"%s\" port %s", - mesg, StringValueCStr(host), StringValueCStr(port)); + message = rb_sprintf("%s for %+"PRIsVALUE" port % "PRIsVALUE"", + mesg, host, port); rb_syserr_fail_str(err, message); } @@ -43,15 +41,7 @@ rsock_syserr_fail_path(int err, const char *mesg, VALUE path) VALUE message; if (RB_TYPE_P(path, T_STRING)) { - if (memchr(RSTRING_PTR(path), '\0', RSTRING_LEN(path))) { - path = rb_str_inspect(path); - message = rb_sprintf("%s for %s", mesg, - StringValueCStr(path)); - } - else { - message = rb_sprintf("%s for \"%s\"", mesg, - StringValueCStr(path)); - } + message = rb_sprintf("%s for % "PRIsVALUE"", mesg, path); rb_syserr_fail_str(err, message); } else { @@ -87,7 +77,7 @@ rsock_syserr_fail_raddrinfo(int err, const char *mesg, VALUE rai) VALUE str, message; str = rsock_addrinfo_inspect_sockaddr(rai); - message = rb_sprintf("%s for %s", mesg, StringValueCStr(str)); + message = rb_sprintf("%s for %"PRIsVALUE"", mesg, str); rb_syserr_fail_str(err, message); } diff --git a/ext/tk/extconf.rb b/ext/tk/extconf.rb index 6e2ddb79e6b6ed..00980ddaffd834 100644 --- a/ext/tk/extconf.rb +++ b/ext/tk/extconf.rb @@ -9,10 +9,10 @@ # %w[8.9 8.8 8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6 4.2] # %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0] # %w[8.7 8.6 8.5 8.4 8.0] # to shorten search steps - %w[8.5 8.4] # At present, Tcl/Tk8.6 is not supported. + %w[8.6 8.5 8.4] TkLib_Config['unsupported_versions'] = - %w[8.8 8.7 8.6] # At present, Tcl/Tk8.6 is not supported. + %w[8.8 8.7] TkLib_Config['major_nums'] = '87' diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 5bac92e47c4d9b..65ab57311e9335 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -1309,8 +1309,12 @@ def status.value=(val) end unless interp.deleted? - #Thread.current[:status].value = TclTkLib.mainloop(false) - Thread.current[:status].value = interp.mainloop(false) + begin + #Thread.current[:status].value = TclTkLib.mainloop(false) + Thread.current[:status].value = interp.mainloop(false) + rescue Exception=>e + puts "ignore exception on interp: #{e.inspect}\n" if $DEBUG + end end ensure @@ -1569,7 +1573,15 @@ def INTERP.init_ip_internal EOL =end - at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) } + if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!! + at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) } + else + at_exit{ + Tk.root.destroy + INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) + INTERP_THREAD.kill.join + } + end EventFlag = TclTkLib::EventFlag diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c index 237462fc3b3894..22e2676bb82bcd 100644 --- a/ext/tk/tcltklib.c +++ b/ext/tk/tcltklib.c @@ -6012,7 +6012,12 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv) Tcl_CmdInfo info; int ret; + DUMP1("call ip_rbNamespaceObjCmd"); + DUMP2("objc = %d", objc); + DUMP2("objv[0] = '%s'", Tcl_GetString(objv[0])); + DUMP2("objv[1] = '%s'", Tcl_GetString(objv[1])); if (!Tcl_GetCommandInfo(interp, "__orig_namespace_command__", &(info))) { + DUMP1("fail to get __orig_namespace_command__"); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "invalid command name \"namespace\"", (char*)NULL); @@ -6020,15 +6025,38 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv) } rbtk_eventloop_depth++; - /* DUMP2("namespace wrapper enter depth == %d", rbtk_eventloop_depth); */ + DUMP2("namespace wrapper enter depth == %d", rbtk_eventloop_depth); if (info.isNativeObjectProc) { +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 6 + DUMP1("call a native-object-proc"); ret = (*(info.objProc))(info.objClientData, interp, objc, objv); +#else + /* Tcl8.6 or later */ + int i; + Tcl_Obj **cp_objv; + char org_ns_cmd_name[] = "__orig_namespace_command__"; + + DUMP1("call a native-object-proc for tcl8.6 or later"); + cp_objv = RbTk_ALLOC_N(Tcl_Obj *, (objc + 1)); + + cp_objv[0] = Tcl_NewStringObj(org_ns_cmd_name, strlen(org_ns_cmd_name)); + for(i = 1; i < objc; i++) { + cp_objv[i] = objv[i]; + } + cp_objv[objc] = (Tcl_Obj *)NULL; + + /* ret = Tcl_EvalObjv(interp, objc, cp_objv, TCL_EVAL_DIRECT); */ + ret = Tcl_EvalObjv(interp, objc, cp_objv, 0); + + ckfree((char*)cp_objv); +#endif } else { /* string interface */ int i; char **argv; + DUMP1("call with the string-interface"); /* argv = (char **)Tcl_Alloc(sizeof(char *) * (objc + 1)); */ argv = RbTk_ALLOC_N(char *, (objc + 1)); #if 0 /* use Tcl_Preserve/Release */ @@ -6056,9 +6084,10 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv) #endif } - /* DUMP2("namespace wrapper exit depth == %d", rbtk_eventloop_depth); */ + DUMP2("namespace wrapper exit depth == %d", rbtk_eventloop_depth); rbtk_eventloop_depth--; + DUMP1("end of ip_rbNamespaceObjCmd"); return ret; } #endif @@ -6068,6 +6097,8 @@ ip_wrap_namespace_command(interp) Tcl_Interp *interp; { #if TCL_MAJOR_VERSION >= 8 + +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 6 Tcl_CmdInfo orig_info; if (!Tcl_GetCommandInfo(interp, "namespace", &(orig_info))) { @@ -6084,6 +6115,11 @@ ip_wrap_namespace_command(interp) orig_info.deleteProc); } +#else /* tcl8.6 or later */ + Tcl_GlobalEval(interp, "rename namespace __orig_namespace_command__"); + +#endif + Tcl_CreateObjCommand(interp, "namespace", ip_rbNamespaceObjCmd, (ClientData) 0, (Tcl_CmdDeleteProc *)NULL); #endif @@ -8448,15 +8484,28 @@ invoke_tcl_proc(arg) #endif { struct invoke_info *inf = (struct invoke_info *)arg; + +#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION < 6 int i, len; -#if TCL_MAJOR_VERSION >= 8 int argc = inf->objc; char **argv = (char **)NULL; #endif + DUMP1("call invoke_tcl_proc"); + +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 6) + + /* eval */ + inf->ptr->return_value = Tcl_EvalObjv(inf->ptr->ip, inf->objc, inf->objv, TCL_EVAL_DIRECT); + /* inf->ptr->return_value = Tcl_EvalObjv(inf->ptr->ip, inf->objc, inf->objv, 0); */ + +#else /* Tcl/Tk 7.x, 8.0 -- 8.5 */ + /* memory allocation for arguments of this command */ -#if TCL_MAJOR_VERSION >= 8 +#if TCL_MAJOR_VERSION == 8 + /* Tcl/Tk 8.0 -- 8.5 */ if (!inf->cmdinfo.isNativeObjectProc) { + DUMP1("called proc is not a native-obj-proc"); /* string interface */ /* argv = (char **)ALLOC_N(char *, argc+1);*/ /* XXXXXXXXXX */ argv = RbTk_ALLOC_N(char *, (argc+1)); @@ -8470,11 +8519,14 @@ invoke_tcl_proc(arg) } #endif + DUMP1("reset result of tcl-interp"); Tcl_ResetResult(inf->ptr->ip); /* Invoke the C procedure */ -#if TCL_MAJOR_VERSION >= 8 +#if TCL_MAJOR_VERSION == 8 + /* Tcl/Tk 8.0 -- 8.5 */ if (inf->cmdinfo.isNativeObjectProc) { + DUMP1("call tcl_proc as a native-obj-proc"); inf->ptr->return_value = (*(inf->cmdinfo.objProc))(inf->cmdinfo.objClientData, inf->ptr->ip, inf->objc, inf->objv); @@ -8482,7 +8534,9 @@ invoke_tcl_proc(arg) else #endif { -#if TCL_MAJOR_VERSION >= 8 +#if TCL_MAJOR_VERSION == 8 + /* Tcl/Tk 8.0 -- 8.5 */ + DUMP1("call tcl_proc as not a native-obj-proc"); inf->ptr->return_value = (*(inf->cmdinfo.proc))(inf->cmdinfo.clientData, inf->ptr->ip, argc, (CONST84 char **)argv); @@ -8505,6 +8559,9 @@ invoke_tcl_proc(arg) #endif } +#endif /* Tcl/Tk 8.6 or later || Tcl 7.x, 8.0 -- 8.5 */ + + DUMP1("end of invoke_tcl_proc"); return Qnil; } @@ -8644,7 +8701,9 @@ ip_invoke_core(interp, argc, argv) #endif /* invoke tcl-proc */ + DUMP1("invoke tcl-proc"); rb_protect(invoke_tcl_proc, (VALUE)&inf, &status); + DUMP2("status of tcl-proc, %d", status); switch(status) { case TAG_RAISE: if (NIL_P(rb_errinfo())) { diff --git a/ext/win32/lib/win32/registry.rb b/ext/win32/lib/win32/registry.rb index 74cc77dc9fc8e1..911821a1b31950 100644 --- a/ext/win32/lib/win32/registry.rb +++ b/ext/win32/lib/win32/registry.rb @@ -222,8 +222,8 @@ module API "long RegEnumKeyExW(void *, long, void *, void *, void *, void *, void *, void *)", "long RegQueryValueExW(void *, void *, void *, void *, void *, void *)", "long RegSetValueExW(void *, void *, long, long, void *, long)", - "long RegDeleteValue(void *, void *)", - "long RegDeleteKey(void *, void *)", + "long RegDeleteValueW(void *, void *)", + "long RegDeleteKeyW(void *, void *)", "long RegFlushKey(void *)", "long RegCloseKey(void *)", "long RegQueryInfoKey(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)", @@ -315,7 +315,7 @@ def SetValue(hkey, name, type, data, size) case type when REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ data = data.encode(WCHAR) - size ||= data.size + 1 + size ||= data.bytesize + WCHAR_SIZE end check RegSetValueExW.call(hkey, make_wstr(name), 0, type, data, size) end diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 9dbc193f54bf72..e8b2d93baebeb4 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1832,7 +1832,7 @@ rb_inflate_s_allocate(VALUE klass) * Have inflate use the window size from the zlib header of the compressed * stream. * - * (8..15) + * (8..15):: * Overrides the window size of the inflate header in the compressed stream. * The window size must be greater than or equal to the window size of the * compressed stream. diff --git a/file.c b/file.c index e9e2dd134030bf..dc8f9021d4daa4 100644 --- a/file.c +++ b/file.c @@ -26,6 +26,7 @@ #include "ruby/ruby.h" #include "ruby/io.h" #include "ruby/util.h" +#include "ruby/thread.h" #include "dln.h" #include "internal.h" @@ -5384,6 +5385,12 @@ rb_path_check(const char *path) } #ifndef _WIN32 +static void * +loadopen_func(void *arg) +{ + return (void *)(VALUE)rb_cloexec_open((const char *)arg, O_RDONLY, 0); +} + #ifdef __native_client__ __attribute__((noinline)) #endif @@ -5391,7 +5398,9 @@ int rb_file_load_ok(const char *path) { int ret = 1; - int fd = rb_cloexec_open(path, O_RDONLY, 0); + int fd; + + fd = (int)(VALUE)rb_thread_call_without_gvl(loadopen_func, (void *)path, RUBY_UBF_IO, 0); if (fd == -1) return 0; rb_update_max_fd(fd); #if !defined DOSISH diff --git a/gc.c b/gc.c index 69f1198736ef4b..c193d6f2349e1c 100644 --- a/gc.c +++ b/gc.c @@ -2379,6 +2379,9 @@ id2ref(VALUE obj, VALUE objid) if (!is_live_object(objspace, ptr)) { rb_raise(rb_eRangeError, "%p is recycled object", p0); } + if (RBASIC(ptr)->klass == 0) { + rb_raise(rb_eRangeError, "%p is internal object", p0); + } return (VALUE)ptr; } diff --git a/hash.c b/hash.c index 58f04a9663310c..1e3b691acc8c41 100644 --- a/hash.c +++ b/hash.c @@ -133,11 +133,20 @@ rb_any_hash(VALUE a) if (SPECIAL_CONST_P(a)) { if (a == Qundef) return 0; + if (FLONUM_P(a)) { + /* prevent pathological behavior: [Bug #10761] */ + goto flt; + } hnum = rb_objid_hash((st_index_t)a); } else if (BUILTIN_TYPE(a) == T_STRING) { hnum = rb_str_hash(a); } + else if (BUILTIN_TYPE(a) == T_FLOAT) { + flt: + hval = rb_dbl_hash(rb_float_value(a)); + hnum = FIX2LONG(hval); + } else { hval = rb_hash(a); hnum = FIX2LONG(hval); diff --git a/internal.h b/internal.h index afa936ecbff0f4..833045676f8f18 100644 --- a/internal.h +++ b/internal.h @@ -547,6 +547,7 @@ double ruby_float_mod(double x, double y); int rb_num_negative_p(VALUE); VALUE rb_int_succ(VALUE num); VALUE rb_int_pred(VALUE num); +VALUE rb_dbl_hash(double d); #if USE_FLONUM #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) @@ -885,6 +886,7 @@ VALUE rb_gcd_gmp(VALUE x, VALUE y); /* util.c */ extern const signed char ruby_digit36_to_number_table[]; +extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow); /* variable.c */ void rb_gc_mark_global_tbl(void); diff --git a/io.c b/io.c index 95229903ca3b4a..b86ebe8e7f3938 100644 --- a/io.c +++ b/io.c @@ -4958,6 +4958,9 @@ rb_io_oflags_modestr(int oflags) case O_WRONLY: return MODE_BINARY("w", "wb"); case O_RDWR: + if (oflags & O_TRUNC) { + return MODE_BINARY("w+", "wb+"); + } return MODE_BINARY("r+", "rb+"); } } diff --git a/iseq.c b/iseq.c index 700a161f6bc3e6..4fbfe9edb4cf01 100644 --- a/iseq.c +++ b/iseq.c @@ -610,6 +610,7 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE li if (RB_TYPE_P((src), T_FILE)) node = rb_parser_compile_file_path(parser, file, src, ln); else { + StringValue(src); node = rb_parser_compile_string_path(parser, file, src, ln); if (!node) { diff --git a/lib/cmath.rb b/lib/cmath.rb index 337c2e063ad713..24d619fe75ce3c 100644 --- a/lib/cmath.rb +++ b/lib/cmath.rb @@ -1,17 +1,30 @@ ## +# = Trigonometric and transcendental functions for complex numbers. +# # CMath is a library that provides trigonometric and transcendental -# functions for complex numbers. +# functions for complex numbers. The functions in this module accept +# integers, floating-point numbers or complex numbers as arguments. +# +# Note that the selection of functions is similar, but not identical, +# to that in module math. The reason for having two modules is that +# some users aren’t interested in complex numbers, and perhaps don’t +# even know what they are. They would rather have Math.sqrt(-1) raise +# an exception than return a complex number. # # == Usage # -# To start using this library, simply: +# To start using this library, simply require cmath library: # # require "cmath" # -# Square root of a negative number is a complex number. +# And after call any CMath function. For example: +# +# CMath.sqrt(-9) #=> 0+3.0i +# CMath.exp(0 + 0i) #=> 1.0+0.0i +# CMath.log10(-5.to_c) #=> (0.6989700043360187+1.3643763538418412i) # -# CMath.sqrt(-9) #=> 0+3.0i # +# For more information you can see Complec class. module CMath @@ -44,9 +57,7 @@ module CMath ## # Math::E raised to the +z+ power # - # exp(Complex(0,0)) #=> 1.0+0.0i - # exp(Complex(0,PI)) #=> -1.0+1.2246467991473532e-16i - # exp(Complex(0,PI/2.0)) #=> 6.123233995736766e-17+1.0i + # CMath.exp(2i) #=> (-0.4161468365471424+0.9092974268256817i) def exp(z) begin if z.real? @@ -62,10 +73,11 @@ def exp(z) end ## - # Returns the natural logarithm of Complex. If a second argument is given, + # Returns the natural logarithm of Complex. If a second argument is given, # it will be the base of logarithm. # - # log(Complex(0,0)) #=> -Infinity+0.0i + # CMath.log(1 + 4i) #=> (1.416606672028108+1.3258176636680326i) + # CMath.log(1 + 4i, 10) #=> (0.6152244606891369+0.5757952953408879i) def log(*args) begin z, b = args @@ -88,6 +100,8 @@ def log(*args) ## # returns the base 2 logarithm of +z+ + # + # CMath.log2(-1) => (0.0+4.532360141827194i) def log2(z) begin if z.real? and z >= 0 @@ -102,6 +116,8 @@ def log2(z) ## # returns the base 10 logarithm of +z+ + # + # CMath.log10(-1) #=> (0.0+1.3643763538418412i) def log10(z) begin if z.real? and z >= 0 @@ -116,9 +132,8 @@ def log10(z) ## # Returns the non-negative square root of Complex. - # sqrt(-1) #=> 0+1.0i - # sqrt(Complex(-1,0)) #=> 0.0+1.0i - # sqrt(Complex(0,8)) #=> 2.0+2.0i + # + # CMath.sqrt(-1 + 0i) #=> 0.0+1.0i def sqrt(z) begin if z.real? @@ -144,12 +159,16 @@ def sqrt(z) ## # returns the principal value of the cube root of +z+ + # + # CMath.cbrt(1 + 4i) #=> (1.449461632813119+0.6858152562177092i) def cbrt(z) z ** (1.0/3) end ## # returns the sine of +z+, where +z+ is given in radians + # + # CMath.sin(1 + 1i) #=> (1.2984575814159773+0.6349639147847361i) def sin(z) begin if z.real? @@ -165,6 +184,8 @@ def sin(z) ## # returns the cosine of +z+, where +z+ is given in radians + # + # CMath.cos(1 + 1i) #=> (0.8337300251311491-0.9888977057628651i) def cos(z) begin if z.real? @@ -180,6 +201,8 @@ def cos(z) ## # returns the tangent of +z+, where +z+ is given in radians + # + # CMath.tan(1 + 1i) #=> (0.27175258531951174+1.0839233273386943i) def tan(z) begin if z.real? @@ -194,6 +217,8 @@ def tan(z) ## # returns the hyperbolic sine of +z+, where +z+ is given in radians + # + # CMath.sinh(1 + 1i) #=> (0.6349639147847361+1.2984575814159773i) def sinh(z) begin if z.real? @@ -209,6 +234,8 @@ def sinh(z) ## # returns the hyperbolic cosine of +z+, where +z+ is given in radians + # + # CMath.cosh(1 + 1i) #=> (0.8337300251311491+0.9888977057628651i) def cosh(z) begin if z.real? @@ -224,6 +251,8 @@ def cosh(z) ## # returns the hyperbolic tangent of +z+, where +z+ is given in radians + # + # CMath.tanh(1 + 1i) #=> (1.0839233273386943+0.27175258531951174i) def tanh(z) begin if z.real? @@ -238,6 +267,8 @@ def tanh(z) ## # returns the arc sine of +z+ + # + # CMath.asin(1 + 1i) #=> (0.6662394324925153+1.0612750619050355i) def asin(z) begin if z.real? and z >= -1 and z <= 1 @@ -252,6 +283,8 @@ def asin(z) ## # returns the arc cosine of +z+ + # + # CMath.acos(1 + 1i) #=> (0.9045568943023813-1.0612750619050357i) def acos(z) begin if z.real? and z >= -1 and z <= 1 @@ -266,6 +299,8 @@ def acos(z) ## # returns the arc tangent of +z+ + # + # CMath.atan(1 + 1i) #=> (1.0172219678978514+0.4023594781085251i) def atan(z) begin if z.real? @@ -281,6 +316,8 @@ def atan(z) ## # returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and # +x+ to determine the quadrant + # + # CMath.atan2(1 + 1i, 0) #=> (1.5707963267948966+0.0i) def atan2(y,x) begin if y.real? and x.real? @@ -295,6 +332,8 @@ def atan2(y,x) ## # returns the inverse hyperbolic sine of +z+ + # + # CMath.asinh(1 + 1i) #=> (1.0612750619050357+0.6662394324925153i) def asinh(z) begin if z.real? @@ -309,6 +348,8 @@ def asinh(z) ## # returns the inverse hyperbolic cosine of +z+ + # + # CMath.acosh(1 + 1i) #=> (1.0612750619050357+0.9045568943023813i) def acosh(z) begin if z.real? and z >= 1 @@ -323,6 +364,8 @@ def acosh(z) ## # returns the inverse hyperbolic tangent of +z+ + # + # CMath.atanh(1 + 1i) #=> (0.4023594781085251+1.0172219678978514i) def atanh(z) begin if z.real? and z >= -1 and z <= 1 @@ -397,4 +440,3 @@ def handle_no_method_error # :nodoc: module_function :handle_no_method_error end - diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 335d60d4a259b2..5af756be4c8bab 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -516,7 +516,7 @@ def mv(src, dest, options = {}) begin if destent.exist? if destent.directory? - raise Errno::EEXIST, dest + raise Errno::EEXIST, d else destent.remove_file if rename_cannot_overwrite_file? end diff --git a/lib/mkmf.rb b/lib/mkmf.rb index f5c462b58e636e..7a59e572bf78f6 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -1756,11 +1756,18 @@ def pkg_config(pkg, option=nil) elsif get and try_ldflags(ldflags = get['libs']) cflags = get['cflags'] libs = get['libs-only-l'] - ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") - $CFLAGS += " " << cflags - $CXXFLAGS += " " << cflags - $LDFLAGS = [orig_ldflags, ldflags].join(' ') + if cflags + $CFLAGS += " " << cflags + $CXXFLAGS += " " << cflags + end + if libs + ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") + else + libs, ldflags = Shellwords.shellwords(ldflags).partition {|s| s =~ /-l([^ ]+)/ }.map {|l|l.quote.join(" ")} + end $libs += " " << libs + + $LDFLAGS = [orig_ldflags, ldflags].join(' ') Logging::message "package configuration for %s\n", pkg Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb index a57372ac3b7124..5ddccda90ceaf0 100644 --- a/lib/net/ftp.rb +++ b/lib/net/ftp.rb @@ -377,15 +377,9 @@ def sendport(host, port) # :nodoc: end private :sendport - # Constructs a TCPServer socket, and sends it the PORT command - # - # Returns the constructed TCPServer socket + # Constructs a TCPServer socket def makeport # :nodoc: - sock = TCPServer.open(@sock.addr[3], 0) - port = sock.addr[1] - host = sock.addr[3] - sendport(host, port) - return sock + TCPServer.open(@sock.addr[3], 0) end private :makeport @@ -421,6 +415,7 @@ def transfercmd(cmd, rest_offset = nil) # :nodoc: else sock = makeport begin + sendport(sock.addr[3], sock.addr[1]) if @resume and rest_offset resp = sendcmd("REST " + rest_offset.to_s) if resp[0] != ?3 diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb index 9aaa0b32080c12..95d4d0ce944bcf 100644 --- a/lib/net/http/response.rb +++ b/lib/net/http/response.rb @@ -250,7 +250,8 @@ def inflater # :nodoc: return yield @socket unless @decode_content return yield @socket if self['content-range'] - case self['content-encoding'] + v = self['content-encoding'] + case v && v.downcase when 'deflate', 'gzip', 'x-gzip' then self.delete 'content-encoding' @@ -259,7 +260,12 @@ def inflater # :nodoc: begin yield inflate_body_io ensure - inflate_body_io.finish + orig_err = $! + begin + inflate_body_io.finish + rescue => err + raise orig_err || err + end end when 'none', 'identity' then self.delete 'content-encoding' @@ -354,6 +360,7 @@ def initialize socket # Finishes the inflate stream. def finish + return if @inflate.total_in == 0 @inflate.finish end diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 1bb0b81eecdff6..a8845c1314e184 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -2582,7 +2582,13 @@ def body_ext_mpart return param end disposition = body_fld_dsp - match(T_SPACE) + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return param, disposition + end language = body_fld_lang token = lookahead diff --git a/lib/resolv.rb b/lib/resolv.rb index 74618bfaab37ee..78c2b459fe4a10 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -1187,7 +1187,7 @@ def inspect end def ==(other) - return @downcase == other.downcase + return self.class == other.class && @downcase == other.downcase end def eql?(other) @@ -1223,6 +1223,14 @@ def self.create(arg) end def initialize(labels, absolute=true) # :nodoc: + labels = labels.map {|label| + case label + when String then Label::Str.new(label) + when Label::Str then label + else + raise ArgumentError, "unexpected label: #{label.inspect}" + end + } @labels = labels @absolute = absolute end diff --git a/lib/rubygems.rb b/lib/rubygems.rb index ea1893046f6259..73d063e7a0a075 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.2.3' + VERSION = '2.2.5' end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index 58991caeda93da..ed2e171d2c29c2 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -90,7 +90,13 @@ def api_endpoint(uri) rescue Resolv::ResolvError uri else - URI.parse "#{uri.scheme}://#{res.target}#{uri.path}" + target = res.target.to_s.strip + + if /\.#{Regexp.quote(host)}\z/ =~ target + return URI.parse "#{uri.scheme}://#{target}#{uri.path}" + end + + uri end end diff --git a/lib/time.rb b/lib/time.rb index dd7a513dbaed9b..73a8f81177e807 100644 --- a/lib/time.rb +++ b/lib/time.rb @@ -393,10 +393,16 @@ def strptime(date, format, now=self.now) d = Date._strptime(date, format) raise ArgumentError, "invalid strptime format - `#{format}'" unless d if seconds = d[:seconds] + if sec_fraction = d[:sec_fraction] + usec = sec_fraction * 1000000 + usec *= -1 if seconds < 0 + else + usec = 0 + end if offset = d[:offset] - Time.at(seconds).localtime(offset) + Time.at(seconds, usec).localtime(offset) else - Time.at(seconds) + Time.at(seconds, usec) end else year = d[:year] diff --git a/lib/timeout.rb b/lib/timeout.rb index d805dce2a3fdad..5fce1f09a5e6d6 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -24,8 +24,6 @@ module Timeout # Raised by Timeout#timeout when the block times out. class Error < RuntimeError - end - class ExitException < ::Exception # :nodoc: attr_reader :thread def self.catch(*args) @@ -48,6 +46,7 @@ def exception(*) self end end + ExitException = Error # :stopdoc: THIS_FILE = /\A#{Regexp.quote(__FILE__)}:/o @@ -103,7 +102,7 @@ def timeout(sec, klass = nil) #:yield: +sec+ bt = e.backtrace end else - bt = ExitException.catch(message, &bl) + bt = Error.catch(message, &bl) end rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o bt.reject! {|m| rej =~ m} diff --git a/load.c b/load.c index e5014c165faef0..fe34b422eef27e 100644 --- a/load.c +++ b/load.c @@ -319,7 +319,7 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len, const char *e; if (vlen < len+1) return 0; - if (!strncmp(name+(vlen-len), feature, len)) { + if (strchr(feature, '.') && !strncmp(name+(vlen-len), feature, len)) { plen = vlen - len; } else { diff --git a/marshal.c b/marshal.c index a0630cb35ca2ba..4cf4edc88b2e26 100644 --- a/marshal.c +++ b/marshal.c @@ -1272,7 +1272,9 @@ r_symreal(struct load_arg *arg, int ivar) int idx = -1; st_index_t n = arg->symbols->num_entries; - st_insert(arg->symbols, (st_data_t)n, (st_data_t)0); + if (rb_enc_str_asciionly_p(s)) rb_enc_associate_index(s, ENCINDEX_US_ASCII); + id = rb_intern_str(s); + st_insert(arg->symbols, (st_data_t)n, (st_data_t)id); if (ivar) { long num = r_long(arg); while (num-- > 0) { @@ -1282,7 +1284,6 @@ r_symreal(struct load_arg *arg, int ivar) } if (idx > 0) rb_enc_associate_index(s, idx); id = rb_intern_str(s); - st_insert(arg->symbols, (st_data_t)n, (st_data_t)id); return id; } diff --git a/numeric.c b/numeric.c index b7a4e968efdcd4..ba2fb49b3b28a4 100644 --- a/numeric.c +++ b/numeric.c @@ -236,9 +236,14 @@ NORETURN(static void coerce_failed(VALUE x, VALUE y)); static void coerce_failed(VALUE x, VALUE y) { + if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) { + y = rb_inspect(y); + } + else { + y = rb_obj_class(y); + } rb_raise(rb_eTypeError, "%"PRIsVALUE" can't be coerced into %"PRIsVALUE, - (rb_special_const_p(y)? rb_inspect(y) : rb_obj_class(y)), - rb_obj_class(x)); + y, rb_obj_class(x)); } static VALUE @@ -1110,10 +1115,14 @@ flo_eq(VALUE x, VALUE y) static VALUE flo_hash(VALUE num) { - double d; + return rb_dbl_hash(RFLOAT_VALUE(num)); +} + +VALUE +rb_dbl_hash(double d) +{ st_index_t hash; - d = RFLOAT_VALUE(num); /* normalize -0.0 to 0.0 */ if (d == 0.0) d = 0.0; hash = rb_memhash(&d, sizeof(d)); @@ -3295,11 +3304,12 @@ static int bit_coerce(VALUE *x, VALUE *y, int err) { if (!FIXNUM_P(*y) && !RB_TYPE_P(*y, T_BIGNUM)) { + VALUE orig = *x; do_coerce(x, y, err); if (!FIXNUM_P(*x) && !RB_TYPE_P(*x, T_BIGNUM) && !FIXNUM_P(*y) && !RB_TYPE_P(*y, T_BIGNUM)) { if (!err) return FALSE; - coerce_failed(*x, *y); + coerce_failed(orig, *y); } } return TRUE; diff --git a/parse.y b/parse.y index d091a0e6ef4a9d..80a45ebf63bb78 100644 --- a/parse.y +++ b/parse.y @@ -3467,14 +3467,20 @@ lambda : { { $$ = ruby_sourceline; } + { + $$ = cmdarg_stack; + cmdarg_stack = 0; + } lambda_body { lpar_beg = $2; + cmdarg_stack = $5; + CMDARG_LEXPOP(); /*%%%*/ - $$ = NEW_LAMBDA($3, $5); + $$ = NEW_LAMBDA($3, $6); nd_set_line($$, $4); /*% - $$ = dispatch2(lambda, $3, $5); + $$ = dispatch2(lambda, $3, $6); %*/ dyna_pop($1); } @@ -6952,6 +6958,27 @@ parser_prepare(struct parser_params *parser) space_seen && !ISSPACE(c) && \ (ambiguous_operator(op, syn), 0))) +static int +parse_numvar(struct parser_params *parser) +{ + size_t len; + int overflow; + unsigned long n = ruby_scan_digits(tok()+1, toklen()-1, 10, &len, &overflow); + const unsigned long nth_ref_max = + (FIXNUM_MAX / 2 < INT_MAX) ? FIXNUM_MAX / 2 : INT_MAX; + /* NTH_REF is left-shifted to be ORed with back-ref flag and + * turned into a Fixnum, in compile.c */ + + if (overflow || n > nth_ref_max) { + /* compile_error()? */ + rb_warnS("`%s' is too big for a number variable, always nil", tok()); + return 0; /* $0 is $PROGRAM_NAME, not NTH_REF */ + } + else { + return (int)n; + } +} + static int parser_yylex(struct parser_params *parser) { @@ -8048,7 +8075,7 @@ parser_yylex(struct parser_params *parser) pushback(c); if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar; tokfix(); - set_yylval_node(NEW_NTH_REF(atoi(tok()+1))); + set_yylval_node(NEW_NTH_REF(parse_numvar(parser))); return tNTH_REF; default: diff --git a/range.c b/range.c index 3ca9c2feda4e78..2b5d9394b5e9a6 100644 --- a/range.c +++ b/range.c @@ -329,6 +329,21 @@ discrete_object_p(VALUE obj) return rb_respond_to(obj, id_succ); } +static int +linear_object_p(VALUE obj) +{ + if (FIXNUM_P(obj) || FLONUM_P(obj)) return TRUE; + if (SPECIAL_CONST_P(obj)) return FALSE; + switch (BUILTIN_TYPE(obj)) { + case T_FLOAT: + case T_BIGNUM: + return TRUE; + } + if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE; + if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE; + return FALSE; +} + static VALUE range_step_size(VALUE range, VALUE args, VALUE eobj) { @@ -1148,8 +1163,7 @@ range_include(VALUE range, VALUE val) VALUE beg = RANGE_BEG(range); VALUE end = RANGE_END(range); int nv = FIXNUM_P(beg) || FIXNUM_P(end) || - rb_obj_is_kind_of(beg, rb_cNumeric) || - rb_obj_is_kind_of(end, rb_cNumeric); + linear_object_p(beg) || linear_object_p(end); if (nv || !NIL_P(rb_check_to_integer(beg, "to_int")) || diff --git a/rational.c b/rational.c index d8bee601e09937..1c0f7deb1c20ea 100644 --- a/rational.c +++ b/rational.c @@ -2451,13 +2451,14 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass) * a/b (b>0). Where a is numerator and b is denominator. Integer a * equals rational a/1 mathematically. * - * In ruby, you can create rational object with Rational, to_r or - * rationalize method. The return values will be irreducible. + * In ruby, you can create rational object with Rational, to_r, + * rationalize method or suffixing r to a literal. The return values will be irreducible. * * Rational(1) #=> (1/1) * Rational(2, 3) #=> (2/3) * Rational(4, -6) #=> (-2/3) * 3.to_r #=> (3/1) + * 2/3r #=> (2/3) * * You can also create rational object from floating-point numbers or * strings. diff --git a/re.c b/re.c index e9fd7acf634b3f..1353e6da405218 100644 --- a/re.c +++ b/re.c @@ -223,6 +223,32 @@ rb_memsearch_qs_utf8(const unsigned char *xs, long m, const unsigned char *ys, l return -1; } +static inline long +rb_memsearch_wchar(const unsigned char *xs, long m, const unsigned char *ys, long n) +{ + const unsigned char *x = xs, x0 = *xs, *y = ys; + enum {char_size = 2}; + + for (n -= m; n > 0; n -= char_size, y += char_size) { + if (x0 == *y && memcmp(x+1, y+1, m-1) == 0) + return y - ys; + } + return -1; +} + +static inline long +rb_memsearch_qchar(const unsigned char *xs, long m, const unsigned char *ys, long n) +{ + const unsigned char *x = xs, x0 = *xs, *y = ys; + enum {char_size = 4}; + + for (n -= m; n > 0; n -= char_size, y += char_size) { + if (x0 == *y && memcmp(x+1, y+1, m-1) == 0) + return y - ys; + } + return -1; +} + long rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc) { @@ -243,15 +269,21 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc) else return -1; } - else if (m <= SIZEOF_VALUE) { - return rb_memsearch_ss(x0, m, y0, n); + else if (rb_enc_mbminlen(enc) == 1) { + if (m <= SIZEOF_VALUE) { + return rb_memsearch_ss(x0, m, y0, n); + } + else if (enc == rb_utf8_encoding()){ + return rb_memsearch_qs_utf8(x0, m, y0, n); + } } - else if (enc == rb_utf8_encoding()){ - return rb_memsearch_qs_utf8(x0, m, y0, n); + else if (rb_enc_mbminlen(enc) == 2) { + return rb_memsearch_wchar(x0, m, y0, n); } - else { - return rb_memsearch_qs(x0, m, y0, n); + else if (rb_enc_mbminlen(enc) == 4) { + return rb_memsearch_qchar(x0, m, y0, n); } + return rb_memsearch_qs(x0, m, y0, n); } #define REG_LITERAL FL_USER5 diff --git a/string.c b/string.c index 338648fa28819b..d9a9315c9dad22 100644 --- a/string.c +++ b/string.c @@ -4107,6 +4107,9 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str) * double-quoted string, both back-references must be preceded by an * additional backslash. However, within +replacement+ the special match * variables, such as &$, will not refer to the current match. + * If +replacement+ is a String that looks like a pattern's capture group but + * is actaully not a pattern capture group e.g. "\\'", then it + * will have to be preceded by two backslashes like so "\\\\'". * * If the second argument is a Hash, and the matched text is one of its keys, * the corresponding value is the replacement string. @@ -4560,13 +4563,14 @@ rb_str_reverse(VALUE str) rb_encoding *enc; VALUE rev; char *s, *e, *p; - int single = 1; + int cr; if (RSTRING_LEN(str) <= 1) return rb_str_dup(str); enc = STR_ENC_GET(str); rev = rb_str_new5(str, 0, RSTRING_LEN(str)); s = RSTRING_PTR(str); e = RSTRING_END(str); p = RSTRING_END(rev); + cr = ENC_CODERANGE(str); if (RSTRING_LEN(str) > 1) { if (single_byte_optimizable(str)) { @@ -4574,21 +4578,22 @@ rb_str_reverse(VALUE str) *--p = *s++; } } - else if (ENC_CODERANGE(str) == ENC_CODERANGE_VALID) { + else if (cr == ENC_CODERANGE_VALID) { while (s < e) { int clen = rb_enc_fast_mbclen(s, e, enc); - if (clen > 1 || (*s & 0x80)) single = 0; p -= clen; memcpy(p, s, clen); s += clen; } } else { + cr = rb_enc_asciicompat(enc) ? + ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID; while (s < e) { int clen = rb_enc_mbclen(s, e, enc); - if (clen > 1 || (*s & 0x80)) single = 0; + if (clen > 1 || (*s & 0x80)) cr = ENC_CODERANGE_UNKNOWN; p -= clen; memcpy(p, s, clen); s += clen; @@ -4597,15 +4602,8 @@ rb_str_reverse(VALUE str) } STR_SET_LEN(rev, RSTRING_LEN(str)); OBJ_INFECT(rev, str); - if (ENC_CODERANGE(str) == ENC_CODERANGE_UNKNOWN) { - if (single) { - ENC_CODERANGE_SET(str, ENC_CODERANGE_7BIT); - } - else { - ENC_CODERANGE_SET(str, ENC_CODERANGE_VALID); - } - } - rb_enc_cr_str_copy_for_substr(rev, str); + str_enc_copy(rev, str); + ENC_CODERANGE_SET(rev, cr); return rev; } @@ -6234,15 +6232,10 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) } enc = STR_ENC_GET(str); - if (NIL_P(spat)) { - if (!NIL_P(rb_fs)) { - spat = rb_fs; - goto fs_set; - } + if (NIL_P(spat) && NIL_P(spat = rb_fs)) { split_type = awk; } else { - fs_set: if (RB_TYPE_P(spat, T_STRING)) { rb_encoding *enc2 = STR_ENC_GET(spat); diff --git a/test/-ext-/win32/test_dln.rb b/test/-ext-/win32/test_dln.rb index c9065e66fb7168..5573edc1e13690 100644 --- a/test/-ext-/win32/test_dln.rb +++ b/test/-ext-/win32/test_dln.rb @@ -13,7 +13,7 @@ def test_check_imported def test_nonascii_load bug9699 = '[ruby-core:61845] [Bug #9699]' - so = "-test-/win32/dln/empty." + RbConfig::CONFIG["DLEXT"] + so = "-test-/dln/empty." + RbConfig::CONFIG["DLEXT"] so = $:.find {|d| d = ::File.join(d, so); break d if ::File.exist?(d)} assert_not_nil(so) Dir.mkdir(dir = ::File.join(testdir = Dir.mktmpdir("test"), "\u{30c6 30b9 30c8}")) diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb index 0bb6c823e395a9..2007a191b6b8de 100644 --- a/test/fiddle/test_handle.rb +++ b/test/fiddle/test_handle.rb @@ -30,18 +30,23 @@ def test_static_sym_unknown end def test_static_sym - skip "Fiddle::Handle.sym is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM begin # Linux / Darwin / FreeBSD refute_nil Fiddle::Handle.sym('dlopen') assert_equal Fiddle::Handle.sym('dlopen'), Fiddle::Handle['dlopen'] + return rescue + end + + begin # NetBSD require '-test-/dln/empty' refute_nil Fiddle::Handle.sym('Init_empty') assert_equal Fiddle::Handle.sym('Init_empty'), Fiddle::Handle['Init_empty'] + return + rescue end - end + end unless /mswin|mingw/ =~ RUBY_PLATFORM def test_sym_closed_handle handle = Fiddle::Handle.new(LIBC_SO) @@ -152,7 +157,11 @@ def test_NEXT # --- Ubuntu Linux 8.04 dlsym(3) handle = Handle::NEXT refute_nil handle['malloc'] + return rescue + end + + begin # BSD # # If dlsym() is called with the special handle RTLD_NEXT, then the search @@ -169,11 +178,12 @@ def test_NEXT require '-test-/dln/empty' handle = Handle::NEXT refute_nil handle['Init_empty'] + return + rescue end end unless /mswin|mingw/ =~ RUBY_PLATFORM def test_DEFAULT - skip "Handle::DEFAULT is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM handle = Handle::DEFAULT refute_nil handle['malloc'] end unless /mswin|mingw/ =~ RUBY_PLATFORM diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index 6aa89c49eff03e..c409447def93e1 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -390,7 +390,8 @@ def test_mv mkdir 'tmp/tmpdir' mkdir_p 'tmp/dest2/tmpdir' - assert_raise(Errno::EEXIST) { + assert_raise_with_message(Errno::EEXIST, %r' - tmp/dest2/tmpdir\z', + '[ruby-core:68706] [Bug #11021]') { mv 'tmp/tmpdir', 'tmp/dest2' } mkdir 'tmp/dest2/tmpdir/junk' diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb index f25e10747b8d37..423cfe8e9e2f29 100644 --- a/test/net/ftp/test_ftp.rb +++ b/test/net/ftp/test_ftp.rb @@ -477,6 +477,46 @@ def test_list_fail end end + def test_open_data_port_fail_no_leak + commands = [] + server = create_ftp_server { |sock| + sock.print("220 (test_ftp).\r\n") + commands.push(sock.gets) + sock.print("331 Please specify the password.\r\n") + commands.push(sock.gets) + sock.print("230 Login successful.\r\n") + commands.push(sock.gets) + sock.print("200 Switching to Binary mode.\r\n") + commands.push(sock.gets) + sock.print("200 Switching to ASCII mode.\r\n") + line = sock.gets + commands.push(line) + sock.print("421 Service not available, closing control connection.\r\n") + commands.push(sock.gets) + sock.print("200 Switching to Binary mode.\r\n") + } + begin + begin + ftp = Net::FTP.new + ftp.read_timeout = 0.2 + ftp.connect(SERVER_ADDR, server.port) + ftp.login + assert_match(/\AUSER /, commands.shift) + assert_match(/\APASS /, commands.shift) + assert_equal("TYPE I\r\n", commands.shift) + assert_raise(Net::FTPTempError){ ftp.list } + assert_equal("TYPE A\r\n", commands.shift) + assert_match(/\APORT /, commands.shift) + assert_equal("TYPE I\r\n", commands.shift) + assert_equal(nil, commands.shift) + ensure + ftp.close if ftp + end + ensure + server.close + end + end + def test_retrbinary_read_timeout_exceeded commands = [] binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3 diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb index 0193a153e467db..404c7ae1fa8113 100644 --- a/test/net/http/test_httpresponse.rb +++ b/test/net/http/test_httpresponse.rb @@ -103,6 +103,34 @@ def test_read_body_content_encoding_deflate end end + def test_read_body_content_encoding_deflate_uppercase + io = dummy_io(< bug10979} + assert_equal(bug10979, h[-0.0]) + end end diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index d811598ccec1ec..0897fd851f5142 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -1269,8 +1269,14 @@ def eql?(other) end end - hash = {5 => bug9381} - assert_equal(bug9381, hash[wrapper.new(5)]) + bad = [ + 5, true, false, nil, + 0.0, 1.72723e-77, + ].select do |x| + hash = {x => bug9381} + hash[wrapper.new(x)] != bug9381 + end + assert_empty(bad, bug9381) end class TestSubHash < TestHash diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 77ab97317a6e4c..18e37d6d0b03d2 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -1979,6 +1979,15 @@ def test_reopen_inherit } end + def test_reopen_stdio + mkcdtmpdir { + fname = 'bug11319' + File.write(fname, 'hello') + system(EnvUtil.rubybin, '-e', "STDOUT.reopen('#{fname}', 'w+')") + assert_equal('', File.read(fname)) + } + end + def test_reopen_mode feature7067 = '[ruby-core:47694]' make_tempfile {|t| diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 4e3f6c1926895c..5fe90b0ebf2aa2 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -124,4 +124,11 @@ def test_label_fstring ISeq.of(c.instance_method(:foobar)).label assert_same a, b end + + def test_invalid_source + bug11159 = '[ruby-core:69219] [Bug #11159]' + assert_raise(TypeError, bug11159) {ISeq.compile(nil)} + assert_raise(TypeError, bug11159) {ISeq.compile(:foo)} + assert_raise(TypeError, bug11159) {ISeq.compile(1)} + end end diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb index 5fa326acfec25c..6e5d41477e1065 100644 --- a/test/ruby/test_literal.rb +++ b/test/ruby/test_literal.rb @@ -193,7 +193,9 @@ def test_big_array_and_hash_literal assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("[#{(1..1_000_000).to_a.join(", ")}]").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("{#{(1..1_000_000).map{|n| "#{n} => x"}.join(', ')}}").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("{#{(1..1_000_000).map{|n| "#{n} => #{n}"}.join(', ')}}").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] + end + def test_big_hash_literal bug7466 = '[ruby-dev:46658]' h = { 0xFE042 => 0xE5CD, @@ -328,6 +330,19 @@ def test_big_array_and_hash_literal } k = h.keys assert_equal([129, 0xFE331], [k.size, k.last], bug7466) + + code = [ + "h = {", + (1..128).map {|i| "#{i} => 0,"}, + (129..140).map {|i| "#{i} => [],"}, + "}", + ].join + assert_separately([], <<-"end;") + GC.stress = true + #{code} + GC.stress = false + assert_equal(140, h.size) + end; end def test_range diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb index 7d00b1aec67b0e..8dc54e5f4b964b 100644 --- a/test/ruby/test_m17n.rb +++ b/test/ruby/test_m17n.rb @@ -1132,7 +1132,12 @@ def test_casecmp end def test_reverse - assert_equal(u("\xf0jihgfedcba"), u("abcdefghij\xf0").reverse) + bug11387 = '[ruby-dev:49189] [Bug #11387]' + s1 = u("abcdefghij\xf0") + s2 = s1.reverse + assert_not_predicate(s1, :valid_encoding?, bug11387) + assert_equal(u("\xf0jihgfedcba"), s2) + assert_not_predicate(s2, :valid_encoding?, bug11387) end def test_reverse_bang @@ -1221,6 +1226,9 @@ def test_split each_encoding("abc,def", ",", "abc", "def") do |str, sep, *expected| assert_equal(expected, str.split(sep, -1)) end + each_encoding("abc\0def", "\0", "abc", "def") do |str, sep, *expected| + assert_equal(expected, str.split(sep, -1)) + end end def test_nonascii_method_name diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 126efc8ae691e1..967aa37723f908 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -246,6 +246,17 @@ def test_symbol2 assert_equal(ary, Marshal.load(Marshal.dump(ary)), bug2548) end + def test_symlink_in_ivar + bug10991 = '[ruby-core:68587] [Bug #10991]' + sym = Marshal.load("\x04\x08" + + "I" ":\x0bKernel" + + ("\x06" + + ("I" ":\x07@a" + + ("\x06" ":\x07@b" "e;\x0""o:\x0bObject""\x0")) + + "0")) + assert_equal(:Kernel, sym, bug10991) + end + ClassUTF8 = eval("class R\u{e9}sum\u{e9}; self; end") iso_8859_1 = Encoding::ISO_8859_1 diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 0e70078bad8996..98fabc4e136911 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -28,6 +28,10 @@ def test_coerce assert_raise_with_message(TypeError, /:"\\u3042"/) {1|:"\u{3042}"} assert_raise_with_message(TypeError, /:"\\u3042"/) {1^:"\u{3042}"} end + + bug10711 = '[ruby-core:67405] [Bug #10711]' + exp = "1.2 can't be coerced into Fixnum" + assert_raise_with_message(TypeError, exp, bug10711) { 1 & 1.2 } end def test_dummynumeric diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 65bb83d2f669d8..5a82547af14258 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -1263,6 +1263,29 @@ def test_waitall end end + def test_wait_exception + bug11340 = '[ruby-dev:49176] [Bug #11340]' + t0 = t1 = nil + IO.popen([RUBY, '-e', 'puts;STDOUT.flush;Thread.start{gets;exit};sleep(3)'], 'r+') do |f| + pid = f.pid + f.gets + t0 = Time.now + th = Thread.start(Thread.current) do |main| + Thread.pass until main.stop? + main.raise Interrupt + end + begin + assert_raise(Interrupt) {Process.wait(pid)} + ensure + th.kill.join + end + t1 = Time.now + f.puts + end + assert_operator(t1 - t0, :<, 3, + ->{"#{bug11340}: #{t1-t0} seconds to interrupt Process.wait"}) + end + def test_abort with_tmpchdir do s = run_in_child("abort") diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 41107e094a4df6..293818516d6cfe 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -278,6 +278,14 @@ def test_eqq assert_not_operator(0..10, :===, 11) end + def test_eqq_time + bug11113 = '[ruby-core:69052] [Bug #11113]' + t = Time.now + assert_nothing_raised(TypeError, bug11113) { + assert_operator(t..(t+10), :===, t+5) + } + end + def test_include assert_include("a".."z", "c") assert_not_include("a".."z", "5") diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index 4ed0423abdd0fe..b116dbbf62f048 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -1399,6 +1399,33 @@ def M.m1 INPUT end + def test_check_funcall_undefined + bug11117 = '[ruby-core:69064] [Bug #11117]' + + x = Class.new + Module.new do + refine x do + def to_regexp + // + end + end + end + + assert_nothing_raised(NoMethodError, bug11117) { + assert_nil(Regexp.try_convert(x.new)) + } + end + + def test_funcall_inherited + bug11117 = '[ruby-core:69064] [Bug #11117]' + + Module.new {refine(Dir) {def to_s; end}} + x = Class.new(Dir).allocate + assert_nothing_raised(NoMethodError, bug11117) { + x.inspect + } + end + private def eval_using(mod, s) diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index 2bdad8f981ca4d..562f0c13eaf078 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -687,4 +687,18 @@ def test_require_with_loaded_features_pop INPUT } end + + def test_loading_fifo_threading + Tempfile.create(%w'fifo .rb') {|f| + f.close + File.unlink(f.path) + File.mkfifo(f.path) + assert_separately(["-", f.path], <<-END, timeout: 3) + th = Thread.current + Thread.start {begin sleep(0.001) end until th.stop?; th.raise(IOError)} + assert_raise(IOError) {load(ARGV[0])} + END + } + rescue Errno::ENOENT + end unless /mswin|mingw/ =~ RUBY_PLATFORM end diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 5cb6d4a16e31ad..722228d0a1f2ab 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1348,4 +1348,24 @@ def test_b_call_with_redo } end end + + class Bug10724 + def initialize + loop{return} + end + end + + def test_throwing_return_with_finish_frame + target_th = Thread.current + evs = [] + + TracePoint.new(:call, :return){|tp| + return if Thread.current != target_th + evs << tp.event + }.enable{ + a = Bug10724.new + } + + assert_equal([:call, :return], evs) + end end diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 692763ef98cb7b..cf38b5974ce9a0 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -266,6 +266,16 @@ def test_do_block_in_call_args assert_valid_syntax("bar def foo; self.each do end end", bug9308) end + def test_do_block_in_lambda + bug11107 = '[ruby-core:69017] [Bug #11107]' + assert_valid_syntax('p ->() do a() do end end', bug11107) + end + + def test_do_block_after_lambda + bug11380 = '[ruby-core:70067] [Bug #11380]' + assert_valid_syntax('p -> { :hello }, a: 1 do end', bug11380) + end + def test_reserved_method_no_args bug6403 = '[ruby-dev:45626]' assert_valid_syntax("def self; :foo; end", __FILE__, bug6403) @@ -416,6 +426,13 @@ def test_null_range_cmdarg assert_syntax_error('0...%w.', /unterminated string/, bug10957) end + def test_too_big_nth_ref + bug11192 = '[ruby-core:69393] [Bug #11192]' + assert_warn(/too big/, bug11192) do + eval('$99999999999999999') + end + end + private def not_label(x) @result = x; @not_label ||= nil end diff --git a/test/ruby/test_transcode.rb b/test/ruby/test_transcode.rb index 5f3f51a67675ba..d18953dc70cde7 100644 --- a/test/ruby/test_transcode.rb +++ b/test/ruby/test_transcode.rb @@ -2091,4 +2091,31 @@ def test_valid_dummy_encoding assert_equal("\x00\x00\xFE\xFF\x00\x00\x00t\x00\x00\x00e\x00\x00\x00s\x00\x00\x00t", result.b, bug) end; end + + def test_loading_race + assert_separately([], <<-'end;') #do + bug11277 = '[ruby-dev:49106] [Bug #11277]' + num = 2 + th = (0...num).map do |i| + Thread.new {"\u3042".encode("EUC-JP")} + end + result = nil + assert_warning("", bug11277) do + assert_nothing_raised(Encoding::ConverterNotFoundError, bug11277) do + result = th.map(&:value) + end + end + expected = "\xa4\xa2".force_encoding(Encoding::EUC_JP) + assert_equal([expected]*num, result, bug11277) + end; + end + + def test_universal_newline + bug11324 = '[ruby-core:69841] [Bug #11324]' + usascii = Encoding::US_ASCII + s = "A\nB\r\nC".force_encoding(usascii) + assert_equal("A\nB\nC", s.encode(usascii, universal_newline: true), bug11324) + assert_equal("A\nB\nC", s.encode(usascii, universal_newline: true, undef: :replace), bug11324) + assert_equal("A\nB\nC", s.encode(usascii, universal_newline: true, undef: :replace, replace: ''), bug11324) + end end diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb index aaece6868b5bb4..a36be476befe11 100644 --- a/test/rubygems/test_gem_ext_cmake_builder.rb +++ b/test/rubygems/test_gem_ext_cmake_builder.rb @@ -20,7 +20,7 @@ def setup def test_self_build File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists| cmakelists.write <<-eo_cmake -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.6) install (FILES test.txt DESTINATION bin) eo_cmake end diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 79f3a58bfb07ef..d391b9073939cd 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -163,6 +163,21 @@ def test_no_proxy end def test_api_endpoint + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "gems.example.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values uri = URI.parse "http://gems.example.com/foo" target = MiniTest::Mock.new target.expect :target, "blah.com" @@ -171,7 +186,37 @@ def test_api_endpoint dns.expect :getresource, target, [String, Object] fetch = Gem::RemoteFetcher.new nil, dns - assert_equal URI.parse("http://blah.com/foo"), fetch.api_endpoint(uri) + assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values_that_starts_with_original + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "example.combadguy.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values_that_end_with_original + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "badexample.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) target.verify dns.verify @@ -744,7 +789,7 @@ def start_ssl_server(config = {}) server.mount_proc("/insecure_redirect") { |req, res| res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, req.query['to']) } - server.ssl_context.tmp_dh_callback = proc { OpenSSL::PKey::DH.new 128 } + server.ssl_context.tmp_dh_callback = proc {|_, _, k| OpenSSL::PKey::DH.new(k) } t = Thread.new do begin server.start diff --git a/test/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb index 61b889ed26478a..bf1f35d058cc15 100644 --- a/test/socket/test_addrinfo.rb +++ b/test/socket/test_addrinfo.rb @@ -4,6 +4,7 @@ end require "test/unit" +require_relative "../ruby/envutil" class TestSocketAddrinfo < Test::Unit::TestCase HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM @@ -468,6 +469,17 @@ def test_marshal assert_equal(ai1.canonname, ai2.canonname) end + def test_marshal_memory_leak + bug11051 = '[ruby-dev:48923] [Bug #11051]' + assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true) + d = Marshal.dump(Addrinfo.tcp("127.0.0.1", 80)) + 1000.times {Marshal.load(d)} + PREP + GC.start + 20_000.times {Marshal.load(d)} + CODE + end + if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer) def test_addrinfo_new_inet6 diff --git a/test/test_time.rb b/test/test_time.rb index 582e60b8ae01e4..12c8589209be3b 100644 --- a/test/test_time.rb +++ b/test/test_time.rb @@ -404,6 +404,17 @@ def test_strptime assert_equal(3600, Time.strptime('0 +0100', '%s %z').utc_offset) end + def test_strptime_s_N + assert_equal(Time.at(1, 500000), Time.strptime("1.5", "%s.%N")) + assert_equal(Time.at(-2, 500000), Time.strptime("-1.5", "%s.%N")) + t = Time.strptime("1.000000000001", "%s.%N") + assert_equal(1, t.to_i) + assert_equal(Rational("0.000000000001"), t.subsec) + t = Time.strptime("-1.000000000001", "%s.%N") + assert_equal(-2, t.to_i) + assert_equal(1-Rational("0.000000000001"), t.subsec) + end + def test_nsec assert_equal(123456789, Time.xmlschema("2000-01-01T00:00:00.123456789+00:00").tv_nsec) assert_equal(123456789, Time.parse("2000-01-01T00:00:00.123456789+00:00").tv_nsec) diff --git a/test/test_timeout.rb b/test/test_timeout.rb index e71a09f22ca8d4..e4eba7f902b7f3 100644 --- a/test/test_timeout.rb +++ b/test/test_timeout.rb @@ -63,9 +63,9 @@ def initialize(msg) super end end def test_exit_exception - assert_raise_with_message(Timeout::ExitException, "boon") do - Timeout.timeout(10, Timeout::ExitException) do - raise Timeout::ExitException, "boon" + assert_raise_with_message(Timeout::Error, "boon") do + Timeout.timeout(10, Timeout::Error) do + raise Timeout::Error, "boon" end end end @@ -80,4 +80,21 @@ def o.each Timeout.timeout(0.01) {e.next} end end + + def test_handle_interrupt + bug11344 = '[ruby-dev:49179] [Bug #11344]' + ok = false + assert_raise(Timeout::Error) { + Thread.handle_interrupt(Timeout::Error => :never) { + Timeout.timeout(0.01) { + sleep 0.2 + ok = true + Thread.handle_interrupt(Timeout::Error => :on_blocking) { + sleep 0.2 + } + } + } + } + assert(ok, bug11344) + end end diff --git a/thread_pthread.c b/thread_pthread.c index f3cd8702f8e9b1..ed4880c40c69b2 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -657,11 +657,16 @@ reserve_stack(volatile char *limit, size_t size) # endif struct rlimit rl; volatile char buf[0x100]; + enum {stack_check_margin = 0x1000}; /* for -fstack-check */ + STACK_GROW_DIR_DETECTION; if (!getrlimit(RLIMIT_STACK, &rl) && rl.rlim_cur == RLIM_INFINITY) return; + if (size < stack_check_margin) return; + size -= stack_check_margin; + size -= sizeof(buf); /* margin */ if (IS_STACK_DIR_UPPER()) { const volatile char *end = buf + sizeof(buf); @@ -669,13 +674,14 @@ reserve_stack(volatile char *limit, size_t size) if (limit > end) { size = limit - end; limit = alloca(size); - limit[size-1] = 0; + limit[stack_check_margin+size-1] = 0; } } else { limit -= size; if (buf > limit) { limit = alloca(buf - limit); + limit -= stack_check_margin; limit[0] = 0; } } diff --git a/transcode.c b/transcode.c index 0182a205c2cc65..406301cb8cc8a6 100644 --- a/transcode.c +++ b/transcode.c @@ -372,15 +372,12 @@ load_transcoder_entry(transcoder_entry_t *entry) char *const path = RSTRING_PTR(fn); const int safe = rb_safe_level(); - entry->lib = NULL; - memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1); memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len); rb_str_set_len(fn, total_len); FL_UNSET(fn, FL_TAINT); OBJ_FREEZE(fn); - if (!rb_require_safe(fn, safe > 3 ? 3 : safe)) - return NULL; + rb_require_safe(fn, safe > 3 ? 3 : safe); } if (entry->transcoder) @@ -2204,7 +2201,7 @@ rb_econv_set_replacement(rb_econv_t *ec, encname2 = rb_econv_encoding_to_insert_output(ec); - if (encoding_equal(encname, encname2)) { + if (!*encname2 || encoding_equal(encname, encname2)) { str2 = xmalloc(len); MEMCPY(str2, str, unsigned char, len); /* xxx: str may be invalid */ len2 = len; diff --git a/util.c b/util.c index b0f9030c42e9aa..d5d5de325a44d6 100644 --- a/util.c +++ b/util.c @@ -75,21 +75,25 @@ const signed char ruby_digit36_to_number_table[] = { /*f*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; -static unsigned long -scan_digits(const char *str, int base, size_t *retlen, int *overflow) +unsigned long +ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow) { const char *start = str; unsigned long ret = 0, x; unsigned long mul_overflow = (~(unsigned long)0) / base; - int c; + *overflow = 0; - while ((c = (unsigned char)*str++) != '\0') { - int d = ruby_digit36_to_number_table[c]; + if (!len) { + *retlen = 0; + return 0; + } + + do { + int d = ruby_digit36_to_number_table[(unsigned char)*str++]; if (d == -1 || base <= d) { - *retlen = (str-1) - start; - return ret; + break; } if (mul_overflow < ret) *overflow = 1; @@ -98,7 +102,7 @@ scan_digits(const char *str, int base, size_t *retlen, int *overflow) ret += d; if (ret < x) *overflow = 1; - } + } while (len < 0 || --len); *retlen = (str-1) - start; return ret; } @@ -150,7 +154,7 @@ ruby_strtoul(const char *str, char **endptr, int base) b = base == 0 ? 10 : base; } - ret = scan_digits(str, b, &len, &overflow); + ret = ruby_scan_digits(str, -1, b, &len, &overflow); if (0 < len) subject_found = str+len; diff --git a/version.h b/version.h index 11331cb9017734..60581a0b461a7f 100644 --- a/version.h +++ b/version.h @@ -1,10 +1,10 @@ -#define RUBY_VERSION "2.1.6" -#define RUBY_RELEASE_DATE "2015-04-13" -#define RUBY_PATCHLEVEL 336 +#define RUBY_VERSION "2.1.7" +#define RUBY_RELEASE_DATE "2015-08-18" +#define RUBY_PATCHLEVEL 400 #define RUBY_RELEASE_YEAR 2015 -#define RUBY_RELEASE_MONTH 4 -#define RUBY_RELEASE_DAY 13 +#define RUBY_RELEASE_MONTH 8 +#define RUBY_RELEASE_DAY 18 #include "ruby/version.h" diff --git a/vm.c b/vm.c index 212f7b01401f68..8f3ac5e7c06cb2 100644 --- a/vm.c +++ b/vm.c @@ -1285,6 +1285,30 @@ vm_frametype_name(const rb_control_frame_t *cfp) } #endif +static void +hook_before_rewind(rb_thread_t *th, rb_control_frame_t *cfp) +{ + switch (VM_FRAME_TYPE(th->cfp)) { + case VM_FRAME_MAGIC_METHOD: + RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0); + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil); + break; + case VM_FRAME_MAGIC_BLOCK: + case VM_FRAME_MAGIC_LAMBDA: + if (VM_FRAME_TYPE_BMETHOD_P(th->cfp)) { + EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil); + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, th->cfp->me->called_id, th->cfp->me->klass, Qnil); + } + else { + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil); + } + break; + case VM_FRAME_MAGIC_CLASS: + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->cfp->self, 0, 0, Qnil); + break; + } +} + /* evaluator body */ /* finish @@ -1383,7 +1407,6 @@ vm_frametype_name(const rb_control_frame_t *cfp) }; */ - static VALUE vm_exec(rb_thread_t *th) { @@ -1451,15 +1474,9 @@ vm_exec(rb_thread_t *th) } } if (!catch_iseqval) { - result = GET_THROWOBJ_VAL(err); th->errinfo = Qnil; - - switch (VM_FRAME_TYPE(cfp)) { - case VM_FRAME_MAGIC_LAMBDA: - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil); - break; - } - + result = GET_THROWOBJ_VAL(err); + hook_before_rewind(th, th->cfp); vm_pop_frame(th); goto finish_vme; } @@ -1598,26 +1615,7 @@ vm_exec(rb_thread_t *th) } else { /* skip frame */ - - switch (VM_FRAME_TYPE(th->cfp)) { - case VM_FRAME_MAGIC_METHOD: - RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0); - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil); - break; - case VM_FRAME_MAGIC_BLOCK: - case VM_FRAME_MAGIC_LAMBDA: - if (VM_FRAME_TYPE_BMETHOD_P(th->cfp)) { - EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil); - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, th->cfp->me->called_id, th->cfp->me->klass, Qnil); - } - else { - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil); - } - break; - case VM_FRAME_MAGIC_CLASS: - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->cfp->self, 0, 0, Qnil); - break; - } + hook_before_rewind(th, th->cfp); if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { vm_pop_frame(th); @@ -2271,7 +2269,11 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, #define REWIND_CFP(expr) do { \ rb_thread_t *th__ = GET_THREAD(); \ - th__->cfp++; expr; th__->cfp--; \ + VALUE *const curr_sp = (th__->cfp++)->sp; \ + VALUE *const saved_sp = th__->cfp->sp; \ + th__->cfp->sp = curr_sp; \ + expr; \ + (th__->cfp--)->sp = saved_sp; \ } while (0) static VALUE diff --git a/vm_eval.c b/vm_eval.c index da6338419fdfa5..5abd8a518db88e 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -533,8 +533,13 @@ rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type sc int noex; if (UNDEFINED_METHOD_ENTRY_P(me)) { + undefined: return scope == CALL_VCALL ? NOEX_VCALL : 0; } + if (me->def->type == VM_METHOD_TYPE_REFINED) { + me = rb_resolve_refined_method(Qnil, me, NULL); + if (UNDEFINED_METHOD_ENTRY_P(me)) goto undefined; + } klass = me->klass; oid = me->def->original_id; noex = me->flag; diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 20dc63f1e05d89..7a081d2b7406ec 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -200,16 +200,16 @@ lep_svar_set(rb_thread_t *th, VALUE *lep, rb_num_t key, VALUE val) switch (key) { case 0: - svar->u1.value = val; + RB_OBJ_WRITE(svar, &svar->u1.value, val); return; case 1: - svar->u2.value = val; + RB_OBJ_WRITE(svar, &svar->u2.value, val); return; default: { VALUE ary = svar->u3.value; if (NIL_P(ary)) { - svar->u3.value = ary = rb_ary_new(); + RB_OBJ_WRITE(svar, &svar->u3.value, ary = rb_ary_new()); } rb_ary_store(ary, key - DEFAULT_SPECIAL_VAR_COUNT, val); } diff --git a/win32/file.c b/win32/file.c index 0c5fda96113e72..de66e8cb95f121 100644 --- a/win32/file.c +++ b/win32/file.c @@ -1,5 +1,6 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" +#include "ruby/thread.h" #include "internal.h" #include #include @@ -415,6 +416,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na else { /* determine if we ignore dir or not later */ path_drive = wpath_pos[0]; + wpath_pos += 2; + wpath_len -= 2; } } else if (abs_mode == 0 && wpath_len >= 2 && wpath_pos[0] == L'~') { @@ -505,15 +508,11 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na /* determine if we ignore dir or not */ if (!ignore_dir && path_drive && dir_drive) { - if (towupper(path_drive) == towupper(dir_drive)) { - /* exclude path drive letter to use dir */ - wpath_pos += 2; - wpath_len -= 2; - } - else { + if (towupper(path_drive) != towupper(dir_drive)) { /* ignore dir since path drive is different from dir drive */ ignore_dir = 1; wdir_len = 0; + dir_drive = 0; } } @@ -544,6 +543,10 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na buffer_pos[0] = L'\\'; buffer_pos++; } + else if (!dir_drive && path_drive) { + *buffer_pos++ = path_drive; + *buffer_pos++ = L':'; + } if (wdir_len) { /* tainted if dir is used and dir is tainted */ @@ -668,6 +671,14 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na return result; } +static void * +loadopen_func(void *wpath) +{ + return (void *)CreateFileW(wpath, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +} + int rb_file_load_ok(const char *path) { @@ -684,9 +695,8 @@ rb_file_load_ok(const char *path) ret = 0; } else { - HANDLE h = CreateFileW(wpath, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE h = (HANDLE)rb_thread_call_without_gvl(loadopen_func, (void *)wpath, + RUBY_UBF_IO, 0); if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); } diff --git a/win32/win32.c b/win32/win32.c index ed5bfa778e70d4..f19c097abdd16a 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -4265,7 +4265,9 @@ waitpid(rb_pid_t pid, int *stat_loc, int options) while (!(pid = poll_child_status(child, stat_loc))) { /* wait... */ - if (rb_w32_wait_events_blocking(&child->hProcess, 1, timeout) != WAIT_OBJECT_0) { + int ret = rb_w32_wait_events_blocking(&child->hProcess, 1, timeout); + if (ret == WAIT_OBJECT_0 + 1) return -1; /* maybe EINTR */ + if (ret != WAIT_OBJECT_0) { /* still active */ if (options & WNOHANG) { pid = 0; @@ -6274,12 +6276,16 @@ rb_w32_close(int fd) } static int -setup_overlapped(OVERLAPPED *ol, int fd) +setup_overlapped(OVERLAPPED *ol, int fd, int iswrite) { memset(ol, 0, sizeof(*ol)); if (!(_osfile(fd) & (FDEV | FPIPE))) { LONG high = 0; - DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT; + /* On mode:a, it can write only FILE_END. + * On mode:a+, though it can write only FILE_END, + * it can read from everywhere. + */ + DWORD method = ((_osfile(fd) & FAPPEND) && iswrite) ? FILE_END : FILE_CURRENT; DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method); #ifndef INVALID_SET_FILE_POINTER #define INVALID_SET_FILE_POINTER ((DWORD)-1) @@ -6376,7 +6382,7 @@ rb_w32_read(int fd, void *buf, size_t size) /* if have cancel_io, use Overlapped I/O */ if (cancel_io) { - if (setup_overlapped(&ol, fd)) { + if (setup_overlapped(&ol, fd, FALSE)) { MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); return -1; } @@ -6494,7 +6500,7 @@ rb_w32_write(int fd, const void *buf, size_t size) /* if have cancel_io, use Overlapped I/O */ if (cancel_io) { - if (setup_overlapped(&ol, fd)) { + if (setup_overlapped(&ol, fd, TRUE)) { MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); return -1; }