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; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy