diff --git a/ChangeLog b/ChangeLog index f6e3807c6e1c05..298c3722fc52a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,545 @@ Thu Mar 6 10:33:31 2014 Martin Bosslet Reported by Jeff Hodges. [ruby-core:59829] [Bug #9424] -Tue Jan 14 02:20:00 2014 Kenta Murata +Mon Feb 24 13:05:48 2014 Aaron Patterson + + * ext/psych/lib/psych.rb: New release of psych. + * ext/psych/psych.gemspec: ditto + +Mon Feb 24 13:05:48 2014 Aaron Patterson + + * ext/psych/yaml/emitter.c: merge libyaml 0.1.5 + * ext/psych/yaml/loader.c: ditto + * ext/psych/yaml/parser.c: ditto + * ext/psych/yaml/reader.c: ditto + * ext/psych/yaml/scanner.c: ditto + * ext/psych/yaml/writer.c: ditto + * ext/psych/yaml/yaml_private.h: ditto + +Sat Feb 22 22:26:43 2014 NAKAMURA Usaku + + * ext/io/console/console.c (console_dev): need read access for conout$ + because some functions need it. [Bug#9554] + +Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada + + * compile.c (iseq_set_arguments): set arg_keyword_check from + nd_cflag, which is set by parser. internal ID is used for + unnamed keyword rest argument, which should be separated from no + keyword check. + + * iseq.c (rb_iseq_parameters): if no keyword check, keyword rest is + present. + + * parse.y (new_args_tail_gen): set keywords check to nd_cflag, which + equals to that keyword rest is not present. + +Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada + + * iseq.c (rb_iseq_parameters): push argument type symbol only for + unnamed rest keywords argument. + +Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada + + * proc.c (rb_iseq_min_max_arity): maximum argument is unlimited if + having rest keywords argument. [ruby-core:53298] [Bug #8072] + +Sat Feb 22 18:55:08 2014 Shugo Maeda + + * ext/socket/init.c (wait_connectable): break if the socket is + writable to avoid infinite loops on FreeBSD and other platforms + which conforms to SUSv3. This problem cannot be reproduced with + loopback interfaces, so it's hard to write test code. + rsock_connect() and wait_connectable() are overly complicated, so + they should be refactored, but I commit this fix as a workaround + for the release of Ruby 1.9.3 scheduled on Feb 24. + [ruby-core:60940] [Bug #9547] + +Sat Feb 22 18:48:57 2014 Nobuyoshi Nakada + + * class.c (rb_mod_init_copy): do nothing if copying self. + [ruby-dev:47989] [Bug #9535] + + * hash.c (rb_hash_initialize_copy): ditto. + +Sat Feb 22 18:20:58 2014 Masaki Matsushita + + * hash.c (rb_hash_flatten): fix behavior of flatten(-1). + [ruby-dev:47988] [Bug #9533] + + * test/ruby/test_array.rb: test for above. + +Sat Feb 22 17:46:32 2014 Tanaka Akira + + * lib/open-uri.rb: Make proxy disabling working again. + Fixed by Christophe Philemotte. [ruby-core:59650] [Bug #9385] + +Sat Feb 22 17:33:39 2014 Nobuyoshi Nakada + + * eval.c (rb_mod_s_constants): return its own constants for other + than Module itself. [ruby-core:59763] [Bug #9413] + +Sat Feb 22 16:51:36 2014 Eric Wong + + * ext/json/generator/depend: add build dependencies for json extension + [Bug #9374] [ruby-core:59609] + * ext/json/parser/depend: ditto + +Sat Feb 22 16:34:12 2014 Yusuke Endoh + + * ext/fiddle/closure.c: use sizeof(*pcl) for correct sizeof value. + [ruby-core:57599] [Bug #8978]. + +Sat Feb 22 16:34:12 2014 Aaron Patterson + + * ext/fiddle/closure.c: use sizeof(*pcl) for correct sizeof value. + [ruby-core:57599] [Bug #8978]. Thanks mame! + +Sat Feb 22 16:17:54 2014 Eric Wong + + * ext/socket/ancdata.c (bsock_sendmsg_internal): only retry on error + (bsock_recvmsg_internal): ditto + * test/socket/test_unix.rb: test above for infinite loop + +Sat Feb 22 15:56:53 2014 Nobuyoshi Nakada + + * thread_pthread.c (rb_thread_create_timer_thread): fix for platforms + where PTHREAD_STACK_MIN is a dynamic value and not a compile-time + constant. [ruby-dev:47911] [Bug #9436] + +Sat Feb 22 15:56:53 2014 Nobuyoshi Nakada + + * thread_pthread.c (rb_thread_create_timer_thread): expand timer + thread stack size to get rid of segfault on FreeBSD/powerpc64. + based on the patch by Steve Wills at [ruby-core:59923]. + [ruby-core:56590] [Bug #8783] + +Sat Feb 22 15:13:38 2014 Benoit Daloze + + * range.c (Range#size): [DOC] improve description and add examples. + Patch by @skade. [Fixes GH-501] + +Sat Feb 22 15:07:58 2014 Zachary Scott + + * lib/racc/rdoc/grammar.en.rdoc: [DOC] Correct grammar and typos + Patch by Giorgos Tsiftsis [Bug #9429] [ci skip] + +Sat Feb 22 15:06:32 2014 Zachary Scott + + * lib/open-uri.rb: [DOC] use lower case version of core classes, same + as commit r44878, based on patch by Jonathan Jackson [Bug #9483] + +Sat Feb 22 15:06:32 2014 Zachary Scott + + * ext/ripper/lib/ripper/lexer.rb: [DOC] use lower case version of core + classes when referring to return value, since we aren't directly + talking about the class. Patch by Jonathan Jackson [Bug #9483] + +Sat Feb 22 15:03:05 2014 Ayumu AIZAWA + + * variable.c: adding extra example in docs. + patched by Steve Klabnik. [Bug #9210] + +Sat Feb 22 15:01:21 2014 Tanaka Akira + + * lib/resolv.rb (Resolv::DNS::Resource::TXT#data): Return concatenated + string. + Patch by Ryan Brunner. [ruby-core:58220] [Bug #9093] + +Sat Feb 22 14:52:55 2014 Zachary Scott + + * ext/openssl/ossl_pkey_dh.c: Fixed typo by Sandor Szuecs [Bug #9243] + +Sat Feb 22 14:45:36 2014 Zachary Scott + + * lib/xmlrpc/client.rb: [DOC] Remove note about SSL package on RAA + Since RAA has been deprecated, and the SSL package has been replaced + with net/https this statement is entirely false and should be + deleted. [Bug #9152] + +Sat Feb 22 14:31:23 2014 Zachary Scott + + * lib/net/smtp.rb: [DOC] Remove dead link to RAA by Giorgos Tsiftsis + Fixes the following bugs: [Bug #9152] [Bug #9268] [Bug #9394] + * lib/open-uri.rb: ditto + +Sat Feb 22 14:18:35 2014 Tanaka Akira + + * lib/resolv.rb: Ignore name servers which cause EAFNOSUPPORT on + socket creation. + Reported by Bjoern Rennhak. [ruby-core:60442] [Bug #9477] + +Sat Feb 22 14:07:04 2014 Tanaka Akira + + * lib/resolv.rb (Resolv::DNS::Message::MessageDecoder): Raise + DecodeError if no data before the limit. + Reported by Will Bryant. [ruby-core:60557] [Bug #9498] + +Sat Feb 22 13:49:30 2014 Shugo Maeda + + * vm_insnhelper.c (vm_call_method): should check ci->me->flag of + a refining method in case the method is private. + [ruby-core:60111] [Bug #9452] + + * vm_method.c (make_method_entry_refined): set me->flag of a refined + method entry to NOEX_PUBLIC in case the original method is private + and it is refined as a public method. The original flag is stored + in me->def->body.orig_me, so it's OK to make a refined method + entry public. [ruby-core:60111] [Bug #9452] + + * test/ruby/test_refinement.rb: related tests. + +Sat Feb 22 13:26:57 2014 Nobuyoshi Nakada + + * iseq.c (iseq_load): keep type_map to get rid of memory leak. + based on a patch by Eric Wong at [ruby-core:59699]. [Bug #9399] + +Sat Feb 22 13:17:32 2014 Masaki Matsushita + + * ext/thread/thread.c (rb_szqueue_clear): notify SZQUEUE_WAITERS + on SizedQueue#clear. [ruby-core:59462] [Bug #9342] + + * test/thread/test_queue.rb: add test. the patch is from + Justin Collins. + +Sat Feb 22 01:35:02 2014 Nobuyoshi Nakada + + * configure.in: check if pthread_setname_np is available. + + * thread_pthread.c: pthread_setname_np is not available on old + Darwins. [ruby-core:60524] [Bug #9492] + +Sat Feb 22 00:21:50 2014 Nobuyoshi Nakada + + * parse.y (local_push_gen, local_pop_gen): save cmdarg_stack to + isolate command argument state from outer scope. + [ruby-core:59342] [Bug #9308] + +Fri Feb 21 23:51:38 2014 Nobuyoshi Nakada + + * encoding.c (must_encindex, rb_enc_from_index, rb_obj_encoding): mask + encoding index and ignore dummy flags. [ruby-core:59354] [Bug #9314] + +Fri Feb 21 23:10:12 2014 Nobuyoshi Nakada + + * lib/mkmf.rb (RbConfig): expand RUBY_SO_NAME for extensions + backward compatibility. [ruby-core:59426] [Bug #9329] + +Fri Feb 21 23:07:56 2014 Akio Tajima + + * win32/Makefile.sub: remove HAVE_FSEEKO because fseeko removed from win32/win32.c + Fixed [Bug #9333]. + +Fri Feb 21 23:00:34 2014 Aaron Patterson + + * ext/psych/lib/psych/visitors/yaml_tree.rb: dumping strings with + quotes should not have changed. [ruby-core:59316] [Bug #9300] + + * ext/psych/lib/psych.rb: fixed missing require. + + * test/psych/test_string.rb: test + +Sun Feb 2 05:48:42 2014 Eric Wong + + * io.c (rb_io_syswrite): add RB_GC_GUARD + [Bug #9472][ruby-core:60407] + +Fri Feb 21 17:42:42 2014 Nobuyoshi Nakada + + * lib/resolv.rb (Resolv::Hosts#lazy_initialize): should not + consider encodings in hosts file. [ruby-core:59239] [Bug #9273] + + * lib/resolv.rb (Resolv::Config.parse_resolv_conf): ditto. + +Fri Feb 21 16:47:20 2014 Nobuyoshi Nakada + + * string.c (get_encoding): respect BOM on pseudo encodings. + [ruby-dev:47895] [Bug #9415] + +Fri Feb 21 16:47:20 2014 Nobuyoshi Nakada + + * string.c (get_actual_encoding): get actual encoding according to + the BOM if exists. + + * string.c (rb_str_inspect): use according encoding, instead of + pseudo encodings, UTF-{16,32}. [ruby-core:59757] [Bug #8940] + +Fri Feb 21 13:39:21 2014 Charlie Somerville + + * compile.c (iseq_build_from_ary_body): Use :blockptr instead of :block + as hash key when loading serialized instruction sequences from arrays. + [Bug #9455] [ruby-core:60146] + +Thu Feb 20 12:58:45 2014 Tanaka Akira + + * process.c (READ_FROM_CHILD): Apply the last hunk of + 0001-process.c-avoid-EINTR-from-Process.spawn.patch written by + Eric Wong in [Bug #8770]. + +Thu Feb 20 12:58:45 2014 Eric Wong + + * process.c (send_child_error): retry write on EINTR to fix + occasional Errno::EINTR from Process.spawn. + + * process.c (recv_child_error): retry read on EINTR to fix + occasional Errno::EINTR from Process.spawn. + +Thu Feb 20 12:24:59 2014 Eric Hodel + + * lib/rinda/ring.rb (Rinda::RingFinger#make_socket): Use + ipv4_multicast_ttl option for portability. + +Thu Feb 20 10:19:40 2014 Tanaka Akira + + * ext/socket/option.c: IP_MULTICAST_LOOP and IP_MULTICAST_TTL socket + option takes a byte on OpenBSD. + Fixed by Jeremy Evans. [ruby-core:59496] [Bug #9350] + +Wed Feb 19 15:25:13 2014 Koichi Sasada + + * gc.c (ruby_gc_set_params): don't show obsolete warnings for + RUBY_FREE_MIN/RUBY_HEAP_MIN_SLOTS if + RUBY_GC_HEAP_FREE_SLOTS/RUBY_GC_HEAP_INIT_SLOTS are given. + [Bug #9276] + +Wed Feb 19 14:25:55 2014 Koichi Sasada + + * test/ruby/test_gc.rb: ignore warning messages for running with -w + option such as chkbuild. + +Wed Feb 19 14:25:55 2014 Koichi Sasada + + * gc.c (get_envparam_double): fix a warning message. + +Wed Feb 19 14:25:55 2014 Koichi Sasada + + * gc.c: introduce new environment variable + "RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR" to control major/minor GC + frequency. + + Do full GC when the number of old objects is more than R * N + where R is this factor and + N is the number of old objects just after last full GC. + + * test/ruby/test_gc.rb: add a test. + +Wed Feb 19 07:51:02 2014 Eric Hodel + + * lib/rinda/ring.rb (Rinda::RingFinger#make_socket): Use + ipv4_multicast_loop option for portability. Patch by Jeremy Evans. + [ruby-trunk - Bug #9351] + +Mon Feb 17 05:43:20 2014 Nobuyoshi Nakada + + * configure.in: reset LDFLAGS and DLDFLAGS for opt-dir again after + LIBPATHFLAG and RPATHFLAG are set. [ruby-dev:47868] [Bug #9317] + +Sun Feb 16 07:13:36 2014 Tanaka Akira + + * configure.in: Fix compilation error. + https://bugs.ruby-lang.org/issues/8358#note-16 + +Sun Feb 16 07:13:36 2014 Vit Ondruch + + * configure.in: add qouting brackets and append wildcard for the + rest after target_cpu, to properly detect platform for SSE2 + instructions. [ruby-core:60576] [Bug #8358] + +Sun Feb 16 07:13:36 2014 Nobuyoshi Nakada + + * configure.in: -mstackrealign is necessary for -msse2 working. + [ruby-core:54716] [Bug #8349] + +Sun Feb 16 07:13:36 2014 Nobuyoshi Nakada + + * configure.in: -mstackrealign is necessary for -msse2 working. + [ruby-core:54716] [Bug #8349] + + * configure.in: use SSE2 instructions to drop unexpected precisions on + other than mingw. [ruby-core:59472] [Bug #8358] + +Sun Feb 16 07:13:36 2014 Nobuyoshi Nakada + + * configure.in: use SSE2 instructions for drop unexpected + precisions. [ruby-core:54738] [Bug #8358] + +Fri Feb 7 04:19:19 2014 Koichi Sasada + + * gc.c (get_envparam_int): correct warning messsages. + + * gc.c (get_envparam_double): ditto. + +Fri Feb 7 04:19:19 2014 Koichi Sasada + + * gc.c (get_envparam_int): don't accept a value equals to lowerbound + (changed by last commit) because "" or "foo" (not a number) strings + are parsed as 0. They should be rejected. + + * gc.c (get_envparam_double): ditto. + +Thu Feb 6 08:23:28 2014 Eric Wong + + * ext/thread/thread.c (rb_szqueue_max_set): use correct queue and + limit wakeups. [Bug #9343][ruby-core:60517] + * test/thread/test_queue.rb (test_sized_queue_assign_max): + test for bug + +Thu Feb 6 11:27:39 2014 Eric Hodel + + * lib/rubygems: RubyGems 2.2.2 which contains the following bug fixes: + http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.2.2+%2F+2014-02-05 + https://bugs.ruby-lang.org/issues/9489 + +Thu Feb 6 11:23:59 2014 Koichi Sasada + + * gc.c (ruby_gc_set_params): if RUBY_GC_OLDMALLOC_LIMIT is provided, + then set objspace->rgengc.oldmalloc_increase_limit. + Without this fix, the env variable RUBY_GC_OLDMALLOC_LIMIT + does not work. + + * gc.c (get_envparam_int): accept a value equals to lowerbound. + + * gc.c (get_envparam_double): ditto. + +Wed Feb 5 23:57:05 2014 Charlie Somerville + + * ext/thread/thread.c (rb_szqueue_push): check GET_SZQUEUE_WAITERS + instead of GET_QUEUE_WAITERS to prevent deadlock. Patch by Eric Wong. + [Bug #9302] [ruby-core:59324] + + * test/thread/test_queue.rb: add test + +Wed Feb 5 23:43:30 2014 NAKAMURA Usaku + + * hash.c (rb_objid_hash): should return `long'. brushup r44534. + + * object.c (rb_obj_hash): follow above change. + +Wed Feb 5 23:43:30 2014 NAKAMURA Usaku + + * hash.c (rb_any_hash): should treat the return value of rb_objid_hash() + as `long', because ruby assumes the hash value of the object id of + an object is `long'. + this fixes test failures on mswin64 introduced at r44525. + +Wed Feb 5 23:43:30 2014 Nobuyoshi Nakada + + * hash.c (rb_objid_hash): return hash value from object ID with a + salt, extract from rb_any_hash(). + + * object.c (rb_obj_hash): return same value as rb_any_hash(). + fix r44125. [ruby-core:59638] [Bug #9381] + +Wed Feb 5 22:28:41 2014 Nobuyoshi Nakada + + * vm_insnhelper.c (vm_search_super_method): allow bound method from a + module, yet another method transplanting. + +Wed Feb 5 22:28:41 2014 Nobuyoshi Nakada + + * vm_insnhelper.c (vm_search_super_method): when super called in a + bound UnboundMethod generated from a module, no superclass is + found since the current defined class is the module, then call + method_missing in that case. [ruby-core:59619] [Bug #9377] + +Wed Feb 5 21:57:40 2014 Nobuyoshi Nakada + + * ext/socket/socket.c (rsock_syserr_fail_host_port): add errno + argument version anduse rb_syserr_fail_str() instead of + rb_sys_fail_str() with restoring errno. + + * ext/socket/socket.c (rsock_syserr_fail_path): ditto, and + rb_syserr_fail(). + + * ext/socket/socket.c (rsock_sys_fail_sockaddr): ditto, use + rsock_syserr_fail_raddrinfo(). + + * ext/socket/socket.c (rsock_sys_fail_raddrinfo): ditto. + + * ext/socket/socket.c (setup_domain_and_type): ditto. + +Wed Feb 5 21:57:40 2014 Eric Wong + + * ext/socket/socket.c (rsock_sys_fail_host_port): save and restore errno + before calling rb_sys_fail_str to prevent [BUG] errno == 0. + Patch by Eric Wong. [ruby-core:59498] [Bug #9352] + + * ext/socket/socket.c (rsock_sys_fail_path): ditto + * ext/socket/socket.c (rsock_sys_fail_sockaddr): ditto + * ext/socket/socket.c (rsock_sys_fail_raddrinfo): ditto + * ext/socket/socket.c (rsock_sys_fail_raddrinfo_or_sockaddr): ditto + +Wed Feb 5 21:12:02 2014 Nobuyoshi Nakada + + * lib/timeout.rb (Timeout::ExitException.catch): pass arguments + for new instance. + + * lib/timeout.rb (Timeout::ExitException#exception): fallback to + Timeout::Error if couldn't throw. [ruby-dev:47872] [Bug #9380] + + * lib/timeout.rb (Timeout#timeout): initialize ExitException with + message for the fallback case. + +Wed Feb 5 21:12:02 2014 Nobuyoshi Nakada + + * lib/timeout.rb (Timeout#timeout): should not rescue ordinarily + raised ExitException, which should not be thrown. + + * lib/timeout.rb (Timeout::ExitException.catch): set @thread only if + it ought to be caught. + + * lib/timeout.rb (Timeout#timeout): when a custom exception is given, + no instance is needed to be caught, so defer creating new instance + until it is raised. [ruby-core:59511] [Bug #9354] + +Wed Feb 5 17:55:28 2014 Aman Gupta + + * array.c (ary_add_hash): Fix consistency issue between Array#uniq and + Array#uniq! [Bug #9340] [ruby-core:59457] + * test/ruby/test_array.rb (class TestArray): regression test for above. + +Wed Feb 5 11:48:42 2014 Charlie Somerville + + * struct.c (rb_struct_set): return assigned value from setter method + rather than struct object. [Bug #9353] [ruby-core:59509] + + * test/ruby/test_struct.rb (test_setter_method_returns_value): add test + +Wed Feb 5 11:13:21 2014 Nobuyoshi Nakada + + * string.c (rb_str_modify_expand): enable capacity and disable + assocation with packed objects when setting capa, so that + pack("p") string fails to unpack properly after modified. + +Sun Feb 2 22:39:28 2014 Nobuyoshi Nakada + + * lib/delegate.rb (Delegator): keep source information methods + which start and end with '__'. [ruby-core:59718] [Bug #9403] + +Fri Jan 31 12:10:16 2014 Nobuyoshi Nakada + + * proc.c (mnew_from_me): keep iclass as-is, to make inheritance + chain consistent. [ruby-core:59358] [Bug #9315] + + * proc.c (method_owner): return the original defined_class from + prepended iclass, instead. + +Fri Jan 31 12:05:59 2014 Nobuyoshi Nakada + + * configure.in: let mingw do something black-magic, and check if + _gmtime64_s() is available actually. + + * win32/win32.c (gmtime_s, localtime_s): use _gmtime64_s() and + _localtime64_s() if available, not depending on very confusing + mingw variants macros. based on the patch by phasis68 (Heesob + Park) at [ruby-core:58764]. [ruby-core:58391] [Bug #9119] + +Thu Jan 30 15:02:35 2014 Shugo Maeda + + * configure.in: use $@ instead of $(.TARGET) because .TARGET is not + supported by GNU make. + +Mon Jan 27 16:49:52 2014 Kenta Murata * ext/bigdecimal/bigdecimal.c (BigDecimal_divide): Add an additional digit for the quotient to be compatible with bigdecimal 1.2.1 and @@ -21,6 +559,38 @@ Tue Jan 14 02:20:00 2014 Kenta Murata * ext/bigdecimal/bigdecimal.gemspec: bigdecimal version 1.2.4. +Mon Jan 27 16:45:34 2014 Yamashita Yuu + + * ext/openssl/ossl_ssl.c (Init_ossl_ssl): Declare a constant + `OP_MSIE_SSLV2_RSA_PADDING` only if the macro is defined. The + `SSL_OP_MSIE_SSLV2_RSA_PADDING` has been removed from latest + snapshot of OpenSSL 1.0.1. [Fixes GH-488] + +Thu Jan 23 10:37:24 2014 Nobuyoshi Nakada + + * hash.c (HAS_EXTRA_STATES): warn extra states only when something + differ. [ruby-core:59254] [Bug #9275] + +Thu Jan 9 14:05:24 2014 NAKAMURA Usaku + + * win32/{setup.mak,Makefile.sub}: update fake.rb like + template/fake.rb.in. + +Thu Jan 9 14:05:24 2014 NAKAMURA Usaku + + * win32/Makefile.sub (fake.rb): should depend on version.h because + if RUBY_VERSION is updated, fake.rb need to say the new version + to avoid install error in rbconfig.rb. + +Thu Jan 9 08:21:00 2014 Aman Gupta + + * test/net/imap/cacert.pem: generate new CA cert, since the last one + expired. [Bug #9341] [ruby-core:59459] + * test/net/imap/server.crt: new server cert signed with updated CA. + * test/net/imap/Makefile: add `make regen_certs` to automate this + process. + +>>>>>>> v2_1_1 Thu Dec 26 03:28:11 2013 Koichi Sasada * vm_insnhelper.c (argument_error): insert dummy frame to make diff --git a/NEWS b/NEWS index 59251a40cfe8f2..afd15faf3b128c 100644 --- a/NEWS +++ b/NEWS @@ -114,6 +114,7 @@ with all sufficient information, see the ChangeLog file. * Process.clock_getres * String + * "literal".freeze is now optimized to return the same object * New methods: * String#scrub and String#scrub! verify and fix invalid byte sequence. If you want to use this function with older Ruby, @@ -133,6 +134,10 @@ with all sufficient information, see the ChangeLog file. === Core classes compatibility issues (excluding feature bug fixes) +* Dir + * incompatible changes: + * Dir#glob returns composed characters (previously Apple Modofied UTF-8). + * Hash * incompatible changes: * Hash#reject will return plain Hash object in the future versions, that @@ -250,7 +255,7 @@ String * REXML::Parsers::SAX2Parser * Fixes wrong number of arguments of entitydecl event. Document of the event says "an array of the entity declaration" but implementation passes two - or more arguments. It is an implementation bug but it breaks backword + or more arguments. It is an implementation bug but it breaks backward compatibility. * REXML::Parsers::StreamParser @@ -271,6 +276,8 @@ String * Improved, iterative resolver (compared to RubyGems 2.1 and earlier) * Support for a sharing a GEM_HOME across ruby platforms and versions + * Updated to 2.2.2. Fixes some minor bugs and performance regressions. + For a complete list of enhancements and bug fixes see: https://github.com/rubygems/rubygems/tree/master/History.txt diff --git a/benchmark/driver.rb b/benchmark/driver.rb index 695dc41afff0c9..cbc72cf604f26c 100644 --- a/benchmark/driver.rb +++ b/benchmark/driver.rb @@ -242,7 +242,7 @@ def measure executable, file cmd = "#{executable} #{@ruby_arg} #{file}" m = Benchmark.measure{ - `#{cmd}` + system(cmd, out: File::NULL) } if $? != 0 diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index 4282bc62738dab..0a7cb0a577510d 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -957,8 +957,8 @@ class C < B assert_normal_exit %q{ begin - Process.setrlimit(Process::RLIMIT_STACK, 4_202_496) - # FreeBSD fails this less than 4M + 8K bytes. + Process.setrlimit(Process::RLIMIT_STACK, 4_206_592) + # FreeBSD SEGVs this less than 4M + 12K bytes. rescue Exception exit end diff --git a/class.c b/class.c index 7bf26940c4c343..0c18b43eb3eea0 100644 --- a/class.c +++ b/class.c @@ -322,7 +322,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig) if (RB_TYPE_P(clone, T_CLASS)) { class_init_copy_check(clone, orig); } - rb_obj_init_copy(clone, orig); + if (!OBJ_INIT_COPY(clone, orig)) return clone; if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig)); rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); diff --git a/compile.c b/compile.c index 10c5ff6229b687..936728984291e7 100644 --- a/compile.c +++ b/compile.c @@ -1203,7 +1203,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args) node = node->nd_next; i += 1; } - iseq->arg_keyword_check = (args->kw_rest_arg->nd_vid & ID_SCOPE_MASK) == ID_JUNK; + iseq->arg_keyword_check = args->kw_rest_arg->nd_cflag != 0; iseq->arg_keywords = i; iseq->arg_keyword_required = r; iseq->arg_keyword_table = ALLOC_N(ID, i); diff --git a/configure.in b/configure.in index 702d17d08a5616..96b8f1994416da 100644 --- a/configure.in +++ b/configure.in @@ -856,6 +856,22 @@ if test "$GCC" = yes; then for oflag in -fno-fast-math; do RUBY_TRY_CFLAGS($oflag, [RUBY_APPEND_OPTION(optflags, $oflag)]) done + AS_CASE(["$target"], + [*-darwin*], [ + # doesn't seem necessary on Mac OS X + ], + [[i[4-6]86*]], [ + RUBY_TRY_CFLAGS(-msse2 -mfpmath=sse, [ + RUBY_APPEND_OPTION(XCFLAGS, -msse2 -mfpmath=sse) + ]) + AS_CASE(["$XCFLAGS"], + [[*-msse2*]], [ + RUBY_TRY_CFLAGS(-mstackrealign, [ + RUBY_APPEND_OPTION(XCFLAGS, -mstackrealign) + ]) + ]) + ] + ) fi AC_ARG_WITH(opt-dir, @@ -864,17 +880,11 @@ AC_ARG_WITH(opt-dir, [ val=`echo "$PATH_SEPARATOR$withval" | sed "s|$PATH_SEPARATOR\([[^$PATH_SEPARATOR]*]\)| -I\1/include|g;s/^ //"` CPPFLAGS="$CPPFLAGS $val" - val=`IFS="$PATH_SEPARATOR" - for dir in $withval; do - echo x ${LIBPATHFLAG} ${RPATHFLAG} | - sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${dir}/lib${IFS}g;s${IFS}%s${IFS}${dir}/lib${IFS}g" - done | tr '\012' ' '` + val=`echo "$PATH_SEPARATOR$withval" | sed "s|$PATH_SEPARATOR\([[^$PATH_SEPARATOR]*]\)| -L\1/lib|g;s/^ //"` + LDFLAGS="$LDFLAGS $val" LDFLAGS_OPTDIR="$val" - test x"${LDFLAGS}" = x || LDFLAGS="$LDFLAGS " - LDFLAGS="$LDFLAGS$val" - test x"${DLDFLAGS}" = x || DLDFLAGS="$DLDFLAGS " - DLDFLAGS="$DLDFLAGS$val" - ]) + OPT_DIR="$withval" + ], [OPT_DIR=]) test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $ARCH_FLAG\"" test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\"" @@ -888,6 +898,7 @@ AC_ARG_WITH(winnt-ver, AS_CASE(["$target_os"], [mingw*], [ RUBY_APPEND_OPTION(CPPFLAGS, -D_WIN32_WINNT=$with_winnt_ver) + RUBY_APPEND_OPTION(CPPFLAGS, -D__MINGW_USE_VC2005_COMPAT) ]) AS_CASE(["$target_os"], @@ -1040,6 +1051,7 @@ main() if test x"$ac_cv_type_NET_LUID" = xyes; then AC_DEFINE(HAVE_TYPE_NET_LUID, 1) fi + AC_CHECK_FUNCS(_gmtime64_s) AC_LIBOBJ([langinfo]) ], [os2-emx*], [ LIBS="-lm $LIBS" @@ -2437,7 +2449,7 @@ if test x"$enable_pthread" = xyes; then pthread_get_stackaddr_np pthread_get_stacksize_np \ thr_stksegment pthread_stackseg_np pthread_getthrds_np \ pthread_cond_init pthread_condattr_setclock pthread_condattr_init \ - pthread_sigmask) + pthread_sigmask pthread_setname_np) if test "${host_os}" = "nacl"; then ac_cv_func_pthread_attr_init=no else @@ -2657,7 +2669,7 @@ if test "$with_dln_a_out" != yes; then : ${LDSHARED='$(CC) -shared'} if test "$rb_cv_binary_elf" = yes; then LDFLAGS="$LDFLAGS -rdynamic" - DLDFLAGS="$DLDFLAGS "'-Wl,-soname,$(.TARGET)' + DLDFLAGS="$DLDFLAGS "'-Wl,-soname,$@' else test "$GCC" = yes && test "$rb_cv_prog_gnu_ld" = yes || LDSHARED='$(LD) -Bshareable' fi @@ -2760,6 +2772,21 @@ AC_SUBST(RPATHFLAG) AC_SUBST(LIBPATHENV, "${LIBPATHENV-LD_LIBRARY_PATH}") AC_SUBST(TRY_LINK) +if test "x$OPT_DIR" != x; then + pat=`echo "${LDFLAGS_OPTDIR}" | sed ['s/[][\\.*|]/\\\\&/']` + LDFLAGS=`echo "${LDFLAGS}" | sed "s| ${pat}||"` + val=`IFS="$PATH_SEPARATOR" + for dir in $OPT_DIR; do + echo x ${LIBPATHFLAG} ${RPATHFLAG} | + sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${dir}/lib${IFS}g;s${IFS}%s${IFS}${dir}/lib${IFS}g" + done | tr '\012' ' '` + test x"${LDFLAGS}" = x || LDFLAGS="$LDFLAGS " + LDFLAGS="$LDFLAGS$val" + test x"${DLDFLAGS}" = x || DLDFLAGS="$DLDFLAGS " + DLDFLAGS="$DLDFLAGS$val" + LDFLAGS_OPTDIR="$val" +fi + AS_CASE(["$target_cpu-$target_os"], [*-darwin*], [ AC_CHECK_HEADERS([execinfo.h]) diff --git a/encoding.c b/encoding.c index 17748b09dcc84e..9bdf7df6ea009a 100644 --- a/encoding.c +++ b/encoding.c @@ -158,7 +158,7 @@ must_encindex(int index) rb_raise(rb_eEncodingError, "encoding index out of bound: %d", index); } - if (ENC_TO_ENCINDEX(enc) != index) { + if (ENC_TO_ENCINDEX(enc) != (int)(index & ENC_INDEX_MASK)) { rb_raise(rb_eEncodingError, "wrong encoding index %d for %s (expected %d)", index, rb_enc_name(enc), ENC_TO_ENCINDEX(enc)); } @@ -594,12 +594,18 @@ rb_enc_from_index(int index) if (!enc_table.list) { rb_enc_init(); } - if (index < 0 || enc_table.count <= index) { + if (index < 0 || enc_table.count <= (index &= ENC_INDEX_MASK)) { return 0; } return enc_table.list[index].enc; } +rb_encoding * +rb_enc_get_from_index(int index) +{ + return must_encindex(index); +} + int rb_enc_registered(const char *name) { @@ -937,7 +943,7 @@ rb_obj_encoding(VALUE obj) if (idx < 0) { rb_raise(rb_eTypeError, "unknown encoding"); } - return rb_enc_from_encoding_index(idx); + return rb_enc_from_encoding_index(idx & ENC_INDEX_MASK); } int diff --git a/eval.c b/eval.c index 3a0206f24ab8c2..841b3671e3b794 100644 --- a/eval.c +++ b/eval.c @@ -380,8 +380,8 @@ rb_mod_s_constants(int argc, VALUE *argv, VALUE mod) VALUE cbase = 0; void *data = 0; - if (argc > 0) { - return rb_mod_constants(argc, argv, rb_cModule); + if (argc > 0 || mod != rb_cModule) { + return rb_mod_constants(argc, argv, mod); } while (cref) { diff --git a/ext/-test-/tracepoint/tracepoint.c b/ext/-test-/tracepoint/tracepoint.c index 245dbd6191673b..aa8c212f99b71d 100644 --- a/ext/-test-/tracepoint/tracepoint.c +++ b/ext/-test-/tracepoint/tracepoint.c @@ -64,8 +64,7 @@ tracepoint_track_objspace_events(VALUE self) VALUE result = rb_ary_new(); rb_tracepoint_enable(tpval); - rb_yield(Qundef); - rb_tracepoint_disable(tpval); + rb_ensure(rb_yield, Qundef, rb_tracepoint_disable, tpval); rb_ary_push(result, SIZET2NUM(track.newobj_count)); rb_ary_push(result, SIZET2NUM(track.free_count)); diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 8537817e86b636..4120a2346dc948 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2481,7 +2481,9 @@ BigDecimal_initialize_copy(VALUE self, VALUE other) Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); Real *x = rb_check_typeddata(other, &BigDecimal_data_type); - DATA_PTR(self) = VpCopy(pv, x); + if (self != other) { + DATA_PTR(self) = VpCopy(pv, x); + } return self; } @@ -2519,8 +2521,8 @@ BigDecimal_new(int argc, VALUE *argv) case T_RATIONAL: if (NIL_P(nFig)) { rb_raise(rb_eArgError, - "can't omit precision for a %s.", - rb_class2name(CLASS_OF(iniValue))); + "can't omit precision for a %"PRIsVALUE".", + rb_obj_class(iniValue)); } return GetVpValueWithPrec(iniValue, mf, 1); diff --git a/ext/dl/cptr.c b/ext/dl/cptr.c index 9e59139fc9d0a0..3f8858c4b37c2e 100644 --- a/ext/dl/cptr.c +++ b/ext/dl/cptr.c @@ -391,9 +391,8 @@ rb_dlptr_inspect(VALUE self) char str[1024]; TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data); - snprintf(str, 1023, "#<%s:%p ptr=%p size=%ld free=%p>", - rb_class2name(CLASS_OF(self)), data, data->ptr, data->size, data->free); - return rb_str_new2(str); + return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>", + rb_obj_class(self), data, data->ptr, data->size, data->free); } /* diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 121a08ea19f7da..e0f7e4b12d3475 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -27,7 +27,7 @@ dealloc(void * ptr) #if USE_FFI_CLOSURE_ALLOC ffi_closure_free(cls->pcl); #else - munmap(cls->pcl, sizeof(cls->pcl)); + munmap(cls->pcl, sizeof(*cls->pcl)); #endif if (cls->argv) xfree(cls->argv); xfree(cls); @@ -234,7 +234,7 @@ initialize(int rbargc, VALUE argv[], VALUE self) #else result = ffi_prep_closure(pcl, cif, callback, (void *)self); cl->code = (void *)pcl; - i = mprotect(pcl, sizeof(pcl), PROT_READ | PROT_EXEC); + i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC); if (i) { rb_sys_fail("mprotect"); } diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c index 4f4842fc334d53..0129363a8df2de 100644 --- a/ext/fiddle/pointer.c +++ b/ext/fiddle/pointer.c @@ -427,12 +427,10 @@ static VALUE rb_fiddle_ptr_inspect(VALUE self) { struct ptr_data *data; - char str[1024]; TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - snprintf(str, 1023, "#<%s:%p ptr=%p size=%ld free=%p>", - rb_class2name(CLASS_OF(self)), data, data->ptr, data->size, data->free); - return rb_str_new2(str); + return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>", + rb_obj_class(self), data, data->ptr, data->size, data->free); } /* diff --git a/ext/io/console/console.c b/ext/io/console/console.c index f3379ffd8d1542..de5ca825583bd0 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -710,7 +710,7 @@ console_dev(VALUE klass) int fd; #ifdef CONSOLE_DEVICE_FOR_WRITING - fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY, 0); + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); if (fd < 0) return Qnil; rb_update_max_fd(fd); args[1] = INT2FIX(O_WRONLY); diff --git a/ext/json/generator/depend b/ext/json/generator/depend index 1a042a2501eb2d..593a8fbb543db0 100644 --- a/ext/json/generator/depend +++ b/ext/json/generator/depend @@ -1 +1,2 @@ +$(OBJS): $(ruby_headers) generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index ed7bb8288758f2..550e9beef0bd28 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -965,6 +965,7 @@ static VALUE cState_init_copy(VALUE obj, VALUE orig) { JSON_Generator_State *objState, *origState; + if (obj == orig) return obj; Data_Get_Struct(obj, JSON_Generator_State, objState); Data_Get_Struct(orig, JSON_Generator_State, origState); if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); diff --git a/ext/json/parser/depend b/ext/json/parser/depend index 498ffa964cdc82..d188844670f0d4 100644 --- a/ext/json/parser/depend +++ b/ext/json/parser/depend @@ -1 +1,2 @@ +$(OBJS): $(ruby_headers) parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 43ccf4c3fdf7fe..3961d3ea33424c 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -293,10 +293,9 @@ ossl_to_der_if_possible(VALUE obj) static VALUE ossl_make_error(VALUE exc, const char *fmt, va_list args) { - char buf[BUFSIZ]; + VALUE str = Qnil; const char *msg; long e; - int len = 0; #ifdef HAVE_ERR_PEEK_LAST_ERROR e = ERR_peek_last_error(); @@ -304,14 +303,19 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args) e = ERR_peek_error(); #endif if (fmt) { - len = vsnprintf(buf, BUFSIZ, fmt, args); + str = rb_vsprintf(fmt, args); } - if (len < BUFSIZ && e) { + if (e) { if (dOSSL == Qtrue) /* FULL INFO */ msg = ERR_error_string(e, NULL); else msg = ERR_reason_error_string(e); - len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg); + if (NIL_P(str)) { + str = rb_str_new_cstr(msg); + } + else { + rb_str_cat2(rb_str_cat2(str, ": "), msg); + } } if (dOSSL == Qtrue){ /* show all errors on the stack */ while ((e = ERR_get_error()) != 0){ @@ -320,8 +324,8 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args) } ERR_clear_error(); - if(len > BUFSIZ) len = rb_long2int(strlen(buf)); - return rb_exc_new(exc, buf, len); + if (NIL_P(str)) str = rb_str_new(0, 0); + return rb_exc_new3(exc, str); } void diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 96d0ade11e0d24..83a927dabe585e 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -95,15 +95,15 @@ extern VALUE eOSSLError; */ #define OSSL_Check_Kind(obj, klass) do {\ if (!rb_obj_is_kind_of((obj), (klass))) {\ - ossl_raise(rb_eTypeError, "wrong argument (%s)! (Expected kind of %s)",\ - rb_obj_classname(obj), rb_class2name(klass));\ + ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ + rb_obj_class(obj), (klass));\ }\ } while (0) #define OSSL_Check_Instance(obj, klass) do {\ if (!rb_obj_is_instance_of((obj), (klass))) {\ - ossl_raise(rb_eTypeError, "wrong argument (%s)! (Expected instance of %s)",\ - rb_obj_classname(obj), rb_class2name(klass));\ + ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected instance of %"PRIsVALUE")",\ + rb_obj_class(obj), (klass));\ }\ } while (0) diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index e3f59bfe1e16f7..c2344affa69145 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -624,8 +624,8 @@ ossl_asn1_default_tag(VALUE obj) } tmp_class = rb_class_superclass(tmp_class); } - ossl_raise(eASN1Error, "universal tag for %s not found", - rb_class2name(CLASS_OF(obj))); + ossl_raise(eASN1Error, "universal tag for %"PRIsVALUE" not found", + rb_obj_class(obj)); return -1; /* dummy */ } diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 03374372ad0d6a..df6fd108878b40 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -213,9 +213,9 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) * We deprecated the arguments for this method, but we decided * keeping this behaviour for backward compatibility. */ - const char *cname = rb_class2name(rb_obj_class(self)); - rb_warn("arguments for %s#encrypt and %s#decrypt were deprecated; " - "use %s#pkcs5_keyivgen to derive key and IV", + VALUE cname = rb_class_path(rb_obj_class(self)); + rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; " + "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV", cname, cname, cname); StringValue(pass); GetCipher(self, ctx); diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index a6ae0063f5b338..011b6f00b4b7b3 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -621,7 +621,7 @@ Init_ossl_dh() * * === Example of a key exchange * dh1 = OpenSSL::PKey::DH.new(2048) - * params = dh1.public_key.to_der #you may send this publicly to the participating party + * der = dh1.public_key.to_der #you may send this publicly to the participating party * dh2 = OpenSSL::PKey::DH.new(der) * dh2.generate_key! #generate the per-session key pair * symm_key1 = dh1.compute_key(dh2.pub_key) @@ -664,4 +664,3 @@ Init_ossl_dh() { } #endif /* NO_DH */ - diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index ec7135064a48c6..206470cbfe90f0 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -2229,7 +2229,9 @@ Init_ossl_ssl() ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG); ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER); +#if defined(SSL_OP_MSIE_SSLV2_RSA_PADDING) ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING); +#endif ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG); ossl_ssl_def_const(OP_TLS_D5_BUG); ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG); diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index 2a87f43efe0b1d..4b422f56449b38 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -14,6 +14,7 @@ require 'psych/json/tree_builder' require 'psych/json/stream' require 'psych/handlers/document_stream' +require 'psych/class_loader' ### # = Overview @@ -216,7 +217,7 @@ module Psych # The version is Psych you're using - VERSION = '2.0.2' + VERSION = '2.0.3' # The version of libyaml Psych is using LIBYAML_VERSION = Psych.libyaml_version.join '.' diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 1cb21376934e6c..f89fcbb8f12c3e 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -284,7 +284,7 @@ def visit_String o quote = false elsif o =~ /\n/ style = Nodes::Scalar::LITERAL - elsif o =~ /^\W/ + elsif o =~ /^\W[^"]*$/ style = Nodes::Scalar::DOUBLE_QUOTED else unless String === @ss.tokenize(o) diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec index ca751a033dcaed..100b6ff73720ad 100644 --- a/ext/psych/psych.gemspec +++ b/ext/psych/psych.gemspec @@ -2,23 +2,22 @@ Gem::Specification.new do |s| s.name = "psych" - s.version = "2.0.2" + s.version = "2.0.3" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] s.authors = ["Aaron Patterson"] - s.date = "2013-11-26" + s.date = "2014-02-04" s.description = "Psych is a YAML parser and emitter. Psych leverages libyaml[http://pyyaml.org/wiki/LibYAML]\nfor its YAML parsing and emitting capabilities. In addition to wrapping\nlibyaml, Psych also knows how to serialize and de-serialize most Ruby objects\nto and from the YAML format." s.email = ["aaron@tenderlovemaking.com"] s.extensions = ["ext/psych/extconf.rb"] - s.extra_rdoc_files = ["CHANGELOG.rdoc", "Manifest.txt", "README.rdoc"] s.files = [".autotest", ".travis.yml", "CHANGELOG.rdoc", "Manifest.txt", "README.rdoc", "Rakefile", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h", "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h", "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h", "ext/psych/yaml/LICENSE", "ext/psych/yaml/api.c", "ext/psych/yaml/config.h", "ext/psych/yaml/dumper.c", "ext/psych/yaml/emitter.c", "ext/psych/yaml/loader.c", "ext/psych/yaml/parser.c", "ext/psych/yaml/reader.c", "ext/psych/yaml/scanner.c", "ext/psych/yaml/writer.c", "ext/psych/yaml/yaml.h", "ext/psych/yaml/yaml_private.h", "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", "lib/psych/core_ext.rb", "lib/psych/deprecated.rb", "lib/psych/exception.rb", "lib/psych/handler.rb", "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb", "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", "lib/psych/json/tree_builder.rb", "lib/psych/json/yaml_events.rb", "lib/psych/nodes.rb", "lib/psych/nodes/alias.rb", "lib/psych/nodes/document.rb", "lib/psych/nodes/mapping.rb", "lib/psych/nodes/node.rb", "lib/psych/nodes/scalar.rb", "lib/psych/nodes/sequence.rb", "lib/psych/nodes/stream.rb", "lib/psych/omap.rb", "lib/psych/parser.rb", "lib/psych/scalar_scanner.rb", "lib/psych/set.rb", "lib/psych/stream.rb", "lib/psych/streaming.rb", "lib/psych/syntax_error.rb", "lib/psych/tree_builder.rb", "lib/psych/visitors.rb", "lib/psych/visitors/depth_first.rb", "lib/psych/visitors/emitter.rb", "lib/psych/visitors/json_tree.rb", "lib/psych/visitors/to_ruby.rb", "lib/psych/visitors/visitor.rb", "lib/psych/visitors/yaml_tree.rb", "lib/psych/y.rb", "test/psych/handlers/test_recorder.rb", "test/psych/helper.rb", "test/psych/json/test_stream.rb", "test/psych/nodes/test_enumerable.rb", "test/psych/test_alias_and_anchor.rb", "test/psych/test_array.rb", "test/psych/test_boolean.rb", "test/psych/test_class.rb", "test/psych/test_coder.rb", "test/psych/test_date_time.rb", "test/psych/test_deprecated.rb", "test/psych/test_document.rb", "test/psych/test_emitter.rb", "test/psych/test_encoding.rb", "test/psych/test_engine_manager.rb", "test/psych/test_exception.rb", "test/psych/test_hash.rb", "test/psych/test_json_tree.rb", "test/psych/test_merge_keys.rb", "test/psych/test_nil.rb", "test/psych/test_null.rb", "test/psych/test_numeric.rb", "test/psych/test_object.rb", "test/psych/test_object_references.rb", "test/psych/test_omap.rb", "test/psych/test_parser.rb", "test/psych/test_psych.rb", "test/psych/test_safe_load.rb", "test/psych/test_scalar.rb", "test/psych/test_scalar_scanner.rb", "test/psych/test_serialize_subclasses.rb", "test/psych/test_set.rb", "test/psych/test_stream.rb", "test/psych/test_string.rb", "test/psych/test_struct.rb", "test/psych/test_symbol.rb", "test/psych/test_tainted.rb", "test/psych/test_to_yaml_properties.rb", "test/psych/test_tree_builder.rb", "test/psych/test_yaml.rb", "test/psych/test_yamldbm.rb", "test/psych/test_yamlstore.rb", "test/psych/visitors/test_depth_first.rb", "test/psych/visitors/test_emitter.rb", "test/psych/visitors/test_to_ruby.rb", "test/psych/visitors/test_yaml_tree.rb", ".gemtest"] s.homepage = "http://github.com/tenderlove/psych" s.licenses = ["MIT"] s.rdoc_options = ["--main", "README.rdoc"] - s.require_paths = ["lib"] s.required_ruby_version = Gem::Requirement.new(">= 1.9.2") s.rubyforge_project = "psych" - s.rubygems_version = "2.0.2" + s.rubygems_version = "2.2.1" s.summary = "Psych is a YAML parser and emitter" s.test_files = ["test/psych/handlers/test_recorder.rb", "test/psych/json/test_stream.rb", "test/psych/nodes/test_enumerable.rb", "test/psych/test_alias_and_anchor.rb", "test/psych/test_array.rb", "test/psych/test_boolean.rb", "test/psych/test_class.rb", "test/psych/test_coder.rb", "test/psych/test_date_time.rb", "test/psych/test_deprecated.rb", "test/psych/test_document.rb", "test/psych/test_emitter.rb", "test/psych/test_encoding.rb", "test/psych/test_engine_manager.rb", "test/psych/test_exception.rb", "test/psych/test_hash.rb", "test/psych/test_json_tree.rb", "test/psych/test_merge_keys.rb", "test/psych/test_nil.rb", "test/psych/test_null.rb", "test/psych/test_numeric.rb", "test/psych/test_object.rb", "test/psych/test_object_references.rb", "test/psych/test_omap.rb", "test/psych/test_parser.rb", "test/psych/test_psych.rb", "test/psych/test_safe_load.rb", "test/psych/test_scalar.rb", "test/psych/test_scalar_scanner.rb", "test/psych/test_serialize_subclasses.rb", "test/psych/test_set.rb", "test/psych/test_stream.rb", "test/psych/test_string.rb", "test/psych/test_struct.rb", "test/psych/test_symbol.rb", "test/psych/test_tainted.rb", "test/psych/test_to_yaml_properties.rb", "test/psych/test_tree_builder.rb", "test/psych/test_yaml.rb", "test/psych/test_yamldbm.rb", "test/psych/test_yamlstore.rb", "test/psych/visitors/test_depth_first.rb", "test/psych/visitors/test_emitter.rb", "test/psych/visitors/test_to_ruby.rb", "test/psych/visitors/test_yaml_tree.rb"] end diff --git a/ext/psych/yaml/api.c b/ext/psych/yaml/api.c index 0c4732e1520d22..e0b9d979cc0596 100644 --- a/ext/psych/yaml/api.c +++ b/ext/psych/yaml/api.c @@ -395,7 +395,7 @@ yaml_emitter_delete(yaml_emitter_t *emitter) } QUEUE_DEL(emitter, emitter->events); STACK_DEL(emitter, emitter->indents); - while (!STACK_EMPTY(empty, emitter->tag_directives)) { + while (!STACK_EMPTY(emitter, emitter->tag_directives)) { yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); yaml_free(tag_directive.handle); yaml_free(tag_directive.prefix); @@ -822,6 +822,7 @@ yaml_scalar_event_initialize(yaml_event_t *event, yaml_char_t *anchor_copy = NULL; yaml_char_t *tag_copy = NULL; yaml_char_t *value_copy = NULL; + size_t value_length; assert(event); /* Non-NULL event object is expected. */ assert(value); /* Non-NULL anchor is expected. */ @@ -839,16 +840,19 @@ yaml_scalar_event_initialize(yaml_event_t *event, } if (length < 0) { - length = strlen((char *)value); + value_length = strlen((char *)value); + } + else { + value_length = (size_t)length; } - if (!yaml_check_utf8(value, length)) goto error; - value_copy = yaml_malloc(length+1); + if (!yaml_check_utf8(value, value_length)) goto error; + value_copy = yaml_malloc(value_length+1); if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; + memcpy(value_copy, value, value_length); + value_copy[value_length] = '\0'; - SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, + SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, value_length, plain_implicit, quoted_implicit, style, mark, mark); return 1; @@ -1202,6 +1206,8 @@ yaml_document_add_scalar(yaml_document_t *document, yaml_char_t *tag_copy = NULL; yaml_char_t *value_copy = NULL; yaml_node_t node; + size_t value_length; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ assert(value); /* Non-NULL value is expected. */ @@ -1215,19 +1221,26 @@ yaml_document_add_scalar(yaml_document_t *document, if (!tag_copy) goto error; if (length < 0) { - length = strlen((char *)value); + value_length = strlen((char *)value); + } + else { + value_length = (size_t)length; } - if (!yaml_check_utf8(value, length)) goto error; - value_copy = yaml_malloc(length+1); + if (!yaml_check_utf8(value, value_length)) goto error; + value_copy = yaml_malloc(value_length+1); if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; + memcpy(value_copy, value, value_length); + value_copy[value_length] = '\0'; - SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); + SCALAR_NODE_INIT(node, tag_copy, value_copy, value_length, style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: yaml_free(tag_copy); @@ -1255,6 +1268,7 @@ yaml_document_add_sequence(yaml_document_t *document, yaml_node_item_t *top; } items = { NULL, NULL, NULL }; yaml_node_t node; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ @@ -1272,7 +1286,11 @@ yaml_document_add_sequence(yaml_document_t *document, style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: STACK_DEL(&context, items); @@ -1300,6 +1318,7 @@ yaml_document_add_mapping(yaml_document_t *document, yaml_node_pair_t *top; } pairs = { NULL, NULL, NULL }; yaml_node_t node; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ @@ -1317,7 +1336,11 @@ yaml_document_add_mapping(yaml_document_t *document, style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: STACK_DEL(&context, pairs); diff --git a/ext/psych/yaml/config.h b/ext/psych/yaml/config.h index 6d6c25b3b104ea..fb62651340416d 100644 --- a/ext/psych/yaml/config.h +++ b/ext/psych/yaml/config.h @@ -1,11 +1,11 @@ #define PACKAGE_NAME "yaml" #define PACKAGE_TARNAME "yaml" -#define PACKAGE_VERSION "0.1.4" -#define PACKAGE_STRING "yaml 0.1.4" +#define PACKAGE_VERSION "0.1.5" +#define PACKAGE_STRING "yaml 0.1.5" #define PACKAGE_BUGREPORT "http://pyyaml.org/newticket?component libyaml" #define PACKAGE_URL "" #define YAML_VERSION_MAJOR 0 #define YAML_VERSION_MINOR 1 -#define YAML_VERSION_PATCH 4 -#define YAML_VERSION_STRING "0.1.4" +#define YAML_VERSION_PATCH 5 +#define YAML_VERSION_STRING "0.1.5" diff --git a/ext/psych/yaml/emitter.c b/ext/psych/yaml/emitter.c index c41a94a79f8837..bf84fafc511a5a 100644 --- a/ext/psych/yaml/emitter.c +++ b/ext/psych/yaml/emitter.c @@ -53,7 +53,7 @@ #define WRITE_BREAK(emitter,string) \ (FLUSH(emitter) \ && (CHECK(string,'\n') ? \ - (PUT_BREAK(emitter), \ + ((void)PUT_BREAK(emitter), \ string.pointer ++, \ 1) : \ (COPY(emitter->buffer,string), \ @@ -1493,7 +1493,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, int break_space = 0; int space_break = 0; - int preceded_by_whitespace = 0; + int preceeded_by_whitespace = 0; int followed_by_whitespace = 0; int previous_space = 0; int previous_break = 0; @@ -1524,7 +1524,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, flow_indicators = 1; } - preceded_by_whitespace = 1; + preceeded_by_whitespace = 1; followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); while (string.pointer != string.end) @@ -1570,7 +1570,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, } } - if (CHECK(string, '#') && preceded_by_whitespace) { + if (CHECK(string, '#') && preceeded_by_whitespace) { flow_indicators = 1; block_indicators = 1; } @@ -1619,7 +1619,7 @@ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, previous_break = 0; } - preceded_by_whitespace = IS_BLANKZ(string); + preceeded_by_whitespace = IS_BLANKZ(string); MOVE(string); if (string.pointer != string.end) { followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); diff --git a/ext/psych/yaml/loader.c b/ext/psych/yaml/loader.c index 9d3d912663c328..cb3ea930891b90 100644 --- a/ext/psych/yaml/loader.c +++ b/ext/psych/yaml/loader.c @@ -283,9 +283,12 @@ static int yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) { yaml_node_t node; + ptrdiff_t node_index; int index; yaml_char_t *tag = first_event->data.scalar.tag; + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + if (!tag || strcmp((char *)tag, "!") == 0) { yaml_free(tag); tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); @@ -298,7 +301,11 @@ yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.scalar.anchor)) return 0; @@ -327,8 +334,11 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) yaml_node_item_t *top; } items = { NULL, NULL, NULL }; int index, item_index; + ptrdiff_t node_index; yaml_char_t *tag = first_event->data.sequence_start.tag; + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + if (!tag || strcmp((char *)tag, "!") == 0) { yaml_free(tag); tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); @@ -343,7 +353,11 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.sequence_start.anchor)) return 0; @@ -351,6 +365,9 @@ yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) if (!yaml_parser_parse(parser, &event)) return 0; while (event.type != YAML_SEQUENCE_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.sequence.items, + INT_MAX-1)) return 0; item_index = yaml_parser_load_node(parser, &event); if (!item_index) return 0; if (!PUSH(parser, @@ -384,9 +401,12 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) yaml_node_pair_t *top; } pairs = { NULL, NULL, NULL }; int index; + ptrdiff_t node_index; yaml_node_pair_t pair; yaml_char_t *tag = first_event->data.mapping_start.tag; + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + if (!tag || strcmp((char *)tag, "!") == 0) { yaml_free(tag); tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); @@ -401,7 +421,11 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.mapping_start.anchor)) return 0; @@ -409,6 +433,9 @@ yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) if (!yaml_parser_parse(parser, &event)) return 0; while (event.type != YAML_MAPPING_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.mapping.pairs, + INT_MAX-1)) return 0; pair.key = yaml_parser_load_node(parser, &event); if (!pair.key) return 0; if (!yaml_parser_parse(parser, &event)) return 0; diff --git a/ext/psych/yaml/parser.c b/ext/psych/yaml/parser.c index dc5430b09fc27c..32671b252c23f1 100644 --- a/ext/psych/yaml/parser.c +++ b/ext/psych/yaml/parser.c @@ -759,9 +759,8 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, else if (token->type == YAML_BLOCK_END_TOKEN) { - yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ parser->state = POP(parser, parser->states); - dummy_mark = POP(parser, parser->marks); + (void)POP(parser, parser->marks); SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -869,9 +868,8 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, else if (token->type == YAML_BLOCK_END_TOKEN) { - yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ parser->state = POP(parser, parser->states); - dummy_mark = POP(parser, parser->marks); + (void)POP(parser, parser->marks); MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -952,7 +950,6 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, yaml_event_t *event, int first) { yaml_token_t *token; - yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ if (first) { token = PEEK_TOKEN(parser); @@ -997,7 +994,7 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, } parser->state = POP(parser, parser->states); - dummy_mark = POP(parser, parser->marks); + (void)POP(parser, parser->marks); SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -1104,7 +1101,6 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, yaml_event_t *event, int first) { yaml_token_t *token; - yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ if (first) { token = PEEK_TOKEN(parser); @@ -1158,7 +1154,7 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, } parser->state = POP(parser, parser->states); - dummy_mark = POP(parser, parser->marks); + (void)POP(parser, parser->marks); MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; diff --git a/ext/psych/yaml/reader.c b/ext/psych/yaml/reader.c index 4e48add7b8813c..f1a06deb9d3a5b 100644 --- a/ext/psych/yaml/reader.c +++ b/ext/psych/yaml/reader.c @@ -460,6 +460,10 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length) } + if (parser->offset >= PTRDIFF_MAX) + return yaml_parser_set_reader_error(parser, "input is too long", + PTRDIFF_MAX, -1); + return 1; } diff --git a/ext/psych/yaml/scanner.c b/ext/psych/yaml/scanner.c index 31fed0ed94dcda..34308d5d4540d7 100644 --- a/ext/psych/yaml/scanner.c +++ b/ext/psych/yaml/scanner.c @@ -615,11 +615,11 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser); */ static int -yaml_parser_roll_indent(yaml_parser_t *parser, int column, - int number, yaml_token_type_t type, yaml_mark_t mark); +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark); static int -yaml_parser_unroll_indent(yaml_parser_t *parser, int column); +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column); /* * Token fetchers. @@ -1103,7 +1103,7 @@ yaml_parser_save_simple_key(yaml_parser_t *parser) */ int required = (!parser->flow_level - && parser->indent == (int)parser->mark.column); + && parser->indent == (ptrdiff_t)parser->mark.column); /* * A simple key is required only when it is the first token in the current @@ -1176,6 +1176,11 @@ yaml_parser_increase_flow_level(yaml_parser_t *parser) /* Increase the flow level. */ + if (parser->flow_level == INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + parser->flow_level++; return 1; @@ -1188,11 +1193,9 @@ yaml_parser_increase_flow_level(yaml_parser_t *parser) static int yaml_parser_decrease_flow_level(yaml_parser_t *parser) { - yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */ - if (parser->flow_level) { parser->flow_level --; - dummy_key = POP(parser, parser->simple_keys); + (void)POP(parser, parser->simple_keys); } return 1; @@ -1206,8 +1209,8 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser) */ static int -yaml_parser_roll_indent(yaml_parser_t *parser, int column, - int number, yaml_token_type_t type, yaml_mark_t mark) +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark) { yaml_token_t token; @@ -1226,7 +1229,14 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column, if (!PUSH(parser, parser->indents, parser->indent)) return 0; - parser->indent = column; +#if PTRDIFF_MAX > INT_MAX + if (column > INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } +#endif + + parser->indent = (int)column; /* Create a token and insert it into the queue. */ @@ -1248,13 +1258,13 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column, /* * Pop indentation levels from the indents stack until the current level - * becomes less or equal to the column. For each indentation level, append + * becomes less or equal to the column. For each intendation level, append * the BLOCK-END token. */ static int -yaml_parser_unroll_indent(yaml_parser_t *parser, int column) +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column) { yaml_token_t token; @@ -1263,7 +1273,7 @@ yaml_parser_unroll_indent(yaml_parser_t *parser, int column) if (parser->flow_level) return 1; - /* Loop through the indentation levels in the stack. */ + /* Loop through the intendation levels in the stack. */ while (parser->indent > column) { @@ -2574,7 +2584,7 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, /* Resize the string to include the head. */ - while (string.end - string.start <= (int)length) { + while ((size_t)(string.end - string.start) <= length) { if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) { parser->error = YAML_MEMORY_ERROR; goto error; @@ -2769,15 +2779,15 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, if (IS_DIGIT(parser->buffer)) { - /* Check that the indentation is greater than 0. */ + /* Check that the intendation is greater than 0. */ if (CHECK(parser->buffer, '0')) { yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0"); + start_mark, "found an intendation indicator equal to 0"); goto error; } - /* Get the indentation level and eat the indicator. */ + /* Get the intendation level and eat the indicator. */ increment = AS_DIGIT(parser->buffer); @@ -2791,7 +2801,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, { if (CHECK(parser->buffer, '0')) { yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0"); + start_mark, "found an intendation indicator equal to 0"); goto error; } @@ -2841,7 +2851,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, end_mark = parser->mark; - /* Set the indentation level if it was specified. */ + /* Set the intendation level if it was specified. */ if (increment) { indent = parser->indent >= 0 ? parser->indent+increment : increment; @@ -2907,7 +2917,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, if (!READ_LINE(parser, leading_break)) goto error; - /* Eat the following indentation spaces and line breaks. */ + /* Eat the following intendation spaces and line breaks. */ if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark)) goto error; @@ -2942,8 +2952,8 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, } /* - * Scan indentation spaces and line breaks for a block scalar. Determine the - * indentation level if needed. + * Scan intendation spaces and line breaks for a block scalar. Determine the + * intendation level if needed. */ static int @@ -2955,11 +2965,11 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, *end_mark = parser->mark; - /* Eat the indentation spaces and line breaks. */ + /* Eat the intendation spaces and line breaks. */ while (1) { - /* Eat the indentation spaces. */ + /* Eat the intendation spaces. */ if (!CACHE(parser, 1)) return 0; @@ -2972,12 +2982,12 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, if ((int)parser->mark.column > max_indent) max_indent = (int)parser->mark.column; - /* Check for a tab character messing the indentation. */ + /* Check for a tab character messing the intendation. */ if ((!*indent || (int)parser->mark.column < *indent) && IS_TAB(parser->buffer)) { return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found a tab character where an indentation space is expected"); + start_mark, "found a tab character where an intendation space is expected"); } /* Have we found a non-empty line? */ @@ -3498,12 +3508,12 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token) { if (IS_BLANK(parser->buffer)) { - /* Check for tab character that abuse indentation. */ + /* Check for tab character that abuse intendation. */ if (leading_blanks && (int)parser->mark.column < indent && IS_TAB(parser->buffer)) { yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found a tab character that violates indentation"); + start_mark, "found a tab character that violate intendation"); goto error; } @@ -3536,7 +3546,7 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token) if (!CACHE(parser, 1)) goto error; } - /* Check indentation level. */ + /* Check intendation level. */ if (!parser->flow_level && (int)parser->mark.column < indent) break; diff --git a/ext/psych/yaml/yaml_private.h b/ext/psych/yaml/yaml_private.h index af10c839735237..cd3d3a56c4b4e6 100644 --- a/ext/psych/yaml/yaml_private.h +++ b/ext/psych/yaml/yaml_private.h @@ -10,6 +10,17 @@ #include #include +#include + +#ifndef _MSC_VER +#include +#else +#ifdef _WIN64 +#define PTRDIFF_MAX _I64_MAX +#else +#define PTRDIFF_MAX INT_MAX +#endif +#endif /* * Memory management. @@ -422,7 +433,14 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end); (stack).start = (stack).top = (stack).end = 0) #define STACK_EMPTY(context,stack) \ - ((stack).start == (stack).top) + ((void)(context), \ + ((stack).start == (stack).top)) + +#define STACK_LIMIT(context,stack,size) \ + ((stack).top - (stack).start < (size) ? \ + 1 : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) #define PUSH(context,stack,value) \ (((stack).top != (stack).end \ diff --git a/ext/pty/pty.c b/ext/pty/pty.c index 4ba1cba6212b91..f54bbb52e58a91 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -613,7 +613,7 @@ static void raise_from_check(rb_pid_t pid, int status) { const char *state; - char buf[1024]; + VALUE msg; VALUE exc; #if defined(WIFSTOPPED) @@ -631,8 +631,8 @@ raise_from_check(rb_pid_t pid, int status) else { state = "exited"; } - snprintf(buf, sizeof(buf), "pty - %s: %ld", state, (long)pid); - exc = rb_exc_new2(eChildExited, buf); + msg = rb_sprintf("pty - %s: %ld", state, (long)pid); + exc = rb_exc_new_str(eChildExited, msg); rb_iv_set(exc, "status", rb_last_status_get()); rb_exc_raise(exc); } diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c index 9bb40e74830f8e..36ad9592229463 100644 --- a/ext/racc/cparse/cparse.c +++ b/ext/racc/cparse/cparse.c @@ -418,10 +418,10 @@ extract_user_token(struct cparse_params *v, VALUE block_args, if (!RB_TYPE_P(block_args, T_ARRAY)) { rb_raise(rb_eTypeError, - "%s() %s %s (must be Array[2])", + "%s() %s %"PRIsVALUE" (must be Array[2])", v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token", v->lex_is_iterator ? "yielded" : "returned", - rb_class2name(CLASS_OF(block_args))); + rb_obj_class(block_args)); } if (RARRAY_LEN(block_args) != 2) { rb_raise(rb_eArgError, diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index 5c99dfe8fa2961..c0a64d1ee592ac 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -12,7 +12,7 @@ class Ripper - # Tokenizes the Ruby program and returns an Array of String. + # Tokenizes the Ruby program and returns an array of strings. # # p Ripper.tokenize("def m(a) nil end") # # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"] @@ -21,7 +21,7 @@ def Ripper.tokenize(src, filename = '-', lineno = 1) Lexer.new(src, filename, lineno).tokenize end - # Tokenizes the Ruby program and returns an Array of an Array, + # Tokenizes the Ruby program and returns an array of an array, # which is formatted like [[lineno, column], type, token]. # # require 'ripper' diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 9a68a0c2893b3e..bbbf985e2834e1 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1280,12 +1280,11 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) ss = rb_sendmsg(fptr->fd, &mh, flags); - if (!nonblock && rb_io_wait_writable(fptr->fd)) { - rb_io_check_closed(fptr); - goto retry; - } - if (ss == -1) { + if (!nonblock && rb_io_wait_writable(fptr->fd)) { + rb_io_check_closed(fptr); + goto retry; + } if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block"); rb_sys_fail("sendmsg(2)"); @@ -1595,12 +1594,11 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) ss = rb_recvmsg(fptr->fd, &mh, flags); - if (!nonblock && rb_io_wait_readable(fptr->fd)) { - rb_io_check_closed(fptr); - goto retry; - } - if (ss == -1) { + if (!nonblock && rb_io_wait_readable(fptr->fd)) { + rb_io_check_closed(fptr); + goto retry; + } if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block"); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) diff --git a/ext/socket/init.c b/ext/socket/init.c index 6d98a66d6e8573..d3b875c78dffce 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -323,8 +323,12 @@ wait_connectable(int fd) */ if (ret < 0) break; - if (sockerr == 0) - continue; /* workaround for winsock */ + if (sockerr == 0) { + if (revents & RB_WAITFD_OUT) + break; + else + continue; /* workaround for winsock */ + } /* BSD and Linux use sockerr. */ errno = sockerr; diff --git a/ext/socket/option.c b/ext/socket/option.c index 3e32230aabcd95..28bdc07db621e4 100644 --- a/ext/socket/option.c +++ b/ext/socket/option.c @@ -357,7 +357,7 @@ static VALUE sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value) { #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) -# ifdef __NetBSD__ +# if defined(__NetBSD__) || defined(__OpenBSD__) unsigned char i = NUM2CHR(rb_to_int(value)); # else int i = NUM2INT(rb_to_int(value)); @@ -387,7 +387,7 @@ sockopt_ipv4_multicast_loop(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) { -# ifdef __NetBSD__ +# if defined(__NetBSD__) || defined(__OpenBSD__) return sockopt_byte(self); # else return sockopt_int(self); @@ -398,7 +398,7 @@ sockopt_ipv4_multicast_loop(VALUE self) UNREACHABLE; } -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) # define inspect_ipv4_multicast_loop(a,b,c,d) inspect_byte(a,b,c,d) #else # define inspect_ipv4_multicast_loop(a,b,c,d) inspect_int(a,b,c,d) @@ -420,7 +420,7 @@ static VALUE sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value) { #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) -# ifdef __NetBSD__ +# if defined(__NetBSD__) || defined(__OpenBSD__) unsigned char i = NUM2CHR(rb_to_int(value)); # else int i = NUM2INT(rb_to_int(value)); @@ -450,7 +450,7 @@ sockopt_ipv4_multicast_ttl(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) { -# ifdef __NetBSD__ +# if defined(__NetBSD__) || defined(__OpenBSD__) return sockopt_byte(self); # else return sockopt_int(self); @@ -461,7 +461,7 @@ sockopt_ipv4_multicast_ttl(VALUE self) UNREACHABLE; } -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) # define inspect_ipv4_multicast_ttl(a,b,c,d) inspect_byte(a,b,c,d) #else # define inspect_ipv4_multicast_ttl(a,b,c,d) inspect_int(a,b,c,d) @@ -481,7 +481,7 @@ inspect_int(int level, int optname, VALUE data, VALUE ret) } } -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) static int inspect_byte(int level, int optname, VALUE data, VALUE ret) { diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index f020ba780dd8e4..ec983e1f5046e8 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1155,76 +1155,69 @@ static VALUE strscan_inspect(VALUE self) { struct strscanner *p; - char buf[BUFSIZE]; - long len; VALUE a, b; p = check_strscan(self); if (NIL_P(p->str)) { - len = snprintf(buf, BUFSIZE, "#<%s (uninitialized)>", - rb_class2name(CLASS_OF(self))); - return infect(rb_str_new(buf, len), p); + a = rb_sprintf("#<%"PRIsVALUE" (uninitialized)>", rb_obj_class(self)); + return infect(a, p); } if (EOS_P(p)) { - len = snprintf(buf, BUFSIZE, "#<%s fin>", - rb_class2name(CLASS_OF(self))); - return infect(rb_str_new(buf, len), p); + a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self)); + return infect(a, p); } if (p->curr == 0) { - b = inspect2(p); - len = snprintf(buf, BUFSIZE, "#<%s %ld/%ld @ %s>", - rb_class2name(CLASS_OF(self)), - p->curr, S_LEN(p), - RSTRING_PTR(b)); - return infect(rb_str_new(buf, len), p); + b = inspect2(p); + a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld @ %"PRIsVALUE">", + rb_obj_class(self), + p->curr, S_LEN(p), + b); + return infect(a, p); } a = inspect1(p); b = inspect2(p); - len = snprintf(buf, BUFSIZE, "#<%s %ld/%ld %s @ %s>", - rb_class2name(CLASS_OF(self)), - p->curr, S_LEN(p), - RSTRING_PTR(a), - RSTRING_PTR(b)); - return infect(rb_str_new(buf, len), p); + a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld %"PRIsVALUE" @ %"PRIsVALUE">", + rb_obj_class(self), + p->curr, S_LEN(p), + a, b); + return infect(a, p); } static VALUE inspect1(struct strscanner *p) { - char buf[BUFSIZE]; - char *bp = buf; + VALUE str; long len; if (p->curr == 0) return rb_str_new2(""); if (p->curr > INSPECT_LENGTH) { - strcpy(bp, "..."); bp += 3; - len = INSPECT_LENGTH; + str = rb_str_new_cstr("..."); + len = INSPECT_LENGTH; } else { - len = p->curr; + str = rb_str_new(0, 0); + len = p->curr; } - memcpy(bp, CURPTR(p) - len, len); bp += len; - return rb_str_dump(rb_str_new(buf, bp - buf)); + rb_str_cat(str, CURPTR(p) - len, len); + return rb_str_dump(str); } static VALUE inspect2(struct strscanner *p) { - char buf[BUFSIZE]; - char *bp = buf; + VALUE str; long len; if (EOS_P(p)) return rb_str_new2(""); len = S_LEN(p) - p->curr; if (len > INSPECT_LENGTH) { - len = INSPECT_LENGTH; - memcpy(bp, CURPTR(p), len); bp += len; - strcpy(bp, "..."); bp += 3; + str = rb_str_new(CURPTR(p), INSPECT_LENGTH); + rb_str_cat2(str, "..."); } else { - memcpy(bp, CURPTR(p), len); bp += len; + str = rb_str_new(CURPTR(p), len); } - return rb_str_dump(rb_str_new(buf, bp - buf)); + return rb_str_dump(str); } /* ======================================================================= diff --git a/ext/syslog/syslog.c b/ext/syslog/syslog.c index 17c5ef89697e0e..482a0a2eeeb541 100644 --- a/ext/syslog/syslog.c +++ b/ext/syslog/syslog.c @@ -312,7 +312,7 @@ static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self) pri = *argv++; if (!FIXNUM_P(pri)) { - rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(pri))); + rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", rb_obj_class(pri)); } syslog_write(FIX2INT(pri), argc, argv); diff --git a/ext/thread/thread.c b/ext/thread/thread.c index 208d1172dfb3ab..c409b36da2c0ba 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -437,7 +437,7 @@ rb_szqueue_max_set(VALUE self, VALUE vmax) diff = max - GET_SZQUEUE_ULONGMAX(self); } RSTRUCT_SET(self, SZQUEUE_MAX, vmax); - while (diff > 0 && !NIL_P(t = rb_ary_shift(GET_QUEUE_QUE(self)))) { + while (diff-- > 0 && !NIL_P(t = rb_ary_shift(GET_SZQUEUE_WAITERS(self)))) { rb_thread_wakeup_alive(t); } return vmax; @@ -502,6 +502,20 @@ rb_szqueue_pop(int argc, VALUE *argv, VALUE self) return szqueue_do_pop(self, should_block); } +/* + * Document-method: Queue#clear + * + * Removes all objects from the queue. + */ + +static VALUE +rb_szqueue_clear(VALUE self) +{ + rb_ary_clear(GET_QUEUE_QUE(self)); + wakeup_all_threads(GET_SZQUEUE_WAITERS(self)); + return self; +} + /* * Document-method: SizedQueue#num_waiting * @@ -586,6 +600,7 @@ Init_thread(void) rb_define_method(rb_cSizedQueue, "max=", rb_szqueue_max_set, 1); rb_define_method(rb_cSizedQueue, "push", rb_szqueue_push, 1); rb_define_method(rb_cSizedQueue, "pop", rb_szqueue_pop, -1); + rb_define_method(rb_cSizedQueue, "clear", rb_szqueue_clear, 0); rb_define_method(rb_cSizedQueue, "num_waiting", rb_szqueue_num_waiting, 0); /* Alias for #push. */ diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c index d269f9c43ed6f4..237462fc3b3894 100644 --- a/ext/tk/tcltklib.c +++ b/ext/tk/tcltklib.c @@ -848,15 +848,14 @@ create_ip_exc(interp, exc, fmt, va_alist) #endif { va_list args; - char buf[BUFSIZ]; + VALUE msg; VALUE einfo; struct tcltkip *ptr = get_ip(interp); va_init_list(args,fmt); - vsnprintf(buf, BUFSIZ, fmt, args); - buf[BUFSIZ - 1] = '\0'; + msg = rb_vsprintf(fmt, args); va_end(args); - einfo = rb_exc_new2(exc, buf); + einfo = rb_exc_new_str(exc, msg); rb_ivar_set(einfo, ID_at_interp, interp); if (ptr) { Tcl_ResetResult(ptr->ip); diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 9765929f345423..072638a10b5920 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -1209,19 +1209,18 @@ static void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...) { va_list args; - char buf[BUFSIZ]; + VALUE msg; VALUE err_msg; va_init_list(args, fmt); - vsnprintf(buf, BUFSIZ, fmt, args); + msg = rb_vsprintf(fmt, args); va_end(args); err_msg = ole_hresult2msg(hr); if(err_msg != Qnil) { - rb_raise(ecs, "%s\n%s", buf, StringValuePtr(err_msg)); - } - else { - rb_raise(ecs, "%s", buf); + rb_str_cat2(msg, "\n"); + rb_str_append(msg, err_msg); } + rb_exc_raise(rb_exc_new_str(ecs, msg)); } void diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index df2a2501b21031..ffdd9a0b7d51d2 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -337,11 +337,8 @@ raise_zlib_error(int err, const char *msg) rb_sys_fail(msg); /* no return */ default: - { - char buf[BUFSIZ]; - snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg); - exc = rb_exc_new2(cZError, buf); - } + exc = rb_exc_new_str(cZError, + rb_sprintf("unknown zlib error %d: %s", err, msg)); } rb_exc_raise(exc); @@ -1559,6 +1556,7 @@ rb_deflate_init_copy(VALUE self, VALUE orig) Data_Get_Struct(self, struct zstream, z1); z2 = get_zstream(orig); + if (z1 == z2) return self; err = deflateCopy(&z1->stream, &z2->stream); if (err != Z_OK) { raise_zlib_error(err, 0); diff --git a/gc.c b/gc.c index af4d125f0be8a4..4df9dfe5fe0380 100644 --- a/gc.c +++ b/gc.c @@ -2961,7 +2961,9 @@ gc_before_sweep(rb_objspace_t *objspace) } } - if (0) fprintf(stderr, "%d\t%d\t%u\t%u\t%d\n", (int)rb_gc_count(), objspace->rgengc.need_major_gc, + if (0) fprintf(stderr, "%d\t%d\t%u\t%u\t%d\n", + (int)rb_gc_count(), + (int)objspace->rgengc.need_major_gc, (unsigned int)objspace->rgengc.oldmalloc_increase, (unsigned int)objspace->rgengc.oldmalloc_increase_limit, (unsigned int)gc_params.oldmalloc_limit_max); @@ -5695,12 +5697,12 @@ get_envparam_int(const char *name, unsigned int *default_value, int lower_bound) if (ptr != NULL) { val = atoi(ptr); if (val > lower_bound) { - if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%d (%d)\n", name, val, *default_value); + if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%d (default value: %d)\n", name, val, *default_value); *default_value = val; return 1; } else { - if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%d (%d), but ignored because lower than %d\n", name, val, *default_value, lower_bound); + if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%d (default value: %d) is ignored because it must be greater than %d.\n", name, val, *default_value, lower_bound); } } return 0; @@ -5720,7 +5722,7 @@ get_envparam_double(const char *name, double *default_value, double lower_bound) return 1; } else { - if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%f (%f), but ignored because lower than %f\n", name, val, *default_value, lower_bound); + if (RTEST(ruby_verbose)) fprintf(stderr, "%s=%f (default value: %f) is ignored because it must be greater than %f.\n", name, val, *default_value, lower_bound); } } return 0; @@ -5800,7 +5802,10 @@ ruby_gc_set_params(int safe_level) get_envparam_double("RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR", &gc_params.malloc_limit_growth_factor, 1.0); #ifdef RGENGC_ESTIMATE_OLDMALLOC - get_envparam_int("RUBY_GC_OLDMALLOC_LIMIT", &gc_params.oldmalloc_limit_min, 0); + if (get_envparam_int("RUBY_GC_OLDMALLOC_LIMIT", &gc_params.oldmalloc_limit_min, 0)) { + rb_objspace_t *objspace = &rb_objspace; + objspace->rgengc.oldmalloc_increase_limit = gc_params.oldmalloc_limit_min; + } get_envparam_int("RUBY_GC_OLDMALLOC_LIMIT_MAX", &gc_params.oldmalloc_limit_max, 0); get_envparam_double("RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR", &gc_params.oldmalloc_limit_growth_factor, 1.0); #endif diff --git a/hash.c b/hash.c index c5374cb1193a32..50f199fbc75be6 100644 --- a/hash.c +++ b/hash.c @@ -27,12 +27,24 @@ # endif #endif -#define HAS_MISC_ATTRIBUTES(hash, klass) ( \ - (klass = rb_obj_class(hash)) != rb_cHash || \ - (klass = 0, \ - FL_TEST((hash), FL_EXIVAR|FL_TAINT|HASH_PROC_DEFAULT) || \ - !NIL_P(RHASH_IFNONE(hash)))) -#define HASH_REJECT_COPY_MISC_ATTRIBUTES 1 +#define HAS_EXTRA_STATES(hash, klass) ( \ + ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \ + FL_TEST((hash), FL_EXIVAR|FL_TAINT|HASH_PROC_DEFAULT) || \ + !NIL_P(RHASH_IFNONE(hash))) +#define HASH_REJECT_COPY_EXTRA_STATES 1 + +static VALUE +has_extra_methods(VALUE klass) +{ + const VALUE base = rb_cHash; + VALUE c = klass; + while (c != base) { + st_table *mtbl = RCLASS_M_TBL(c); + if (mtbl && mtbl->num_entries) return klass; + c = RCLASS_SUPER(c); + } + return 0; +} static VALUE rb_hash_s_try_convert(VALUE, VALUE); @@ -55,7 +67,7 @@ rb_hash_freeze(VALUE hash) VALUE rb_cHash; static VALUE envtbl; -static ID id_hash, id_yield, id_default; +static ID id_hash, id_yield, id_default, id_flatten_bang; VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone) @@ -111,7 +123,7 @@ rb_hash(VALUE obj) return hval; } -st_index_t rb_objid_hash(st_index_t index); +long rb_objid_hash(st_index_t index); static st_index_t rb_any_hash(VALUE a) @@ -134,7 +146,7 @@ rb_any_hash(VALUE a) return (st_index_t)RSHIFT(hnum, 1); } -st_index_t +long rb_objid_hash(st_index_t index) { st_index_t hnum = rb_hash_start(index); @@ -1142,11 +1154,11 @@ rb_hash_reject(VALUE hash) RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); if (RTEST(ruby_verbose)) { VALUE klass; - if (HAS_MISC_ATTRIBUTES(hash, klass)) { -#if HASH_REJECT_COPY_MISC_ATTRIBUTES - rb_warn("copying unguaranteed attributes: %+"PRIsVALUE, hash); - rb_warn("following atributes will not be copied in the future version:"); - if (klass != rb_cHash) { + if (HAS_EXTRA_STATES(hash, klass)) { +#if HASH_REJECT_COPY_EXTRA_STATES + rb_warn("copying extra states: %+"PRIsVALUE, hash); + rb_warn("following states will not be copied in the future version:"); + if (klass) { rb_warn(" subclass: %+"PRIsVALUE, klass); } if (FL_TEST(hash, FL_EXIVAR)) { @@ -1162,12 +1174,11 @@ rb_hash_reject(VALUE hash) else if (!NIL_P(RHASH_IFNONE(hash))) rb_warn(" default value: %+"PRIsVALUE, RHASH_IFNONE(hash)); #else - rb_warn("unguaranteed attributes are not copied: %+"PRIsVALUE, hash); - rb_warn("following atributes are ignored now:"); + rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash); #endif } } -#if HASH_REJECT_COPY_MISC_ATTRIBUTES +#if HASH_REJECT_COPY_EXTRA_STATES result = rb_hash_dup_empty(hash); #else result = rb_hash_new(); @@ -1417,6 +1428,8 @@ rb_hash_initialize_copy(VALUE hash, VALUE hash2) Check_Type(hash2, T_HASH); + if (hash == hash2) return hash; + ntbl = RHASH(hash)->ntbl; if (RHASH(hash2)->ntbl) { if (ntbl) st_free_table(ntbl); @@ -2388,15 +2401,25 @@ rb_hash_flatten(int argc, VALUE *argv, VALUE hash) { VALUE ary; - ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); - rb_hash_foreach(hash, flatten_i, ary); if (argc) { - int level = NUM2INT(*argv) - 1; - if (level > 0) { - *argv = INT2FIX(level); - rb_funcall2(ary, rb_intern("flatten!"), argc, argv); + int level = NUM2INT(*argv); + if (level == 0) return rb_hash_to_a(hash); + + ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); + rb_hash_foreach(hash, flatten_i, ary); + if (level - 1 > 0) { + *argv = INT2FIX(level - 1); + rb_funcall2(ary, id_flatten_bang, argc, argv); + } + else if (level < 0) { + rb_funcall2(ary, id_flatten_bang, 0, 0); } } + else { + ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); + rb_hash_foreach(hash, flatten_i, ary); + } + return ary; } @@ -3746,6 +3769,7 @@ Init_Hash(void) id_hash = rb_intern("hash"); id_yield = rb_intern("yield"); id_default = rb_intern("default"); + id_flatten_bang = rb_intern("flatten!"); rb_cHash = rb_define_class("Hash", rb_cObject); diff --git a/io.c b/io.c index 5aa720b6a7b651..6e3fd85d2b1238 100644 --- a/io.c +++ b/io.c @@ -4572,6 +4572,7 @@ rb_io_syswrite(VALUE io, VALUE str) } n = rb_write_internal(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str)); + RB_GC_GUARD(str); if (n == -1) rb_sys_fail_path(fptr->pathv); diff --git a/iseq.c b/iseq.c index 679bdb7a2de1da..32d996796429f9 100644 --- a/iseq.c +++ b/iseq.c @@ -483,6 +483,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) VALUE type, body, locals, args, exception; st_data_t iseq_type; + static struct st_table *type_map_cache = 0; struct st_table *type_map = 0; rb_iseq_t *iseq; rb_compile_option_t option; @@ -523,7 +524,9 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) iseq->self = iseqval; iseq->local_iseq = iseq; + type_map = type_map_cache; if (type_map == 0) { + struct st_table *cached_map; type_map = st_init_numtable(); st_insert(type_map, ID2SYM(rb_intern("top")), ISEQ_TYPE_TOP); st_insert(type_map, ID2SYM(rb_intern("method")), ISEQ_TYPE_METHOD); @@ -534,6 +537,11 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) st_insert(type_map, ID2SYM(rb_intern("eval")), ISEQ_TYPE_EVAL); st_insert(type_map, ID2SYM(rb_intern("main")), ISEQ_TYPE_MAIN); st_insert(type_map, ID2SYM(rb_intern("defined_guard")), ISEQ_TYPE_DEFINED_GUARD); + cached_map = ATOMIC_PTR_CAS(type_map_cache, (struct st_table *)0, type_map); + if (cached_map) { + st_free_table(type_map); + type_map = cached_map; + } } if (st_lookup(type_map, type, &iseq_type) == 0) { @@ -2015,7 +2023,7 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc) } rb_ary_push(args, a); } - if (rb_id2str(iseq->local_table[iseq->arg_keyword])) { + if (!iseq->arg_keyword_check) { CONST_ID(keyrest, "keyrest"); rb_ary_push(args, PARAM(iseq->arg_keyword, keyrest)); } diff --git a/lib/delegate.rb b/lib/delegate.rb index c33f7e40df766c..d7902292f03355 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -48,7 +48,7 @@ class Delegator < BasicObject undef_method m end private_instance_methods.each do |m| - if /\Ablock_given\?\z|iterator\?\z|\A__raise__\z/ =~ m + if /\Ablock_given\?\z|iterator\?\z|\A__.*__\z/ =~ m next end undef_method m diff --git a/lib/mkmf.rb b/lib/mkmf.rb index c4e2e5a90041f2..2d44b123d2f293 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -2508,6 +2508,8 @@ def MAIN_DOES_NOTHING(*refs) $configure_args["--topdir"] ||= $curdir $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"])) + RbConfig.expand(CONFIG["RUBY_SO_NAME"]) + # :startdoc: split = Shellwords.method(:shellwords).to_proc diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index f49e38b283fa01..5fd4f8e5c5a5b2 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -76,8 +76,9 @@ class SMTPUnsupportedCommand < ProtocolError # # This library does NOT provide functions to compose internet mails. # You must create them by yourself. If you want better mail support, - # try RubyMail or TMail. You can get both libraries from RAA. - # (http://www.ruby-lang.org/en/raa.html) + # try RubyMail or TMail or search for alternatives in + # {RubyGems.org}[https://rubygems.org/] or {The Ruby + # Toolbox}[https://www.ruby-toolbox.com/]. # # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt). # diff --git a/lib/open-uri.rb b/lib/open-uri.rb index b1a253841d65a9..264c8501cf284e 100644 --- a/lib/open-uri.rb +++ b/lib/open-uri.rb @@ -73,7 +73,7 @@ def open(name, *rest, &block) # :doc: # The environment variables such as http_proxy, https_proxy and ftp_proxy # are in effect by default. Here we disable proxy: # -# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f| +# open("http://www.ruby-lang.org/en/", :proxy => nil) {|f| # # ... # } # @@ -288,7 +288,7 @@ def OpenURI.open_http(buf, target, proxy, options) # :nodoc: end end - http = klass.new(target_host, target_port) + http = proxy ? klass.new(target_host, target_port) : klass.new(target_host, target_port, nil) if target.class == URI::HTTPS require 'net/https' http.use_ssl = true @@ -534,8 +534,9 @@ def charset end end - # returns a list of encodings in Content-Encoding field - # as an Array of String. + # Returns a list of encodings in Content-Encoding field as an array of + # strings. + # # The encodings are downcased for canonicalization. def content_encoding vs = @metas['content-encoding'] diff --git a/lib/racc/rdoc/grammar.en.rdoc b/lib/racc/rdoc/grammar.en.rdoc index b667a7cb5ece7d..a154246ee58592 100644 --- a/lib/racc/rdoc/grammar.en.rdoc +++ b/lib/racc/rdoc/grammar.en.rdoc @@ -4,14 +4,12 @@ == Class Block and User Code Block -There's two block on toplevel. -one is 'class' block, another is 'user code' block. 'user code' block MUST -places after 'class' block. +There are two blocks on toplevel. One is 'class' block, another is 'user code' +block. 'user code' block MUST be placed after 'class' block. -== Comment +== Comments -You can insert comment about all places. Two style comment can be used, -Ruby style (#.....) and C style (/*......*/) . +You can insert comments about all places. Two style comments can be used, Ruby style '#.....' and C style '/\*......*\/'. == Class Block @@ -19,19 +17,19 @@ The class block is formed like this: class CLASS_NAME [precedance table] - [token declearations] - [expected number of S/R conflict] + [token declarations] + [expected number of S/R conflicts] [options] [semantic value convertion] [start rule] rule GRAMMARS -CLASS_NAME is a name of parser class. -This is the name of generating parser class. +CLASS_NAME is a name of parser class. This is the name of generating parser +class. -If CLASS_NAME includes '::', Racc outputs module clause. -For example, writing "class M::C" causes creating the code bellow: +If CLASS_NAME includes '::', Racc outputs module clause. For example, writing +"class M::C" causes creating the code bellow: module M class C @@ -42,8 +40,8 @@ For example, writing "class M::C" causes creating the code bellow: == Grammar Block -The grammar block discripts grammar which is able -to be understood by parser. Syntax is: +The grammar block describes grammar which is able to be understood by parser. +Syntax is: (token): (token) (token) (token).... (action) @@ -59,28 +57,27 @@ to be understood by parser. Syntax is: Note that you cannot use '%' string, here document, '%r' regexp in action. -Actions can be omitted. -When it is omitted, '' (empty string) is used. +Actions can be omitted. When it is omitted, '' (empty string) is used. -A return value of action is a value of left side value ($$). -It is value of result, or returned value by "return" statement. +A return value of action is a value of left side value ($$). It is value of +result, or returned value by `return` statement. Here is an example of whole grammar block. rule - goal: definition ruls source { result = val } + goal: definition rules source { result = val } definition: /* none */ { result = [] } | definition startdesig { result[0] = val[1] } | definition - precrule # this line continue from upper line + precrule # this line continues from upper line { result[1] = val[1] } startdesig: START TOKEN -You can use following special local variables in action. +You can use the following special local variables in action: * result ($$) @@ -92,8 +89,7 @@ An array of value of right-hand side (rhs). * _values (...$-2,$-1,$0) -A stack of values. -DO NOT MODIFY this stack unless you know what you are doing. +A stack of values. DO NOT MODIFY this stack unless you know what you are doing. == Operator Precedence @@ -107,9 +103,9 @@ To designate this block: right '=' preclow -`right' is yacc's %right, `left' is yacc's %left. +`right` is yacc's %right, `left` is yacc's %left. -`=' + (symbol) means yacc's %prec: +`=` + (symbol) means yacc's %prec: prechigh nonassoc UMINUS @@ -136,22 +132,22 @@ Racc has bison's "expect" directive. : : -This directive declears "expected" number of shift/reduce conflict. -If "expected" number is equal to real number of conflicts, -racc does not print confliction warning message. +This directive declares "expected" number of shift/reduce conflicts. If +"expected" number is equal to real number of conflicts, Racc does not print +conflict warning message. == Declaring Tokens -By declaring tokens, you can avoid many meanless bugs. -If decleared token does not exist/existing token does not decleared, -Racc output warnings. Declearation syntax is: +By declaring tokens, you can avoid many meaningless bugs. If declared token +does not exist or existing token does not decleared, Racc output warnings. +Declaration syntax is: token TOKEN_NAME AND_IS_THIS ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST == Options -You can write options for racc command in your racc file. +You can write options for Racc command in your Racc file. options OPTION OPTION ... @@ -159,19 +155,19 @@ Options are: * omit_action_call -omit empty action call or not. +omits empty action call or not. * result_var -use/does not use local variable "result" +uses local variable "result" or not. -You can use 'no_' prefix to invert its meanings. +You can use 'no_' prefix to invert their meanings. == Converting Token Symbol Token symbols are, as default, - * naked token string in racc file (TOK, XFILE, this_is_token, ...) + * naked token string in Racc file (TOK, XFILE, this_is_token, ...) --> symbol (:TOK, :XFILE, :this_is_token, ...) * quoted string (':', '.', '(', ...) --> same string (':', '.', '(', ...) @@ -185,7 +181,7 @@ Here is an example: end We can use almost all ruby value can be used by token symbol, -except 'false' and 'nil'. These are causes unexpected parse error. +except 'false' and 'nil'. These cause unexpected parse error. If you want to use String as token symbol, special care is required. For example: @@ -202,12 +198,10 @@ For example: start real_target -This statement will not be used forever, I think. - == User Code Block -"User Code Block" is a Ruby source code which is copied to output. -There are three user code block, "header" "inner" and "footer". +"User Code Block" is a Ruby source code which is copied to output. There are +three user code blocks, "header" "inner" and "footer". Format of user code is like this: @@ -221,6 +215,5 @@ Format of user code is like this: : : -If four '-' exist on line head, -racc treat it as beginning of user code block. -A name of user code must be one word. +If four '-' exist on line head, Racc treat it as beginning of user code block. +The name of user code block must be one word. diff --git a/lib/resolv.rb b/lib/resolv.rb index 6d34a67e099666..6b2fa9d90333e2 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -187,7 +187,7 @@ def lazy_initialize # :nodoc: unless @initialized @name2addr = {} @addr2name = {} - open(@filename) {|f| + open(@filename, 'rb') {|f| f.each {|line| line.sub!(/#.*/, '') addr, hostname, *aliases = line.split(/\s+/) @@ -522,8 +522,9 @@ def fetch_resource(name, typeclass) msg.rd = 1 msg.add_question(candidate, typeclass) unless sender = senders[[candidate, nameserver, port]] - sender = senders[[candidate, nameserver, port]] = - requester.sender(msg, candidate, nameserver, port) + sender = requester.sender(msg, candidate, nameserver, port) + next if !sender + senders[[candidate, nameserver, port]] = sender end reply, reply_name = requester.request(sender, tout) case reply.rcode @@ -741,7 +742,11 @@ def initialize(*nameserver_port) af = Socket::AF_INET end next if @socks_hash[bind_host] - sock = UDPSocket.new(af) + begin + sock = UDPSocket.new(af) + rescue Errno::EAFNOSUPPORT + next # The kernel doesn't support the address family. + end sock.do_not_reverse_lookup = true sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD DNS.bind_random_port(sock, bind_host) @@ -756,11 +761,12 @@ def recv_reply(readable_socks) end def sender(msg, data, host, port=Port) + sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] + return nil if !sock service = [host, port] id = DNS.allocate_request_id(host, port) request = msg.encode request[0,2] = [id].pack('n') - sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] return @senders[[service, id]] = Sender.new(request, data, sock, host, port) end @@ -781,6 +787,7 @@ def initialize(msg, data, sock, host, port) attr_reader :data def send + raise "@sock is nil." if @sock.nil? @sock.send(@msg, 0, @host, @port) end end @@ -824,6 +831,7 @@ def close class Sender < Requester::Sender # :nodoc: def send + raise "@sock is nil." if @sock.nil? @sock.send(@msg, 0) end attr_reader :data @@ -920,7 +928,7 @@ def Config.parse_resolv_conf(filename) nameserver = [] search = nil ndots = 1 - open(filename) {|f| + open(filename, 'rb') {|f| f.each {|line| line.sub!(/[#;].*/, '') keyword, *args = line.split(/\s+/) @@ -1520,6 +1528,7 @@ def get_length16 end def get_bytes(len = @limit - @index) + raise DecodeError.new("limit exceeded") if @limit < @index + len d = @data[@index, len] @index += len return d @@ -1547,6 +1556,7 @@ def get_unpack(template) end def get_string + raise DecodeError.new("limit exceeded") if @limit <= @index len = @data[@index].ord raise DecodeError.new("limit exceeded") if @limit < @index + 1 + len d = @data[@index + 1, len] @@ -1570,6 +1580,7 @@ def get_labels(limit=nil) limit = @index if !limit || @index < limit d = [] while true + raise DecodeError.new("limit exceeded") if @limit <= @index case @data[@index].ord when 0 @index += 1 @@ -1963,10 +1974,10 @@ def initialize(first_string, *rest_strings) attr_reader :strings ## - # Returns the first string from +strings+. + # Returns the concatenated string from +strings+. def data - @strings[0] + @strings.join("") end def encode_rdata(msg) # :nodoc: diff --git a/lib/rinda/ring.rb b/lib/rinda/ring.rb index 1ecc56a4f5b75b..2c29977d11bdbe 100644 --- a/lib/rinda/ring.rb +++ b/lib/rinda/ring.rb @@ -413,9 +413,8 @@ def make_socket(address) # :nodoc: soc = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) if addrinfo.ipv4_multicast? then - soc.setsockopt(:IPPROTO_IP, :IP_MULTICAST_LOOP, true) - soc.setsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL, - [@multicast_hops].pack('c')) + soc.setsockopt(Socket::Option.ipv4_multicast_loop(1)) + soc.setsockopt(Socket::Option.ipv4_multicast_ttl(@multicast_hops)) elsif addrinfo.ipv6_multicast? then soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_LOOP, true) soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS, diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 73c4846f8274de..456273ed19d763 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.2.0' + VERSION = '2.2.2' end # Must be first since it unloads the prelude from 1.9.2 @@ -572,7 +572,7 @@ def self.host= host # gem's paths are inserted before site lib directory by default. def self.load_path_insert_index - index = $LOAD_PATH.index ConfigMap[:sitelibdir] + index = $LOAD_PATH.index RbConfig::CONFIG['sitelibdir'] index end @@ -743,8 +743,8 @@ def self.pre_uninstall(&hook) def self.prefix prefix = File.dirname RUBYGEMS_DIR - if prefix != File.expand_path(ConfigMap[:sitelibdir]) and - prefix != File.expand_path(ConfigMap[:libdir]) and + if prefix != File.expand_path(RbConfig::CONFIG['sitelibdir']) and + prefix != File.expand_path(RbConfig::CONFIG['libdir']) and 'lib' == File.basename(RUBYGEMS_DIR) then prefix end @@ -765,6 +765,10 @@ def self.read_binary(path) f.flock(File::LOCK_EX) f.read end + rescue Errno::EACCES + open path, 'rb' do |f| + f.read + end end ## @@ -772,8 +776,8 @@ def self.read_binary(path) def self.ruby if @ruby.nil? then - @ruby = File.join(ConfigMap[:bindir], - "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}") + @ruby = File.join(RbConfig::CONFIG['bindir'], + "#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}") @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/ end @@ -785,8 +789,7 @@ def self.ruby # Returns a String containing the API compatibility version of Ruby def self.ruby_api_version - @ruby_api_version ||= - "#{ConfigMap[:MAJOR]}.#{ConfigMap[:MINOR]}.#{ConfigMap[:TEENY]}" + @ruby_api_version ||= RbConfig::CONFIG['ruby_version'].dup end ## diff --git a/lib/rubygems/available_set.rb b/lib/rubygems/available_set.rb index d8655afc34a000..fabdd6e79d71c3 100644 --- a/lib/rubygems/available_set.rb +++ b/lib/rubygems/available_set.rb @@ -4,9 +4,12 @@ class Gem::AvailableSet Tuple = Struct.new(:spec, :source) + attr_accessor :remote # :nodoc: + def initialize @set = [] @sorted = nil + @remote = true end attr_reader :set diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index a52377ff22e067..470a6ebc8b5c43 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -206,6 +206,24 @@ def require_paths [relative_extension_dir].concat @require_paths end + ## + # Returns the paths to the source files for use with analysis and + # documentation tools. These paths are relative to full_gem_path. + + def source_paths + paths = raw_require_paths.dup + + if @extensions then + ext_dirs = @extensions.map do |extension| + extension.split(File::SEPARATOR, 2).first + end.uniq + + paths.concat ext_dirs + end + + paths.uniq + end + ## # Return a Gem::Specification from this gem diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb index 97218848edac15..603f1d072aaa6f 100644 --- a/lib/rubygems/commands/contents_command.rb +++ b/lib/rubygems/commands/contents_command.rb @@ -94,11 +94,11 @@ def files_in_default_gem spec spec.files.sort.map do |file| case file when /\A#{spec.bindir}\// - [Gem::ConfigMap[:bindir], $POSTMATCH] + [RbConfig::CONFIG['bindir'], $POSTMATCH] when /\.so\z/ - [Gem::ConfigMap[:archdir], file] + [RbConfig::CONFIG['archdir'], file] else - [Gem::ConfigMap[:rubylibdir], file] + [RbConfig::CONFIG['rubylibdir'], file] end end end diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb index a7db013caf9deb..ca6f694bc56d7d 100644 --- a/lib/rubygems/commands/generate_index_command.rb +++ b/lib/rubygems/commands/generate_index_command.rb @@ -62,7 +62,7 @@ def description # :nodoc: end def execute - # This is always true becasue it's the only way now. + # This is always true because it's the only way now. options[:build_modern] = true if not File.exist?(options[:directory]) or diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index 4485eb12e81719..8219eef6ead096 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -228,7 +228,18 @@ def install_gem name, version # :nodoc: def install_gem_without_dependencies name, req # :nodoc: gem = nil - if remote? then + if local? then + if name =~ /\.gem$/ and File.file? name then + source = Gem::Source::SpecificFile.new name + spec = source.spec + else + source = Gem::Source::Local.new + spec = source.find_gem name, req + end + gem = source.download spec if spec + end + + if remote? and not gem then dependency = Gem::Dependency.new name, req dependency.prerelease = options[:prerelease] @@ -236,13 +247,6 @@ def install_gem_without_dependencies name, req # :nodoc: gem = fetcher.download_to_cache dependency end - if local? and not gem then - source = Gem::Source::Local.new - spec = source.find_gem name, req - - gem = source.download spec - end - inst = Gem::Installer.new gem, options inst.install diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index face77fae9ce28..681db0dc1d19fc 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -13,7 +13,7 @@ def initialize super 'setup', 'Install RubyGems', :format_executable => true, :document => %w[ri], - :site_or_vendor => :sitelibdir, + :site_or_vendor => 'sitelibdir', :destdir => '', :prefix => '', :previous_version => '' add_option '--previous-version=VERSION', @@ -36,7 +36,7 @@ def initialize add_option '--[no-]vendor', 'Install into vendorlibdir not sitelibdir' do |vendor, options| - options[:site_or_vendor] = vendor ? :vendorlibdir : :sitelibdir + options[:site_or_vendor] = vendor ? 'vendorlibdir' : 'sitelibdir' end add_option '--[no-]format-executable', @@ -343,19 +343,19 @@ def generate_default_dirs(install_destdir) site_or_vendor = options[:site_or_vendor] if prefix.empty? then - lib_dir = Gem::ConfigMap[site_or_vendor] - bin_dir = Gem::ConfigMap[:bindir] + lib_dir = RbConfig::CONFIG[site_or_vendor] + bin_dir = RbConfig::CONFIG['bindir'] else # Apple installed RubyGems into libdir, and RubyGems <= 1.1.0 gets # confused about installation location, so switch back to # sitelibdir/vendorlibdir. if defined?(APPLE_GEM_HOME) and # just in case Apple and RubyGems don't get this patched up proper. - (prefix == Gem::ConfigMap[:libdir] or + (prefix == RbConfig::CONFIG['libdir'] or # this one is important - prefix == File.join(Gem::ConfigMap[:libdir], 'ruby')) then - lib_dir = Gem::ConfigMap[site_or_vendor] - bin_dir = Gem::ConfigMap[:bindir] + prefix == File.join(RbConfig::CONFIG['libdir'], 'ruby')) then + lib_dir = RbConfig::CONFIG[site_or_vendor] + bin_dir = RbConfig::CONFIG['bindir'] else lib_dir = File.join prefix, 'lib' bin_dir = File.join prefix, 'bin' diff --git a/lib/rubygems/compatibility.rb b/lib/rubygems/compatibility.rb index 5e8618fe39c088..d06ade1fa662ba 100644 --- a/lib/rubygems/compatibility.rb +++ b/lib/rubygems/compatibility.rb @@ -33,6 +33,8 @@ class << Gem module Gem RubyGemsVersion = VERSION + # TODO remove at RubyGems 3 + RbConfigPriorities = %w[ MAJOR MINOR @@ -45,7 +47,7 @@ module Gem unless defined?(ConfigMap) ## # Configuration settings from ::RbConfig - ConfigMap = Hash.new do |cm, key| + ConfigMap = Hash.new do |cm, key| # TODO remove at RubyGems 3 cm[key] = RbConfig::CONFIG[key.to_s] end else diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 1acae9b52942e3..cf14017ea2d5be 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -137,9 +137,10 @@ class Gem::ConfigFile attr_reader :ssl_verify_mode ## - # Path name of directory or file of openssl CA certificate, used for remote https connection + # Path name of directory or file of openssl CA certificate, used for remote + # https connection - attr_reader :ssl_ca_cert + attr_accessor :ssl_ca_cert ## # Path name of directory or file of openssl client certificate, used for remote https connection with client authentication diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 715c0b71b36181..6924f48e5ade92 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -29,22 +29,22 @@ def self.default_spec_cache_dir def self.default_dir path = if defined? RUBY_FRAMEWORK_VERSION then [ - File.dirname(ConfigMap[:sitedir]), + File.dirname(RbConfig::CONFIG['sitedir']), 'Gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] - elsif ConfigMap[:rubylibprefix] then + elsif RbConfig::CONFIG['rubylibprefix'] then [ - ConfigMap[:rubylibprefix], + RbConfig::CONFIG['rubylibprefix'], 'gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] else [ - ConfigMap[:libdir], + RbConfig::CONFIG['libdir'], ruby_engine, 'gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] end @@ -74,7 +74,7 @@ def self.default_rubygems_dirs def self.user_dir parts = [Gem.user_home, '.gem', ruby_engine] - parts << ConfigMap[:ruby_version] unless ConfigMap[:ruby_version].empty? + parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? File.join parts end @@ -100,7 +100,7 @@ def self.default_path # Deduce Ruby's --program-prefix and --program-suffix from its install name def self.default_exec_format - exec_format = ConfigMap[:ruby_install_name].sub('ruby', '%s') rescue '%s' + exec_format = RbConfig::CONFIG['ruby_install_name'].sub('ruby', '%s') rescue '%s' unless exec_format =~ /%s/ then raise Gem::Exception, @@ -117,7 +117,7 @@ def self.default_bindir if defined? RUBY_FRAMEWORK_VERSION then # mac framework support '/usr/bin' else # generic install - ConfigMap[:bindir] + RbConfig::CONFIG['bindir'] end end diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index b7babf6d386e41..da6994a9beb4d3 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -419,6 +419,7 @@ def resolve_dependencies dep_or_name, version # :nodoc: request_set = as.to_request_set install_development_deps request_set.soft_missing = @force + request_set.remote = false unless consider_remote? installer_set = Gem::Resolver::InstallerSet.new @domain installer_set.always_install.concat request_set.always_install diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb index 274d6a5c12023f..e19360da13a81f 100644 --- a/lib/rubygems/deprecate.rb +++ b/lib/rubygems/deprecate.rb @@ -50,7 +50,7 @@ def deprecate name, repl, year, month class_eval { old = "_deprecated_#{name}" alias_method old, name - define_method name do |*args, &block| # TODO: really works on 1.8.7? + define_method name do |*args, &block| klass = self.kind_of? Module target = klass ? "#{self}." : "#{self.class}#" msg = [ "NOTE: #{target}#{name} is deprecated", diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index 402aa966c07791..990fd18524caac 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -34,7 +34,11 @@ def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil) ENV["RUBYOPT"] = ["-r#{siteconf_path}", rubyopt].compact.join(' ') cmd = [Gem.ruby, File.basename(extension), *args].join ' ' - run cmd, results + begin + run cmd, results + ensure + FileUtils.mv 'mkmf.log', dest_path if File.exist? 'mkmf.log' + end ENV["DESTDIR"] = nil ENV["RUBYOPT"] = rubyopt diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index f8eb2c2145fa1e..c80981682f14b1 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -480,7 +480,7 @@ def generate_bin_symlink(filename, bindir) # def shebang(bin_file_name) - ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang + ruby_name = RbConfig::CONFIG['ruby_install_name'] if @env_shebang path = File.join gem_dir, spec.bindir, bin_file_name first_line = File.open(path, "rb") {|file| file.gets} @@ -493,7 +493,7 @@ def shebang(bin_file_name) if which = Gem.configuration[:custom_shebang] # replace bin_file_name with "ruby" to avoid endless loops - which = which.gsub(/ #{bin_file_name}$/," #{Gem::ConfigMap[:ruby_install_name]}") + which = which.gsub(/ #{bin_file_name}$/," #{RbConfig::CONFIG['ruby_install_name']}") which = which.gsub(/\$(\w+)/) do case $1 @@ -641,7 +641,7 @@ def app_script_text(bin_file_name) if ARGV.first str = ARGV.first str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding - if str =~ /\\A_(.*)_\\z/ + if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then version = $1 ARGV.shift end diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb index 28da1db0b508fa..f9ab13aca77447 100644 --- a/lib/rubygems/package/tar_header.rb +++ b/lib/rubygems/package/tar_header.rb @@ -134,7 +134,7 @@ def initialize(vals) vals[:gid] ||= 0 vals[:mtime] ||= 0 vals[:checksum] ||= "" - vals[:typeflag] ||= "0" + vals[:typeflag] = "0" if vals[:typeflag].nil? || vals[:typeflag].empty? vals[:magic] ||= "ustar" vals[:version] ||= "00" vals[:uname] ||= "wheel" diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index e050959dc6fde5..1bcd7549ad4f79 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -16,7 +16,7 @@ class Gem::Platform attr_accessor :version def self.local - arch = Gem::ConfigMap[:arch] + arch = RbConfig::CONFIG['arch'] arch = "#{arch}_60" if arch =~ /mswin32$/ @local ||= new(arch) end diff --git a/lib/rubygems/rdoc.rb b/lib/rubygems/rdoc.rb index 52249dc267aa88..633bd893a5df0c 100644 --- a/lib/rubygems/rdoc.rb +++ b/lib/rubygems/rdoc.rb @@ -193,7 +193,7 @@ def generate ::RDoc::Parser::C.reset args = @spec.rdoc_options - args.concat @spec.require_paths + args.concat @spec.source_paths args.concat @spec.extra_rdoc_files case config_args = Gem.configuration[:rdoc] diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index e32c0249896f53..58991caeda93da 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -131,11 +131,19 @@ def download(spec, source_uri, install_dir = Gem.dir) FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir - # Always escape URI's to deal with potential spaces and such - unless URI::Generic === source_uri - source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? - URI::DEFAULT_PARSER.escape(source_uri.to_s) : - URI.escape(source_uri.to_s)) + # Always escape URI's to deal with potential spaces and such + # It should also be considered that source_uri may already be + # a valid URI with escaped characters. e.g. "{DESede}" is encoded + # as "%7BDESede%7D". If this is escaped again the percentage + # symbols will be escaped. + unless source_uri.is_a?(URI::Generic) + begin + source_uri = URI.parse(source_uri) + rescue + source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? + URI::DEFAULT_PARSER.escape(source_uri.to_s) : + URI.escape(source_uri.to_s)) + end end scheme = source_uri.scheme @@ -285,20 +293,20 @@ def fetch_path(uri, mtime = nil, head = false) def cache_update_path uri, path = nil, update = true mtime = path && File.stat(path).mtime rescue nil - if mtime && Net::HTTPNotModified === fetch_path(uri, mtime, true) - Gem.read_binary(path) - else - data = fetch_path(uri) + data = fetch_path(uri, mtime) - if update and path then - open(path, 'wb') do |io| - io.flock(File::LOCK_EX) - io.write data - end - end + if data == nil # indicates the server returned 304 Not Modified + return Gem.read_binary(path) + end - data + if update and path + open(path, 'wb') do |io| + io.flock(File::LOCK_EX) + io.write data + end end + + data end ## diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index e8707630c5b1fb..d2f076f58110ce 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -48,15 +48,14 @@ def configure_connection_for_https(connection) connection.key = OpenSSL::PKey::RSA.new pem end + store.set_default_paths + add_rubygems_trusted_certs(store) if Gem.configuration.ssl_ca_cert if File.directory? Gem.configuration.ssl_ca_cert store.add_path Gem.configuration.ssl_ca_cert else store.add_file Gem.configuration.ssl_ca_cert end - else - store.set_default_paths - add_rubygems_trusted_certs(store) end connection.cert_store = store rescue LoadError => e @@ -106,7 +105,8 @@ def fetch request = @request_class.new @uri.request_uri unless @uri.nil? || @uri.user.nil? || @uri.user.empty? then - request.basic_auth @uri.user, @uri.password + request.basic_auth Gem::UriFormatter.new(@uri.user).unescape, + Gem::UriFormatter.new(@uri.password).unescape end request.add_field 'User-Agent', @user_agent diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb index aa3f27c9c1a191..fb54e344bdfd3d 100644 --- a/lib/rubygems/request_set.rb +++ b/lib/rubygems/request_set.rb @@ -38,6 +38,11 @@ class Gem::RequestSet attr_accessor :ignore_dependencies + ## + # When false no remote sets are used for resolving gems. + + attr_accessor :remote + ## # Sets used for resolution @@ -71,6 +76,7 @@ def initialize *deps @git_set = nil @ignore_dependencies = false @install_dir = Gem.dir + @remote = true @requests = [] @sets = [] @soft_missing = false @@ -150,6 +156,7 @@ def install_from_gemdeps options, &block gemdeps = options[:gemdeps] @install_dir = options[:install_dir] || Gem.dir + @remote = options[:domain] != :local load_gemdeps gemdeps, options[:without_groups] @@ -235,6 +242,7 @@ def resolve set = Gem::Resolver::BestSet.new @sets << @vendor_set set = Gem::Resolver.compose_sets(*@sets) + set.remote = @remote resolver = Gem::Resolver.new @dependencies, set resolver.development = @development diff --git a/lib/rubygems/request_set/lockfile.rb b/lib/rubygems/request_set/lockfile.rb index 522caf15026af0..0433d2a7fc86e5 100644 --- a/lib/rubygems/request_set/lockfile.rb +++ b/lib/rubygems/request_set/lockfile.rb @@ -303,7 +303,12 @@ def parse_GEM # :nodoc: type, data, = get [:text, :requirement] if type == :text and column == 4 then - last_spec = set.add name, data, Gem::Platform::RUBY + version, platform = data.split '-', 2 + + platform = + platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY + + last_spec = set.add name, version, platform else dependency = parse_dependency name, data diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb index d455e03c0576fb..65e92bbf29b409 100644 --- a/lib/rubygems/resolver.rb +++ b/lib/rubygems/resolver.rb @@ -59,6 +59,8 @@ def self.compose_sets *sets sets = sets.map do |set| case set + when Gem::Resolver::BestSet then + set when Gem::Resolver::ComposedSet then set.sets else @@ -178,27 +180,6 @@ def resolve res.to_a end - ## - # Finds the State in +states+ that matches the +conflict+ so that we can try - # other possible sets. - # - # If no good candidate is found, the first state is tried. - - def find_conflict_state conflict, states # :nodoc: - until states.empty? do - state = states.pop - - explain :consider, state.dep, conflict.failed_dep - - if conflict.for_spec? state.spec - state.conflicts << [state.spec, conflict] - return state - end - end - - nil - end - ## # Extracts the specifications that may be able to fulfill +dependency+ and # returns those that match the local platform and all those that match. diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb index 89ee3c9b15c2a6..5475e626e6e70b 100644 --- a/lib/rubygems/resolver/api_set.rb +++ b/lib/rubygems/resolver/api_set.rb @@ -25,10 +25,12 @@ class Gem::Resolver::APISet < Gem::Resolver::Set # http://guides.rubygems.org/rubygems-org-api def initialize dep_uri = 'https://rubygems.org/api/v1/dependencies' + super() + dep_uri = URI dep_uri unless URI === dep_uri # for ruby 1.8 @dep_uri = dep_uri - @uri = dep_uri + '../../..' + @uri = dep_uri + '../..' @data = Hash.new { |h,k| h[k] = [] } @source = Gem::Source.new @uri @@ -41,6 +43,8 @@ def initialize dep_uri = 'https://rubygems.org/api/v1/dependencies' def find_all req res = [] + return res unless @remote + versions(req.name).each do |ver| if req.dependency.match? req.name, ver[:number] res << Gem::Resolver::APISpecification.new(self, ver) @@ -55,6 +59,7 @@ def find_all req # data for DependencyRequests +reqs+. def prefetch reqs + return unless @remote names = reqs.map { |r| r.dependency.name } needed = names - @data.keys diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb index fa6c9f84c0ee90..20bb94827b0f27 100644 --- a/lib/rubygems/resolver/best_set.rb +++ b/lib/rubygems/resolver/best_set.rb @@ -12,11 +12,30 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet def initialize sources = Gem.sources super() - sources.each_source do |source| + @sources = sources + end + + ## + # Picks which sets to use for the configured sources. + + def pick_sets # :nodoc: + @sources.each_source do |source| @sets << source.dependency_resolver_set end end + def find_all req # :nodoc: + pick_sets if @remote and @sets.empty? + + super + end + + def prefetch reqs # :nodoc: + pick_sets if @remote and @sets.empty? + + super + end + def pretty_print q # :nodoc: q.group 2, '[BestSet', ']' do q.breakable diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb index 19227e095b6b0a..6f912b0afe1cdc 100644 --- a/lib/rubygems/resolver/composed_set.rb +++ b/lib/rubygems/resolver/composed_set.rb @@ -16,9 +16,20 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set # Gem::Resolver::compose_sets instead. def initialize *sets + super() + @sets = sets end + ## + # Sets the remote network access for all composed sets. + + def remote= remote + super + + @sets.each { |set| set.remote = remote } + end + ## # Finds all specs matching +req+ in all sets. diff --git a/lib/rubygems/resolver/git_set.rb b/lib/rubygems/resolver/git_set.rb index 1a2b230b809367..d32710e3d61ca8 100644 --- a/lib/rubygems/resolver/git_set.rb +++ b/lib/rubygems/resolver/git_set.rb @@ -33,6 +33,8 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set attr_reader :specs # :nodoc: def initialize # :nodoc: + super() + @git = ENV['git'] || 'git' @need_submodules = {} @repositories = {} @@ -91,6 +93,7 @@ def prefetch reqs @repositories.each do |name, (repository, reference)| source = Gem::Source::Git.new name, repository, reference source.root_dir = @root_dir + source.remote = @remote source.specs.each do |spec| git_spec = Gem::Resolver::GitSpecification.new self, spec, source diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb index a6ef56bb7f3ea8..ef01f0f0ad5cc2 100644 --- a/lib/rubygems/resolver/index_set.rb +++ b/lib/rubygems/resolver/index_set.rb @@ -5,6 +5,8 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set def initialize source = nil # :nodoc: + super() + @f = if source then sources = Gem::SourceList.from [source] @@ -34,6 +36,8 @@ def initialize source = nil # :nodoc: def find_all req res = [] + return res unless @remote + name = req.dependency.name @all[name].each do |uri, n| diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb index e35e0aabecc92a..045c893fdc4f3d 100644 --- a/lib/rubygems/resolver/installer_set.rb +++ b/lib/rubygems/resolver/installer_set.rb @@ -24,15 +24,17 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set # Creates a new InstallerSet that will look for gems in +domain+. def initialize domain + super() + @domain = domain + @remote = consider_remote? @f = Gem::SpecFetcher.fetcher - @all = Hash.new { |h,k| h[k] = [] } @always_install = [] @ignore_dependencies = false @ignore_installed = false - @loaded_remote_specs = [] + @remote_set = Gem::Resolver::BestSet.new @specs = {} end @@ -79,16 +81,7 @@ def find_all req end end - if consider_remote? then - load_remote_specs dep - - @all[name].each do |remote_source, n| - if dep.match? n then - res << Gem::Resolver::IndexSpecification.new( - self, n.name, n.version, remote_source, n.platform) - end - end - end + res.concat @remote_set.find_all req if consider_remote? res end @@ -101,27 +94,6 @@ def inspect # :nodoc: ] end - ## - # Loads remote prerelease specs if +dep+ is a prerelease dependency - - def load_remote_specs dep # :nodoc: - types = [:released] - types << :prerelease if dep.prerelease? - - types.each do |type| - next if @loaded_remote_specs.include? type - @loaded_remote_specs << type - - list, = @f.available_specs type - - list.each do |uri, specs| - specs.each do |n| - @all[n.name] << [uri, n] - end - end - end - end - ## # Called from IndexSpecification to get a true Specification # object. @@ -151,5 +123,16 @@ def pretty_print q # :nodoc: end end + def remote= remote # :nodoc: + case @domain + when :local then + @domain = :both if remote + when :remote then + @domain = nil unless remote + when :both then + @domain = :local unless remote + end + end + end diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb index cdb41b22bf2292..f4987576ec1993 100644 --- a/lib/rubygems/resolver/lock_set.rb +++ b/lib/rubygems/resolver/lock_set.rb @@ -9,6 +9,8 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set # Creates a new LockSet from the given +source+ def initialize source + super() + @source = Gem::Source::Lock.new source @specs = [] end diff --git a/lib/rubygems/resolver/set.rb b/lib/rubygems/resolver/set.rb index 32c137ef6b1c0d..f053b65e1564d9 100644 --- a/lib/rubygems/resolver/set.rb +++ b/lib/rubygems/resolver/set.rb @@ -4,6 +4,15 @@ class Gem::Resolver::Set + ## + # Set to true to disable network access for this set + + attr_accessor :remote + + def initialize # :nodoc: + @remote = true + end + ## # The find_all method must be implemented. It returns all Resolver # Specification objects matching the given DependencyRequest +req+. @@ -23,5 +32,13 @@ def find_all req def prefetch reqs end + ## + # When true, this set is allowed to access the network when looking up + # specifications or dependencies. + + def remote? # :nodoc: + @remote + end + end diff --git a/lib/rubygems/resolver/vendor_set.rb b/lib/rubygems/resolver/vendor_set.rb index 3db637f4a3d353..6e867073be74f6 100644 --- a/lib/rubygems/resolver/vendor_set.rb +++ b/lib/rubygems/resolver/vendor_set.rb @@ -21,6 +21,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set attr_reader :specs # :nodoc: def initialize # :nodoc: + super() + @directories = {} @specs = {} end diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb index bfd6fd225b47ba..8c5fb7d9f2e146 100644 --- a/lib/rubygems/security.rb +++ b/lib/rubygems/security.rb @@ -120,11 +120,11 @@ # * HighSecurity - Here's the bugger that got us into this mess. # The HighSecurity policy is identical to the MediumSecurity policy, # except that it does not allow unsigned gems. A malicious user -# doesn't have a whole lot of options here; he can't modify the -# package contents without invalidating the signature, and he can't +# doesn't have a whole lot of options here; they can't modify the +# package contents without invalidating the signature, and they can't # modify or remove signature or the signing certificate chain, or # RubyGems will simply refuse to install the package. Oh well, maybe -# he'll have better luck causing problems for CPAN users instead :). +# they'll have better luck causing problems for CPAN users instead :). # # The reason RubyGems refused to install your shiny new signed gem was because # it was from an untrusted source. Well, your code is infallible (naturally), diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index 28178a5f4f1bb6..2e3fa037309e27 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -23,6 +23,11 @@ class Gem::Source::Git < Gem::Source attr_reader :reference + ## + # When false the cache for this repository will not be updated. + + attr_accessor :remote + ## # The git repository this gem is sourced from. @@ -53,6 +58,7 @@ def initialize name, repository, reference, submodules = false @reference = reference @need_submodules = submodules + @remote = true @root_dir = Gem.dir @git = ENV['git'] || 'git' end @@ -85,6 +91,8 @@ def == other # :nodoc: def checkout # :nodoc: cache + return false unless File.exist? repo_cache_dir + unless File.exist? install_dir then system @git, 'clone', '--quiet', '--no-checkout', repo_cache_dir, install_dir @@ -107,6 +115,8 @@ def checkout # :nodoc: # Creates a local cache repository for the git gem. def cache # :nodoc: + return unless @remote + if File.exist? repo_cache_dir then Dir.chdir repo_cache_dir do system @git, 'fetch', '--quiet', '--force', '--tags', @@ -142,6 +152,8 @@ def download full_spec, path # :nodoc: # The directory where the git gem will be installed. def install_dir # :nodoc: + return unless File.exist? repo_cache_dir + File.join base_dir, 'gems', "#{@name}-#{dir_shortref}" end @@ -177,6 +189,8 @@ def rev_parse # :nodoc: def specs checkout + return [] unless install_dir + Dir.chdir install_dir do Dir['{,*,*/*}.gemspec'].map do |spec_file| directory = File.dirname spec_file diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 59d71d378bb3f7..f4e609a5eb4742 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -240,6 +240,28 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :summary + ## + # Singular writer for #authors + # + # Usage: + # + # spec.author = 'John Jones' + + def author= o + self.authors = [o] + end + + ## + # Sets the list of authors, ensuring it is an array. + # + # Usage: + # + # spec.authors = ['John Jones', 'Mary Smith'] + + def authors= value + @authors = Array(value).flatten.grep(String) + end + ## # The platform this gem runs on. # @@ -327,7 +349,7 @@ def files add_bindir(@executables), @extra_rdoc_files, @extensions, - ].flatten.sort.uniq.compact + ].flatten.uniq.compact.sort end ###################################################################### @@ -442,28 +464,6 @@ def add_runtime_dependency(gem, *requirements) add_dependency_with_type(gem, :runtime, *requirements) end - ## - # Singular writer for #authors - # - # Usage: - # - # spec.author = 'John Jones' - - def author= o - self.authors = [o] - end - - ## - # Sets the list of authors, ensuring it is an array. - # - # Usage: - # - # spec.authors = ['John Jones', 'Mary Smith'] - - def authors= value - @authors = Array(value).flatten.grep(String) - end - ## # Executables included in the gem. # diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb index 8dc37d67204dc6..328731d4eac729 100644 --- a/lib/rubygems/test_case.rb +++ b/lib/rubygems/test_case.rb @@ -115,6 +115,23 @@ def assert_path_exists path, msg = nil assert File.exist?(path), msg end + ## + # Sets the ENABLE_SHARED entry in RbConfig::CONFIG to +value+ and restores + # the original value when the block ends + + def enable_shared value + enable_shared = RbConfig::CONFIG['ENABLE_SHARED'] + RbConfig::CONFIG['ENABLE_SHARED'] = value + + yield + ensure + if enable_shared then + RbConfig::CONFIG['enable_shared'] = enable_shared + else + RbConfig::CONFIG.delete 'enable_shared' + end + end + # TODO: move to minitest def refute_path_exists path, msg = nil msg = message(msg) { "Expected path '#{path}' to not exist" } @@ -294,10 +311,10 @@ def setup Gem.searcher = nil Gem::SpecFetcher.fetcher = nil - @orig_BASERUBY = Gem::ConfigMap[:BASERUBY] - Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:ruby_install_name] + @orig_BASERUBY = RbConfig::CONFIG['BASERUBY'] + RbConfig::CONFIG['BASERUBY'] = RbConfig::CONFIG['ruby_install_name'] - @orig_arch = Gem::ConfigMap[:arch] + @orig_arch = RbConfig::CONFIG['arch'] if win_platform? util_set_arch 'i386-mswin32' @@ -315,8 +332,12 @@ def setup def teardown $LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH - Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY - Gem::ConfigMap[:arch] = @orig_arch + if @orig_BASERUBY + RbConfig::CONFIG['BASERUBY'] = @orig_BASERUBY + else + RbConfig::CONFIG.delete('BASERUBY') + end + RbConfig::CONFIG['arch'] = @orig_arch if defined? Gem::RemoteFetcher then Gem::RemoteFetcher.fetcher = nil @@ -898,7 +919,7 @@ def util_make_gems(prerelease = false) # Set the platform to +arch+ def util_set_arch(arch) - Gem::ConfigMap[:arch] = arch + RbConfig::CONFIG['arch'] = arch platform = Gem::Platform.new arch Gem.instance_variable_set :@platforms, nil @@ -1244,11 +1265,18 @@ def vendor_gem name = 'a', version = 1 class StaticSet + ## + # A StaticSet ignores remote because it has a fixed set of gems. + + attr_accessor :remote + ## # Creates a new StaticSet for the given +specs+ def initialize(specs) @specs = specs + + @remote = true end ## diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb index 4cb2a1d33334ba..fa838333cd4543 100644 --- a/lib/rubygems/uninstaller.rb +++ b/lib/rubygems/uninstaller.rb @@ -237,7 +237,7 @@ def remove(spec) unless path_ok?(@gem_home, spec) or (@user_install and path_ok?(Gem.user_dir, spec)) then e = Gem::GemNotInHomeException.new \ - "Gem is not installed in directory #{@gem_home}" + "Gem '#{spec.full_name}' is not installed in directory #{@gem_home}" e.spec = spec raise e diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index fda8b0b5d49407..20663326ef4b01 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -22,6 +22,11 @@ # 3. 1.0.a.2 # 4. 0.9 # +# If you want to specify a version restriction that includes both prereleases +# and regular releases of the 1.x series this is the best way: +# +# s.add_dependency 'example', '>= 1.0.0.a', '< 2.0.0' +# # == How Software Changes # # Users expect to be able to specify a version constraint that gives them @@ -81,8 +86,8 @@ # # * Any "public" release of a gem should have a different version. Normally # that means incrementing the build number. This means a developer can -# generate builds all day long for himself, but as soon as he/she makes a -# public release, the version must be updated. +# generate builds all day long, but as soon as they make a public release, +# the version must be updated. # # === Examples # @@ -99,26 +104,25 @@ # Version 1.1.1:: Fixed a bug in the linked list implementation. # Version 1.1.2:: Fixed a bug introduced in the last fix. # -# Client A needs a stack with basic push/pop capability. He writes to the -# original interface (no top), so his version constraint looks -# like: +# Client A needs a stack with basic push/pop capability. They write to the +# original interface (no top), so their version constraint looks like: # # gem 'stack', '~> 0.0' # # Essentially, any version is OK with Client A. An incompatible change to -# the library will cause him grief, but he is willing to take the chance (we -# call Client A optimistic). +# the library will cause them grief, but they are willing to take the chance +# (we call Client A optimistic). # -# Client B is just like Client A except for two things: (1) He uses the -# depth method and (2) he is worried about future -# incompatibilities, so he writes his version constraint like this: +# Client B is just like Client A except for two things: (1) They use the +# depth method and (2) they are worried about future +# incompatibilities, so they write their version constraint like this: # # gem 'stack', '~> 0.1' # # The depth method was introduced in version 0.1.0, so that version # or anything later is fine, as long as the version stays below version 1.0 # where incompatibilities are introduced. We call Client B pessimistic -# because he is worried about incompatible future changes (it is OK to be +# because they are worried about incompatible future changes (it is OK to be # pessimistic!). # # == Preventing Version Catastrophe: @@ -185,6 +189,8 @@ def self.create input @@all = {} def self.new version # :nodoc: + return super unless Gem::VERSION == self.class + @@all[version] ||= super end diff --git a/lib/xmlrpc/client.rb b/lib/xmlrpc/client.rb index a0d2a13557c20e..5ee3961f3018d7 100644 --- a/lib/xmlrpc/client.rb +++ b/lib/xmlrpc/client.rb @@ -77,8 +77,6 @@ class Client # # If +use_ssl+ is set to +true+, communication over SSL is enabled. # - # Note, that you need the SSL package from RAA installed. - # # Parameter +timeout+ is the time to wait for a XML-RPC response, defaults to 30. def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=nil, timeout=nil) diff --git a/object.c b/object.c index e918712cebe5e2..bb43b4617e5cd1 100644 --- a/object.c +++ b/object.c @@ -161,7 +161,7 @@ rb_obj_equal(VALUE obj1, VALUE obj2) VALUE rb_obj_hash(VALUE obj) { - st_index_t rb_objid_hash(st_index_t index); + long rb_objid_hash(st_index_t index); VALUE oid = rb_obj_id(obj); #if SIZEOF_LONG == SIZEOF_VOIDP st_index_t index = NUM2LONG(oid); @@ -170,8 +170,7 @@ rb_obj_hash(VALUE obj) #else # error not supported #endif - st_index_t h = rb_objid_hash(index); - return LONG2FIX(h); + return LONG2FIX(rb_objid_hash(index)); } /* diff --git a/parse.y b/parse.y index d04cf456126d25..25946dccda974f 100644 --- a/parse.y +++ b/parse.y @@ -130,6 +130,7 @@ struct local_vars { struct vtable *vars; struct vtable *used; struct local_vars *prev; + stack_type cmdargs; }; #define DVARS_INHERIT ((void*)1) @@ -9485,6 +9486,7 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b) struct rb_args_info *args; NODE *kw_rest_arg = 0; NODE *node; + int check = 0; args = ALLOC(struct rb_args_info); MEMZERO(args, struct rb_args_info, 1); @@ -9492,10 +9494,14 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b) args->block_arg = b; args->kw_args = k; - if (k && !kr) kr = internal_id(); + if (k && !kr) { + check = 1; + kr = internal_id(); + } if (kr) { arg_var(kr); kw_rest_arg = NEW_DVAR(kr); + kw_rest_arg->nd_cflag = check; } args->kw_rest_arg = kw_rest_arg; @@ -9642,6 +9648,8 @@ local_push_gen(struct parser_params *parser, int inherit_dvars) local->used = !(inherit_dvars && (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) && RTEST(ruby_verbose) ? vtable_alloc(0) : 0; + local->cmdargs = cmdarg_stack; + cmdarg_stack = 0; lvtbl = local; } @@ -9655,6 +9663,7 @@ local_pop_gen(struct parser_params *parser) } vtable_free(lvtbl->args); vtable_free(lvtbl->vars); + cmdarg_stack = lvtbl->cmdargs; xfree(lvtbl); lvtbl = local; } diff --git a/proc.c b/proc.c index e52beaf9d813d4..78851ac54749f1 100644 --- a/proc.c +++ b/proc.c @@ -825,7 +825,7 @@ proc_arity(VALUE self) static inline int rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max) { - *max = iseq->arg_rest == -1 ? + *max = (iseq->arg_rest == -1 && iseq->arg_keyword == -1) ? iseq->argc + iseq->arg_post_len + iseq->arg_opts - (iseq->arg_opts > 0) : UNLIMITED_ARGUMENTS; return iseq->argc + iseq->arg_post_len; diff --git a/range.c b/range.c index 4526dcba895172..d2d9a707c07fed 100644 --- a/range.c +++ b/range.c @@ -711,9 +711,12 @@ sym_each_i(RB_BLOCK_CALL_FUNC_ARGLIST(v, arg)) * call-seq: * rng.size -> num * - * Returns the number of elements in the range. + * Returns the number of elements in the range. Both the begin and the end of + * the Range must be Numeric, otherwise nil is returned. * * (10..20).size #=> 11 + * ('a'..'z').size #=> nil + * (-Float::INFINITY..Float::INFINITY).size #=> Infinity */ static VALUE diff --git a/ruby_atomic.h b/ruby_atomic.h index 69efbdc4c4c651..789efdc4eaae2a 100644 --- a/ruby_atomic.h +++ b/ruby_atomic.h @@ -161,5 +161,10 @@ atomic_size_exchange(size_t *ptr, size_t val) # define ATOMIC_PTR_EXCHANGE(var, val) (void *)ATOMIC_SIZE_EXCHANGE(*(size_t *)&(var), (size_t)(val)) # endif #endif +#ifndef ATOMIC_PTR_CAS +# if SIZEOF_VOIDP == SIZEOF_SIZE_T +# define ATOMIC_PTR_CAS(var, oldval, val) (void *)ATOMIC_SIZE_CAS(*(size_t *)&(var), (size_t)(oldval), (size_t)(val)) +# endif +#endif #endif /* RUBY_ATOMIC_H */ diff --git a/string.c b/string.c index 4d2dd4e5af7226..99b7e37f58797e 100644 --- a/string.c +++ b/string.c @@ -121,7 +121,45 @@ VALUE rb_cSymbol; #define STR_HEAP_PTR(str) (RSTRING(str)->as.heap.ptr) #define STR_HEAP_SIZE(str) (RSTRING(str)->as.heap.aux.capa + TERM_LEN(str)) -#define STR_ENC_GET(str) rb_enc_from_index(ENCODING_GET(str)) +#define STR_ENC_GET(str) get_encoding(str) + +rb_encoding *rb_enc_get_from_index(int index); + +static rb_encoding * +get_actual_encoding(const int encidx, VALUE str) +{ + const unsigned char *q; + + switch (encidx) { + case ENCINDEX_UTF_16: + if (RSTRING_LEN(str) < 2) break; + q = (const unsigned char *)RSTRING_PTR(str); + if (q[0] == 0xFE && q[1] == 0xFF) { + return rb_enc_get_from_index(ENCINDEX_UTF_16BE); + } + if (q[0] == 0xFF && q[1] == 0xFE) { + return rb_enc_get_from_index(ENCINDEX_UTF_16LE); + } + return rb_ascii8bit_encoding(); + case ENCINDEX_UTF_32: + if (RSTRING_LEN(str) < 4) break; + q = (const unsigned char *)RSTRING_PTR(str); + if (q[0] == 0 && q[1] == 0 && q[2] == 0xFE && q[3] == 0xFF) { + return rb_enc_get_from_index(ENCINDEX_UTF_32BE); + } + if (q[3] == 0 && q[2] == 0 && q[1] == 0xFE && q[0] == 0xFF) { + return rb_enc_get_from_index(ENCINDEX_UTF_32LE); + } + return rb_ascii8bit_encoding(); + } + return rb_enc_from_index(encidx); +} + +static rb_encoding * +get_encoding(VALUE str) +{ + return get_actual_encoding(ENCODING_GET(str), str); +} static int fstring_cmp(VALUE a, VALUE b); @@ -1465,6 +1503,7 @@ rb_str_modify_expand(VALUE str, long expand) int termlen = TERM_LEN(str); if (!STR_EMBED_P(str)) { REALLOC_N(RSTRING(str)->as.heap.ptr, char, capa + termlen); + STR_UNSET_NOCAPA(str); RSTRING(str)->as.heap.aux.capa = capa; } else if (capa + termlen > RSTRING_EMBED_LEN_MAX + 1) { @@ -4768,8 +4807,8 @@ rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p) VALUE rb_str_inspect(VALUE str) { - rb_encoding *enc = STR_ENC_GET(str); - int encidx = rb_enc_to_index(enc); + int encidx = ENCODING_GET(str); + rb_encoding *enc = rb_enc_from_index(encidx), *actenc; const char *p, *pend, *prev; char buf[CHAR_ESC_LEN + 1]; VALUE result = rb_str_buf_new(0); @@ -4784,27 +4823,10 @@ rb_str_inspect(VALUE str) p = RSTRING_PTR(str); pend = RSTRING_END(str); prev = p; - if (encidx == ENCINDEX_UTF_16 && p + 2 <= pend) { - const unsigned char *q = (const unsigned char *)p; - if (q[0] == 0xFE && q[1] == 0xFF) - enc = rb_enc_from_index(ENCINDEX_UTF_16BE); - else if (q[0] == 0xFF && q[1] == 0xFE) - enc = rb_enc_from_index(ENCINDEX_UTF_16LE); - else { - enc = rb_ascii8bit_encoding(); - unicode_p = 0; - } - } - else if (encidx == ENCINDEX_UTF_32 && p + 4 <= pend) { - const unsigned char *q = (const unsigned char *)p; - if (q[0] == 0 && q[1] == 0 && q[2] == 0xFE && q[3] == 0xFF) - enc = rb_enc_from_index(ENCINDEX_UTF_32BE); - else if (q[3] == 0 && q[2] == 0 && q[1] == 0xFE && q[0] == 0xFF) - enc = rb_enc_from_index(ENCINDEX_UTF_32LE); - else { - enc = rb_ascii8bit_encoding(); - unicode_p = 0; - } + actenc = get_actual_encoding(encidx, str); + if (actenc != enc) { + enc = actenc; + if (unicode_p) unicode_p = rb_enc_unicode_p(enc); } while (p < pend) { unsigned int c, cc; diff --git a/test/dl/test_base.rb b/test/dl/test_base.rb index a07056d14264d3..dafba6e44dc610 100644 --- a/test/dl/test_base.rb +++ b/test/dl/test_base.rb @@ -39,6 +39,9 @@ when /mirbsd/ libc_so = "/usr/lib/libc.so.41.10" libm_so = "/usr/lib/libm.so.7.0" +when /freebsd/ + libc_so = "/lib/libc.so.7" + libm_so = "/lib/libm.so.5" when /bsd|dragonfly/ libc_so = "/usr/lib/libc.so" libm_so = "/usr/lib/libm.so" diff --git a/test/dl/test_handle.rb b/test/dl/test_handle.rb index 4ef93adf41f825..83b8af196041f9 100644 --- a/test/dl/test_handle.rb +++ b/test/dl/test_handle.rb @@ -181,7 +181,7 @@ def test_dlerror # In general uses of dlerror(3) should call it before use it. require 'socket' Socket.gethostbyname("localhost") - DL.dlopen("/usr/lib/libc.so").sym('strcpy') + DL.dlopen("/lib/libc.so.7").sym('strcpy') end if /freebsd/=~ RUBY_PLATFORM end end diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb index 404c137f97ef9f..f58077e7bc0f68 100644 --- a/test/fiddle/helper.rb +++ b/test/fiddle/helper.rb @@ -40,6 +40,9 @@ when /mirbsd/ libc_so = "/usr/lib/libc.so.41.10" libm_so = "/usr/lib/libm.so.7.0" +when /freebsd/ + libc_so = "/lib/libc.so.7" + libm_so = "/lib/libm.so.5" when /bsd|dragonfly/ libc_so = "/usr/lib/libc.so" libm_so = "/usr/lib/libm.so" diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb index 2af3e5c9037da1..c598cc33a2cb09 100644 --- a/test/fiddle/test_handle.rb +++ b/test/fiddle/test_handle.rb @@ -183,7 +183,7 @@ def test_dlerror # In general uses of dlerror(3) should call it before use it. require 'socket' Socket.gethostbyname("localhost") - Fiddle.dlopen("/usr/lib/libc.so").sym('strcpy') + Fiddle.dlopen("/lib/libc.so.7").sym('strcpy') end if /freebsd/=~ RUBY_PLATFORM end end if defined?(Fiddle) diff --git a/test/psych/test_string.rb b/test/psych/test_string.rb index 84326da8d31fb4..01fc0e4bb0b722 100644 --- a/test/psych/test_string.rb +++ b/test/psych/test_string.rb @@ -15,6 +15,10 @@ def initialize end end + def test_no_doublequotes_with_special_characters + assert_equal 2, Psych.dump(%Q{<%= ENV["PATH"] %>}).count('"') + end + def test_doublequotes_when_there_is_a_single yaml = Psych.dump "@123'abc" assert_match(/---\s*"/, yaml) diff --git a/test/resolv/test_addr.rb b/test/resolv/test_addr.rb index 84bc8c2d3b2def..d4728e1b716ba2 100644 --- a/test/resolv/test_addr.rb +++ b/test/resolv/test_addr.rb @@ -13,4 +13,16 @@ def test_invalid_ipv4_address end } end + + def test_invalid_byte_comment + bug9273 = '[ruby-core:59239] [Bug #9273]' + Tempfile.open('resolv_test_addr_') do |tmpfile| + tmpfile.print("\xff\x00\x40") + tmpfile.close + hosts = Resolv::Hosts.new(tmpfile.path) + assert_nothing_raised(ArgumentError, bug9273) do + hosts.each_address("") {break} + end + end + end end diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb index 0d9565ef68ac36..07396fb177de8e 100644 --- a/test/resolv/test_dns.rb +++ b/test/resolv/test_dns.rb @@ -1,6 +1,7 @@ require 'test/unit' require 'resolv' require 'socket' +require 'tempfile' class TestResolvDNS < Test::Unit::TestCase def setup @@ -150,4 +151,14 @@ def test_no_server } end + def test_invalid_byte_comment + bug9273 = '[ruby-core:59239] [Bug #9273]' + Tempfile.open('resolv_test_dns_') do |tmpfile| + tmpfile.print("\xff\x00\x40") + tmpfile.close + assert_nothing_raised(ArgumentError, bug9273) do + Resolv::DNS::Config.parse_resolv_conf(tmpfile.path) + end + end + end end diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb index 610f11b4ee25d2..102643f6544266 100644 --- a/test/rinda/test_rinda.rb +++ b/test/rinda/test_rinda.rb @@ -4,7 +4,7 @@ require 'drb/eq' require 'rinda/ring' require 'rinda/tuplespace' - +require 'timeout' require 'singleton' module Rinda @@ -559,6 +559,10 @@ def teardown end def test_do_reply + with_timeout(10) {_test_do_reply} + end + + def _test_do_reply called = nil callback = proc { |ts| @@ -571,12 +575,16 @@ def test_do_reply @rs.do_reply - Thread.pass until called + wait_for(10) {called} assert_same @ts, called end def test_do_reply_local + with_timeout(10) {_test_do_reply_local} + end + + def _test_do_reply_local called = nil callback = proc { |ts| @@ -587,7 +595,7 @@ def test_do_reply_local @rs.do_reply - Thread.pass until called + wait_for(10) {called} assert_same @ts, called end @@ -678,6 +686,46 @@ def test_shutdown assert_nil(@rs.do_reply, 'otherwise should hang forever') end + private + + def with_timeout(n) + aoe = Thread.abort_on_exception + Thread.abort_on_exception = true + tl0 = Thread.list + tl = nil + th = Thread.new(Thread.current) do |mth| + sleep n + (tl = Thread.list - tl0).each {|t|t.raise(Timeout::Error)} + mth.raise(Timeout::Error) + end + tl0 << th + rescue Timeout::Error => e + if tl + bt = e.backtrace + tl.each do |t| + begin + t.value + rescue Timeout::Error => e + bt.unshift("") + bt[0, 0] = e.backtrace + end + end + end + raise Timeout::Error, "timeout", bt + ensure + th.kill if th + Thread.abort_on_exception = aoe + end + + def wait_for(n) + t = n + Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) + until yield + if t < Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) + flunk "timeout during waiting call" + end + sleep 0.1 + end + end end class TestRingFinger < Test::Unit::TestCase diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index 3bb0d0d8faedff..c644aa5d9a2e81 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -185,7 +185,7 @@ def test_gc_parameter assert_normal_exit("exit", "", :child_env => env) assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=0\.9/, "") # always full GC when RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR < 1.0 - assert_in_out_err([env, "-e", "1000_000.times{Object.new}; p(GC.stat[:minor_gc_count] < GC.stat[:major_gc_count])"], "", ['true'], [], "") + assert_in_out_err([env, "-e", "1000_000.times{Object.new}; p(GC.stat[:minor_gc_count] < GC.stat[:major_gc_count])"], "", ['true'], //, "") # check obsolete assert_in_out_err([{'RUBY_FREE_MIN' => '100'}, '-w', '-eexit'], '', [], diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index 89f7a8cba50dff..cbe55cc1f26899 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -108,6 +108,12 @@ def test_clear_initialize_copy assert_empty(h) end + def test_self_initialize_copy + h = @cls[1=>2] + h.instance_eval {initialize_copy(h)} + assert_equal(2, h[1]) + end + def test_dup_will_rehash set1 = @cls[] set2 = @cls[set1 => true] @@ -565,12 +571,23 @@ def test_reject assert_equal(h3, h.reject {|k,v| v }) assert_equal(base, h) - return unless RUBY_VERSION >= "2.2.0" # [ruby-core:59154] [Bug #9223] + unless RUBY_VERSION >= "2.2.0" + # [ruby-core:59154] [Bug #9223] + if @cls == Hash + assert_empty(EnvUtil.verbose_warning {h.reject {false}}) + bug9275 = '[ruby-core:59254] [Bug #9275]' + c = Class.new(Hash) + assert_empty(EnvUtil.verbose_warning {c.new.reject {false}}, bug9275) + else + assert_match(/extra states/, EnvUtil.verbose_warning {h.reject {false}}) + end + return + end h.instance_variable_set(:@foo, :foo) h.default = 42 h.taint - h = h.reject {false} + h = EnvUtil.suppress_warning {h.reject {false}} assert_instance_of(Hash, h) assert_not_predicate(h, :tainted?) assert_nil(h.default) @@ -969,11 +986,11 @@ def test_flatten a = @cls[1=> "one", 2 => [2,"two"], 3 => [3, ["three"]]] assert_equal([1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten) - assert_equal([1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten(-1)) - assert_equal([1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten(0)) + assert_equal([[1, "one"], [2, [2, "two"]], [3, [3, ["three"]]]], a.flatten(0)) assert_equal([1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten(1)) assert_equal([1, "one", 2, 2, "two", 3, 3, ["three"]], a.flatten(2)) assert_equal([1, "one", 2, 2, "two", 3, 3, "three"], a.flatten(3)) + assert_equal([1, "one", 2, 2, "two", 3, 3, "three"], a.flatten(-1)) assert_raise(TypeError){ a.flatten(Object) } end @@ -1247,6 +1264,9 @@ def eql?(other) class TestSubHash < TestHash class SubHash < Hash + def reject(*) + super + end end def setup diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb index 7e708454ae580b..03b93dbf0d0b58 100644 --- a/test/ruby/test_keyword.rb +++ b/test/ruby/test_keyword.rb @@ -117,6 +117,15 @@ def test_f9 assert_equal([1, 2, [3, 4], 5, :key, {str: "bar"}, nil], f9(1, 2, 3, 4, 5, str: "bar")) end + def f10(a: 1, **) + a + end + + def test_f10 + assert_equal(42, f10(a: 42)) + assert_equal(1, f10(b: 42)) + end + def test_method_parameters assert_equal([[:key, :str], [:key, :num]], method(:f1).parameters); assert_equal([[:req, :x], [:key, :str], [:key, :num]], method(:f2).parameters); diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb index 2e4f67c48afe66..b9b85b21293afb 100644 --- a/test/ruby/test_m17n.rb +++ b/test/ruby/test_m17n.rb @@ -226,24 +226,35 @@ def test_string_inspect_encoding end end - def test_utf_16_32_inspect - str = "\u3042" - %w/UTF-16 UTF-32/.each do |enc| - %w/BE LE/.each do |endian| - s = str.encode(enc + endian) + STR_WITHOUT_BOM = "\u3042".freeze + STR_WITH_BOM = "\uFEFF\u3042".freeze + bug8940 = '[ruby-core:59757] [Bug #8940]' + bug9415 = '[ruby-dev:47895] [Bug #9415]' + %w/UTF-16 UTF-32/.each do |enc| + %w/BE LE/.each do |endian| + bom = "\uFEFF".encode("#{enc}#{endian}").force_encoding(enc) + + define_method("test_utf_16_32_inspect(#{enc}#{endian})") do + s = STR_WITHOUT_BOM.encode(enc + endian) # When a UTF-16/32 string doesn't have a BOM, # inspect as a dummy encoding string. assert_equal(s.dup.force_encoding("ISO-2022-JP").inspect, s.dup.force_encoding(enc).inspect) + assert_normal_exit("#{bom.b.dump}.force_encoding('#{enc}').inspect", bug8940) end - end - str = "\uFEFF\u3042" - %w/UTF-16 UTF-32/.each do |enc| - %w/BE LE/.each do |endian| - s = str.encode(enc + endian) - # When a UTF-16/32 string doesn't have a BOM, - # inspect as a dummy encoding string. + define_method("test_utf_16_32_codepoints(#{enc}#{endian})") do + assert_equal([0xFEFF], bom.codepoints, bug9415) + end + + define_method("test_utf_16_32_ord(#{enc}#{endian})") do + assert_equal(0xFEFF, bom.ord, bug9415) + end + + define_method("test_utf_16_32_inspect(#{enc}#{endian}-BOM)") do + s = STR_WITH_BOM.encode(enc + endian) + # When a UTF-16/32 string has a BOM, + # inspect as a particular encoding string. assert_equal(s.inspect, s.dup.force_encoding(enc).inspect) end diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 1652c91d4f1c75..2e3c2ae8b07317 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -22,7 +22,14 @@ def mo4(a, *b, &c) end def mo5(a, *b, c) end def mo6(a, *b, c, &d) end def mo7(a, b = nil, *c, d, &e) end - def ma1((a), &b) end + def ma1((a), &b) nil && a end + def mk1(**) end + def mk2(**o) nil && o end + def mk3(a, **o) nil && o end + def mk4(a = nil, **o) nil && o end + def mk5(a, b = nil, **o) nil && o end + def mk6(a, b = nil, c, **o) nil && o end + def mk7(a, b = nil, *c, d, **o) nil && o end class Base def foo() :base end @@ -68,6 +75,13 @@ def test_arity assert_equal(-2, method(:mo4).arity) assert_equal(-3, method(:mo5).arity) assert_equal(-3, method(:mo6).arity) + assert_equal(-1, method(:mk1).arity) + assert_equal(-1, method(:mk2).arity) + assert_equal(-2, method(:mk3).arity) + assert_equal(-1, method(:mk4).arity) + assert_equal(-2, method(:mk5).arity) + assert_equal(-3, method(:mk6).arity) + assert_equal(-3, method(:mk7).arity) end def test_arity_special @@ -293,7 +307,7 @@ def a end end - assert_nothing_raised do + assert_nothing_raised(bug8686) do m.define_singleton_method(:a, m.method(:a)) end end @@ -456,7 +470,14 @@ def test_default_accessibility define_method(:pmo5) {|a, *b, c|} define_method(:pmo6) {|a, *b, c, &d|} define_method(:pmo7) {|a, b = nil, *c, d, &e|} - define_method(:pma1) {|(a), &b|} + define_method(:pma1) {|(a), &b| nil && a} + define_method(:pmk1) {|**|} + define_method(:pmk2) {|**o|} + define_method(:pmk3) {|a, **o|} + define_method(:pmk4) {|a = nil, **o|} + define_method(:pmk5) {|a, b = nil, **o|} + define_method(:pmk6) {|a, b = nil, c, **o|} + define_method(:pmk7) {|a, b = nil, *c, d, **o|} def test_bound_parameters assert_equal([], method(:m0).parameters) @@ -470,6 +491,13 @@ def test_bound_parameters assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:mo6).parameters) assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:mo7).parameters) assert_equal([[:req], [:block, :b]], method(:ma1).parameters) + assert_equal([[:keyrest]], method(:mk1).parameters) + assert_equal([[:keyrest, :o]], method(:mk2).parameters) + assert_equal([[:req, :a], [:keyrest, :o]], method(:mk3).parameters) + assert_equal([[:opt, :a], [:keyrest, :o]], method(:mk4).parameters) + assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:mk5).parameters) + assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:mk6).parameters) + assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:mk7).parameters) end def test_unbound_parameters @@ -484,6 +512,13 @@ def test_unbound_parameters assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:mo6).parameters) assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:mo7).parameters) assert_equal([[:req], [:block, :b]], self.class.instance_method(:ma1).parameters) + assert_equal([[:keyrest]], self.class.instance_method(:mk1).parameters) + assert_equal([[:keyrest, :o]], self.class.instance_method(:mk2).parameters) + assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:mk3).parameters) + assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:mk4).parameters) + assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], self.class.instance_method(:mk5).parameters) + assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], self.class.instance_method(:mk6).parameters) + assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], self.class.instance_method(:mk7).parameters) end def test_bmethod_bound_parameters @@ -498,6 +533,13 @@ def test_bmethod_bound_parameters assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).parameters) assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).parameters) assert_equal([[:req], [:block, :b]], method(:pma1).parameters) + assert_equal([[:keyrest]], method(:pmk1).parameters) + assert_equal([[:keyrest, :o]], method(:pmk2).parameters) + assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).parameters) + assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).parameters) + assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:pmk5).parameters) + assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:pmk6).parameters) + assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:pmk7).parameters) end def test_bmethod_unbound_parameters @@ -512,6 +554,14 @@ def test_bmethod_unbound_parameters assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:pmo6).parameters) assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:pmo7).parameters) assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters) + assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters) + assert_equal([[:keyrest]], self.class.instance_method(:pmk1).parameters) + assert_equal([[:keyrest, :o]], self.class.instance_method(:pmk2).parameters) + assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:pmk3).parameters) + assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:pmk4).parameters) + assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], self.class.instance_method(:pmk5).parameters) + assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], self.class.instance_method(:pmk6).parameters) + assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], self.class.instance_method(:pmk7).parameters) end def test_public_method_with_zsuper_method @@ -659,6 +709,7 @@ def foo prepend m } assert_raise(NameError, bug7988) {Module.new{prepend m}.instance_method(:bar)} + true || c || bug7836 end def test_gced_bmethod diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 4f834f0c1e3fb1..f89071c10f270b 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -364,6 +364,17 @@ def test_constants assert_equal([:MIXIN, :USER], User.constants.sort) end + def test_self_initialize_copy + bug9535 = '[ruby-dev:47989] [Bug #9535]' + m = Module.new do + def foo + :ok + end + initialize_copy(self) + end + assert_equal(:ok, Object.new.extend(m).foo, bug9535) + end + def test_dup bug6454 = '[ruby-core:45132]' @@ -866,6 +877,19 @@ def test_mod_constants m.instance_eval { remove_const(:Foo) } end + class Bug9413 + class << self + Foo = :foo + end + end + + def test_singleton_constants + bug9413 = '[ruby-core:59763] [Bug #9413]' + c = Bug9413.singleton_class + assert_include(c.constants(true), :Foo, bug9413) + assert_include(c.constants(false), :Foo, bug9413) + end + def test_frozen_class m = Module.new m.freeze diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb index 621a06beba5b25..3f0931bdc0cfb2 100644 --- a/test/ruby/test_pack.rb +++ b/test/ruby/test_pack.rb @@ -181,6 +181,7 @@ def test_pack_p assert_equal a[0], a.pack("p").unpack("p")[0] assert_equal a, a.pack("p").freeze.unpack("p*") assert_raise(ArgumentError) { (a.pack("p") + "").unpack("p*") } + assert_raise(ArgumentError) { (a.pack("p") << "d").unpack("p*") } end def test_format_string_modified diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb index b40485f5821752..206e21fb1a8bfd 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -77,6 +77,13 @@ def test_arity assert_equal(2, proc{|(x, y), z|[x,y]}.arity) assert_equal(1, proc{|(x, y), z=0|[x,y]}.arity) assert_equal(-4, proc{|x, *y, z, a|}.arity) + assert_equal(-1, proc{|**|}.arity) + assert_equal(-1, proc{|**o|}.arity) + assert_equal(-2, proc{|x, **o|}.arity) + assert_equal(-1, proc{|x=0, **o|}.arity) + assert_equal(-2, proc{|x, y=0, **o|}.arity) + assert_equal(-3, proc{|x, y=0, z, **o|}.arity) + assert_equal(-3, proc{|x, y=0, *z, w, **o|}.arity) assert_equal(0, lambda{}.arity) assert_equal(0, lambda{||}.arity) @@ -95,6 +102,13 @@ def test_arity assert_equal(2, lambda{|(x, y), z|[x,y]}.arity) assert_equal(-2, lambda{|(x, y), z=0|[x,y]}.arity) assert_equal(-4, lambda{|x, *y, z, a|}.arity) + assert_equal(-1, lambda{|**|}.arity) + assert_equal(-1, lambda{|**o|}.arity) + assert_equal(-2, lambda{|x, **o|}.arity) + assert_equal(-1, lambda{|x=0, **o|}.arity) + assert_equal(-2, lambda{|x, y=0, **o|}.arity) + assert_equal(-3, lambda{|x, y=0, z, **o|}.arity) + assert_equal(-3, lambda{|x, y=0, *z, w, **o|}.arity) assert_arity(0) {} assert_arity(0) {||} @@ -104,6 +118,10 @@ def test_arity assert_arity(-3) {|x, *y, z|} assert_arity(-1) {|*x|} assert_arity(-1) {|*|} + assert_arity(-1) {|**o|} + assert_arity(-1) {|**|} + assert_arity(-2) {|x, *y, **|} + assert_arity(-3) {|x, *y, z, **|} end def m(x) @@ -1086,6 +1104,13 @@ def pmo5(a, *b, c) end def pmo6(a, *b, c, &d) end def pmo7(a, b = :b, *c, d, &e) end def pma1((a), &b) a; end + def pmk1(**) end + def pmk2(**o) nil && o end + def pmk3(a, **o) nil && o end + def pmk4(a = nil, **o) nil && o end + def pmk5(a, b = nil, **o) nil && o end + def pmk6(a, b = nil, c, **o) nil && o end + def pmk7(a, b = nil, *c, d, **o) nil && o end def test_bound_parameters @@ -1100,6 +1125,13 @@ def test_bound_parameters assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).to_proc.parameters) assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).to_proc.parameters) assert_equal([[:req], [:block, :b]], method(:pma1).to_proc.parameters) + assert_equal([[:keyrest]], method(:pmk1).to_proc.parameters) + assert_equal([[:keyrest, :o]], method(:pmk2).to_proc.parameters) + assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).to_proc.parameters) + assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).to_proc.parameters) + assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:pmk5).to_proc.parameters) + assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:pmk6).to_proc.parameters) + assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:pmk7).to_proc.parameters) assert_equal([], "".method(:upcase).to_proc.parameters) assert_equal([[:rest]], "".method(:gsub).to_proc.parameters) @@ -1209,7 +1241,7 @@ def test_overridden_proc end def get_binding if: 1, case: 2, when: 3, begin: 4, end: 5 - a = 0 + a ||= 0 binding end diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index 07a325c1b847e5..d535c474241d5d 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -1107,6 +1107,51 @@ def foo INPUT end + def test_adding_private_method + bug9452 = '[ruby-core:60111] [Bug #9452]' + + assert_in_out_err([], <<-INPUT, ["Success!", "NoMethodError"], [], bug9452) + module R + refine Object do + def m + puts "Success!" + end + + private(:m) + end + end + + using R + + m + 42.m rescue p($!.class) + INPUT + end + + def test_making_private_method_public + bug9452 = '[ruby-core:60111] [Bug #9452]' + + assert_in_out_err([], <<-INPUT, ["Success!", "Success!"], [], bug9452) + class Object + private + def m + end + end + + module R + refine Object do + def m + puts "Success!" + end + end + end + + using R + m + 42.m + INPUT + end + private def eval_using(mod, s) diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb index 30cc3d8e8610ea..82d6e19ec4ba1c 100644 --- a/test/ruby/test_super.rb +++ b/test/ruby/test_super.rb @@ -448,7 +448,7 @@ def test_missing_super_in_module_unbound_method def foo; super end end - m = a.instance_method(:foo).bind(Object.new.extend(a)) + m = a.instance_method(:foo).bind(Object.new) assert_raise(NoMethodError, bug9377) do m.call end diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 04fcd20a56c28b..cac755a3903c48 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -256,6 +256,11 @@ def test_do_block_in_cmdarg_begin assert_valid_syntax("p begin 1.times do 1 end end", __FILE__, bug6419) end + def test_do_block_in_call_args + bug9308 = '[ruby-core:59342] [Bug #9308]' + assert_valid_syntax("bar def foo; self.each do end end", bug9308) + end + def test_reserved_method_no_args bug6403 = '[ruby-dev:45626]' assert_valid_syntax("def self; :foo; end", __FILE__, bug6403) diff --git a/test/ruby/test_transcode.rb b/test/ruby/test_transcode.rb index 25c9d24663ce8f..5f3f51a67675ba 100644 --- a/test/ruby/test_transcode.rb +++ b/test/ruby/test_transcode.rb @@ -2080,4 +2080,15 @@ def test_encode_with_invalid_chars assert_equal "\ufffd", str.encode(invalid: :replace), bug8995 end end + + def test_valid_dummy_encoding + bug9314 = '[ruby-core:59354] [Bug #9314]' + assert_separately(%W[- -- #{bug9314}], <<-'end;') + bug = ARGV.shift + result = assert_nothing_raised(TypeError, bug) {break "test".encode(Encoding::UTF_16)} + assert_equal("\xFE\xFF\x00t\x00e\x00s\x00t", result.b, bug) + result = assert_nothing_raised(TypeError, bug) {break "test".encode(Encoding::UTF_32)} + assert_equal("\x00\x00\xFE\xFF\x00\x00\x00t\x00\x00\x00e\x00\x00\x00s\x00\x00\x00t", result.b, bug) + end; + end end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 759c2fe9070759..e33742049ce68b 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -199,30 +199,21 @@ def test_self_datadir_nonexistent_package end def test_self_default_exec_format - orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name] - Gem::ConfigMap[:ruby_install_name] = 'ruby' - - assert_equal '%s', Gem.default_exec_format - ensure - Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME + ruby_install_name 'ruby' do + assert_equal '%s', Gem.default_exec_format + end end def test_self_default_exec_format_18 - orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name] - Gem::ConfigMap[:ruby_install_name] = 'ruby18' - - assert_equal '%s18', Gem.default_exec_format - ensure - Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME + ruby_install_name 'ruby18' do + assert_equal '%s18', Gem.default_exec_format + end end def test_self_default_exec_format_jruby - orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name] - Gem::ConfigMap[:ruby_install_name] = 'jruby' - - assert_equal 'j%s', Gem.default_exec_format - ensure - Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME + ruby_install_name 'jruby' do + assert_equal 'j%s', Gem.default_exec_format + end end def test_self_default_sources @@ -230,6 +221,7 @@ def test_self_default_sources end def test_self_detect_gemdeps + skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' FileUtils.mkdir_p 'detect/a/b' @@ -339,21 +331,15 @@ def test_self_ensure_gem_directories_write_protected_parents end def test_self_extension_dir_shared - enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = - RbConfig::CONFIG['ENABLE_SHARED'], 'yes' - - assert_equal Gem.ruby_api_version, Gem.extension_api_version - ensure - RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + enable_shared 'yes' do + assert_equal Gem.ruby_api_version, Gem.extension_api_version + end end def test_self_extension_dir_static - enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = - RbConfig::CONFIG['ENABLE_SHARED'], 'no' - - assert_equal "#{Gem.ruby_api_version}-static", Gem.extension_api_version - ensure - RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + enable_shared 'no' do + assert_equal "#{Gem.ruby_api_version}-static", Gem.extension_api_version + end end def test_self_find_files @@ -565,24 +551,43 @@ def test_self_prefix end def test_self_prefix_libdir - orig_libdir = Gem::ConfigMap[:libdir] - Gem::ConfigMap[:libdir] = @@project_dir + orig_libdir = RbConfig::CONFIG['libdir'] + RbConfig::CONFIG['libdir'] = @@project_dir assert_nil Gem.prefix ensure - Gem::ConfigMap[:libdir] = orig_libdir + RbConfig::CONFIG['libdir'] = orig_libdir end def test_self_prefix_sitelibdir - orig_sitelibdir = Gem::ConfigMap[:sitelibdir] - Gem::ConfigMap[:sitelibdir] = @@project_dir + orig_sitelibdir = RbConfig::CONFIG['sitelibdir'] + RbConfig::CONFIG['sitelibdir'] = @@project_dir assert_nil Gem.prefix ensure - Gem::ConfigMap[:sitelibdir] = orig_sitelibdir + RbConfig::CONFIG['sitelibdir'] = orig_sitelibdir + end + + def test_self_read_binary + open 'test', 'w' do |io| + io.write "\xCF\x80" + end + + assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a + + skip 'chmod not supported' if Gem.win_platform? + + begin + File.chmod 0444, 'test' + + assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a + ensure + File.chmod 0644, 'test' + end end def test_self_refresh + skip 'Insecure operation - mkdir' if RUBY_VERSION <= "1.8.7" util_make_gems a1_spec = @a1.spec_file @@ -602,6 +607,7 @@ def test_self_refresh end def test_self_refresh_keeps_loaded_specs_activated + skip 'Insecure operation - mkdir' if RUBY_VERSION <= "1.8.7" util_make_gems a1_spec = @a1.spec_file @@ -624,46 +630,44 @@ def test_self_refresh_keeps_loaded_specs_activated def test_self_ruby_escaping_spaces_in_path orig_ruby = Gem.ruby - orig_bindir = Gem::ConfigMap[:bindir] - orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name] - orig_exe_ext = Gem::ConfigMap[:EXEEXT] + orig_bindir = RbConfig::CONFIG['bindir'] + orig_ruby_install_name = RbConfig::CONFIG['ruby_install_name'] + orig_exe_ext = RbConfig::CONFIG['EXEEXT'] - Gem::ConfigMap[:bindir] = "C:/Ruby 1.8/bin" - Gem::ConfigMap[:ruby_install_name] = "ruby" - Gem::ConfigMap[:EXEEXT] = ".exe" + RbConfig::CONFIG['bindir'] = "C:/Ruby 1.8/bin" + RbConfig::CONFIG['ruby_install_name'] = "ruby" + RbConfig::CONFIG['EXEEXT'] = ".exe" Gem.instance_variable_set("@ruby", nil) assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby ensure Gem.instance_variable_set("@ruby", orig_ruby) - Gem::ConfigMap[:bindir] = orig_bindir - Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name - Gem::ConfigMap[:EXEEXT] = orig_exe_ext + RbConfig::CONFIG['bindir'] = orig_bindir + RbConfig::CONFIG['ruby_install_name'] = orig_ruby_install_name + RbConfig::CONFIG['EXEEXT'] = orig_exe_ext end def test_self_ruby_path_without_spaces orig_ruby = Gem.ruby - orig_bindir = Gem::ConfigMap[:bindir] - orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name] - orig_exe_ext = Gem::ConfigMap[:EXEEXT] + orig_bindir = RbConfig::CONFIG['bindir'] + orig_ruby_install_name = RbConfig::CONFIG['ruby_install_name'] + orig_exe_ext = RbConfig::CONFIG['EXEEXT'] - Gem::ConfigMap[:bindir] = "C:/Ruby18/bin" - Gem::ConfigMap[:ruby_install_name] = "ruby" - Gem::ConfigMap[:EXEEXT] = ".exe" + RbConfig::CONFIG['bindir'] = "C:/Ruby18/bin" + RbConfig::CONFIG['ruby_install_name'] = "ruby" + RbConfig::CONFIG['EXEEXT'] = ".exe" Gem.instance_variable_set("@ruby", nil) assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby ensure Gem.instance_variable_set("@ruby", orig_ruby) - Gem::ConfigMap[:bindir] = orig_bindir - Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name - Gem::ConfigMap[:EXEEXT] = orig_exe_ext + RbConfig::CONFIG['bindir'] = orig_bindir + RbConfig::CONFIG['ruby_install_name'] = orig_ruby_install_name + RbConfig::CONFIG['EXEEXT'] = orig_exe_ext end def test_self_ruby_api_version - orig_MAJOR, Gem::ConfigMap[:MAJOR] = Gem::ConfigMap[:MAJOR], '1' - orig_MINOR, Gem::ConfigMap[:MINOR] = Gem::ConfigMap[:MINOR], '2' - orig_TEENY, Gem::ConfigMap[:TEENY] = Gem::ConfigMap[:TEENY], '3' + orig_ruby_version, RbConfig::CONFIG['ruby_version'] = RbConfig::CONFIG['ruby_version'], '1.2.3' Gem.instance_variable_set :@ruby_api_version, nil @@ -671,9 +675,7 @@ def test_self_ruby_api_version ensure Gem.instance_variable_set :@ruby_api_version, nil - Gem::ConfigMap[:MAJOR] = orig_MAJOR - Gem::ConfigMap[:MINOR] = orig_MINOR - Gem::ConfigMap[:TEENY] = orig_TEENY + RbConfig::CONFIG['ruby_version'] = orig_ruby_version end def test_self_ruby_version_1_8_5 @@ -825,7 +827,7 @@ def test_self_use_paths def test_self_user_dir parts = [@userhome, '.gem', Gem.ruby_engine] - parts << Gem::ConfigMap[:ruby_version] unless Gem::ConfigMap[:ruby_version].empty? + parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? assert_equal File.join(parts), Gem.user_dir end @@ -857,6 +859,7 @@ def test_self_needs end def test_self_needs_picks_up_unresolved_deps + skip 'loading from unsafe file' if RUBY_VERSION <= "1.8.7" save_loaded_features do util_clear_gems a = util_spec "a", "1" @@ -949,6 +952,7 @@ def test_self_user_home_user_drive_and_path end def test_load_plugins + skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" plugin_path = File.join "lib", "rubygems_plugin.rb" Dir.chdir @tempdir do @@ -1102,6 +1106,7 @@ def test_auto_activation_of_specific_gemdeps_file end def test_auto_activation_of_detected_gemdeps_file + skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" util_clear_gems a = new_spec "a", "1", nil, "lib/a.rb" @@ -1264,6 +1269,7 @@ def test_use_gemdeps end def test_use_gemdeps_automatic + skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' spec = util_spec 'a', 1 @@ -1300,6 +1306,7 @@ def test_use_gemdeps_disabled end def test_use_gemdeps_specific + skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' spec = util_spec 'a', 1 @@ -1317,6 +1324,19 @@ def test_use_gemdeps_specific ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end + def ruby_install_name name + orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['ruby_install_name'] = name + + yield + ensure + if orig_RUBY_INSTALL_NAME then + RbConfig::CONFIG['ruby_install_name'] = orig_RUBY_INSTALL_NAME + else + RbConfig::CONFIG.delete 'ruby_install_name' + end + end + def with_plugin(path) test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}", @@project_dir) diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb index d87e84fc829fc0..7f5cf22223cff5 100644 --- a/test/rubygems/test_gem_commands_contents_command.rb +++ b/test/rubygems/test_gem_commands_contents_command.rb @@ -169,9 +169,9 @@ def test_execute_default_gem end expected = [ - File.join(Gem::ConfigMap[:bindir], 'default_command'), - File.join(Gem::ConfigMap[:rubylibdir], 'default/gem.rb'), - File.join(Gem::ConfigMap[:archdir], 'default_gem.so') + File.join(RbConfig::CONFIG['bindir'], 'default_command'), + File.join(RbConfig::CONFIG['rubylibdir'], 'default/gem.rb'), + File.join(RbConfig::CONFIG['archdir'], 'default_gem.so') ].sort.join "\n" assert_equal expected, @ui.output.chomp diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb index 253c459d942840..bb7589f50de1c3 100644 --- a/test/rubygems/test_gem_commands_environment_command.rb +++ b/test/rubygems/test_gem_commands_environment_command.rb @@ -26,7 +26,7 @@ def test_execute assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|, @ui.output assert_match %r|RUBYGEMS PREFIX: |, @ui.output - assert_match %r|RUBY EXECUTABLE:.*#{Gem::ConfigMap[:ruby_install_name]}|, + assert_match %r|RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}|, @ui.output assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 00bbf7bae7eca2..6315cb5d95b5ed 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -316,6 +316,7 @@ def test_execute_prerelease_skipped_when_non_pre_available end def test_execute_rdoc + skip if RUBY_VERSION <= "1.8.7" specs = spec_fetcher do |fetcher| fetcher.gem 'a', 2 end @@ -559,6 +560,20 @@ def test_install_gem_ignore_dependencies_remote assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } end + def test_install_gem_ignore_dependencies_specific_file + spec = quick_spec 'a', 2 + + util_build_gem spec + + FileUtils.mv spec.cache_file, @tempdir + + @cmd.options[:ignore_dependencies] = true + + @cmd.install_gem File.join(@tempdir, spec.file_name), nil + + assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name } + end + def test_parses_requirement_from_gemname spec_fetcher do |fetcher| fetcher.gem 'a', 2 diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index 7537c1c9c10532..d259383ba2fbb2 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -217,6 +217,7 @@ def test_execute_dependencies end def test_execute_rdoc + skip if RUBY_VERSION <= "1.8.7" spec_fetcher do |fetcher| fetcher.gem 'a', 2 @@ -239,7 +240,6 @@ def test_execute_rdoc a2 = @specs['a-2'] - assert_path_exists File.join(a2.doc_dir, 'ri') assert_path_exists File.join(a2.doc_dir, 'rdoc') end diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 0a82fa63cbbd19..352ebbb54ff513 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -551,7 +551,7 @@ def test_install_env_shebang env = "/\\S+/env" unless Gem.win_platform? - assert_match %r|\A#!#{env} #{Gem::ConfigMap[:ruby_install_name]}\n|, + assert_match %r|\A#!#{env} #{RbConfig::CONFIG['ruby_install_name']}\n|, File.read(File.join(@gemhome, 'bin', 'a_bin')) end diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb index aa9008c7937d69..367c933a4cd6ad 100644 --- a/test/rubygems/test_gem_ext_ext_conf_builder.rb +++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb @@ -42,47 +42,46 @@ def test_class_build end def test_class_build_rbconfig_make_prog - configure_args = RbConfig::CONFIG['configure_args'] + configure_args do - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| - extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" - end + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" + end - output = [] + output = [] - Dir.chdir @ext do - Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output - end + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end - assert_equal "creating Makefile\n", output[1] - assert_contains_make_command 'clean', output[2] - assert_contains_make_command '', output[4] - assert_contains_make_command 'install', output[6] - ensure - RbConfig::CONFIG['configure_args'] = configure_args + assert_equal "creating Makefile\n", output[1] + assert_contains_make_command 'clean', output[2] + assert_contains_make_command '', output[4] + assert_contains_make_command 'install', output[6] + end end def test_class_build_env_make - configure_args, env_make = RbConfig::CONFIG['configure_args'], ENV.delete('make') - RbConfig::CONFIG['configure_args'] = '' + env_make = ENV.delete 'make' ENV['make'] = 'anothermake' - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| - extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" - end + configure_args '' do + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" + end - output = [] + output = [] - assert_raises Gem::InstallError do - Dir.chdir @ext do - Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end end - end - assert_equal "creating Makefile\n", output[1] - assert_contains_make_command 'clean', output[2] + assert_equal "creating Makefile\n", output[1] + assert_contains_make_command 'clean', output[2] + end ensure - RbConfig::CONFIG['configure_args'] = configure_args ENV['make'] = env_make end @@ -108,6 +107,7 @@ def test_class_build_extconf_fail assert_equal 'extconf failed, exit code 1', error.message assert_equal("#{Gem.ruby} extconf.rb", output[0]) + assert_path_exists File.join @dest_path, 'mkmf.log' end def test_class_build_unconventional @@ -188,5 +188,19 @@ def test_class_make_no_Makefile assert_equal 'Makefile not found', error.message end + def configure_args args = nil + configure_args = RbConfig::CONFIG['configure_args'] + RbConfig::CONFIG['configure_args'] = args if args + + yield + + ensure + if configure_args then + RbConfig::CONFIG['configure_args'] = configure_args + else + RbConfig::CONFIG.delete 'configure_args' + end + end + end diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 615a9b57ba4afa..eff62ab28b2886 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -41,7 +41,7 @@ def test_app_script_text if ARGV.first str = ARGV.first str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding - if str =~ /\\A_(.*)_\\z/ + if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then version = $1 ARGV.shift end @@ -84,8 +84,8 @@ def test_check_executable_overwrite_default_bin_dir orig_RUBY_FRAMEWORK_VERSION = RUBY_FRAMEWORK_VERSION Object.send :remove_const, :RUBY_FRAMEWORK_VERSION end - orig_bindir = Gem::ConfigMap[:bindir] - Gem::ConfigMap[:bindir] = Gem.bindir + orig_bindir = RbConfig::CONFIG['bindir'] + RbConfig::CONFIG['bindir'] = Gem.bindir util_conflict_executable false @@ -102,7 +102,11 @@ def test_check_executable_overwrite_default_bin_dir ensure Object.const_set :RUBY_FRAMEWORK_VERSION, orig_RUBY_FRAMEWORK_VERSION if orig_RUBY_FRAMEWORK_VERSION - Gem::ConfigMap[:bindir] = orig_bindir + if orig_bindir then + RbConfig::CONFIG['bindir'] = orig_bindir + else + RbConfig::CONFIG.delete 'bindir' + end end def test_check_executable_overwrite_format_executable @@ -1192,7 +1196,7 @@ def test_shebang_env_shebang env_shebang = "/usr/bin/env" unless Gem.win_platform? - assert_equal("#!#{env_shebang} #{Gem::ConfigMap[:ruby_install_name]}", + assert_equal("#!#{env_shebang} #{RbConfig::CONFIG['ruby_install_name']}", shebang) end diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb index 5d855435ec69f9..8f1f0c45619679 100644 --- a/test/rubygems/test_gem_package_tar_header.rb +++ b/test/rubygems/test_gem_package_tar_header.rb @@ -72,6 +72,20 @@ def test_initialize_bad end end + def test_initialize_typeflag + header = { + :mode => '', + :name => '', + :prefix => '', + :size => '', + :typeflag => '', + } + + tar_header = Gem::Package::TarHeader.new header + + assert_equal '0', tar_header.typeflag + end + def test_empty_eh refute_empty @tar_header diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index 5966710dad30b5..17577dc744a8de 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -116,7 +116,11 @@ def test_initialize_mswin32_vc6 assert_equal expected, platform.to_a, 'i386-mswin32 VC6' ensure - RbConfig::CONFIG['RUBY_SO_NAME'] = orig_RUBY_SO_NAME + if orig_RUBY_SO_NAME then + RbConfig::CONFIG['RUBY_SO_NAME'] = orig_RUBY_SO_NAME + else + RbConfig::CONFIG.delete 'RUBY_SO_NAME' + end end def test_initialize_platform diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 7e6d9c76934881..79f3a58bfb07ef 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -208,15 +208,15 @@ def util_fuck_with_fetcher data, blow = false fetcher.instance_variable_set :@test_data, data unless blow then - def fetcher.fetch_path arg + def fetcher.fetch_path arg, *rest @test_arg = arg @test_data end else - def fetcher.fetch_path arg + def fetcher.fetch_path arg, *rest # OMG I'm such an ass class << self; remove_method :fetch_path; end - def self.fetch_path arg + def self.fetch_path arg, *rest @test_arg = arg @test_data end diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb index 04ff50786f85c3..bcbbcf1f99ef6e 100644 --- a/test/rubygems/test_gem_request.rb +++ b/test/rubygems/test_gem_request.rb @@ -1,9 +1,16 @@ require 'rubygems/test_case' require 'rubygems/request' require 'ostruct' +require 'base64' class TestGemRequest < Gem::TestCase + CA_CERT_FILE = cert_path 'ca' + CHILD_CERT = load_cert 'child' + PUBLIC_CERT = load_cert 'public' + PUBLIC_CERT_FILE = cert_path 'public' + SSL_CERT = load_cert 'ssl' + def setup @proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] @old_proxies = @proxies.map {|k| ENV[k] } @@ -62,6 +69,44 @@ def test_initialize_proxy_ENV_https assert_equal URI(@proxy_uri), proxy end + def test_configure_connection_for_https + connection = Net::HTTP.new 'localhost', 443 + + request = Gem::Request.new URI('https://example'), nil, nil, nil + + def request.add_rubygems_trusted_certs store + store.add_cert TestGemRequest::PUBLIC_CERT + end + + request.configure_connection_for_https connection + + cert_store = connection.cert_store + + assert cert_store.verify CHILD_CERT + end + + def test_configure_connection_for_https_ssl_ca_cert + ssl_ca_cert, Gem.configuration.ssl_ca_cert = + Gem.configuration.ssl_ca_cert, CA_CERT_FILE + + connection = Net::HTTP.new 'localhost', 443 + + request = Gem::Request.new URI('https://example'), nil, nil, nil + + def request.add_rubygems_trusted_certs store + store.add_cert TestGemRequest::PUBLIC_CERT + end + + request.configure_connection_for_https connection + + cert_store = connection.cert_store + + assert cert_store.verify CHILD_CERT + assert cert_store.verify SSL_CERT + ensure + Gem.configuration.ssl_ca_cert = ssl_ca_cert + end + def test_get_proxy_from_env_fallback ENV['http_proxy'] = @proxy_uri @@ -124,6 +169,30 @@ def test_fetch assert_equal :junk, response.body end + def test_fetch_basic_auth + uri = URI.parse "https://user:pass@example.rubygems/specs.#{Gem.marshal_version}" + @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) + conn = util_stub_connection_for :body => :junk, :code => 200 + + @request.fetch + + auth_header = conn.payload['Authorization'] + + assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header + end + + def test_fetch_basic_auth_encoded + uri = URI.parse "https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}" + @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) + conn = util_stub_connection_for :body => :junk, :code => 200 + + @request.fetch + + auth_header = conn.payload['Authorization'] + + assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header + end + def test_fetch_head uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb index 82757958c82517..a5fcdcc2fb31f7 100644 --- a/test/rubygems/test_gem_request_set.rb +++ b/test/rubygems/test_gem_request_set.rb @@ -59,6 +59,8 @@ def test_install_from_gemdeps assert_includes installed, 'a-2' assert_path_exists File.join @gemhome, 'gems', 'a-2' assert_path_exists 'gem.deps.rb.lock' + + assert rs.remote end def test_install_from_gemdeps_install_dir @@ -89,6 +91,25 @@ def test_install_from_gemdeps_install_dir refute_path_exists File.join Gem.dir, 'gems', 'a-2' end + def test_install_from_gemdeps_local + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + io.flush + + assert_raises Gem::UnsatisfiableDependencyError do + rs.install_from_gemdeps :gemdeps => io.path, :domain => :local + end + end + + refute rs.remote + end + def test_install_from_gemdeps_lockfile spec_fetcher do |fetcher| fetcher.gem 'a', 1 diff --git a/test/rubygems/test_gem_request_set_lockfile.rb b/test/rubygems/test_gem_request_set_lockfile.rb index 9e0cab4d1a8f79..0be69bf92b30d4 100644 --- a/test/rubygems/test_gem_request_set_lockfile.rb +++ b/test/rubygems/test_gem_request_set_lockfile.rb @@ -218,6 +218,7 @@ def test_parse_gem_specs_dependency c (~> 4) d e (~> 5.0, >= 5.0.1) + b (3-x86_64-linux) PLATFORMS #{Gem::Platform::RUBY} @@ -238,7 +239,14 @@ def test_parse_gem_specs_dependency assert lockfile_set, 'could not find a LockSet' - assert_equal %w[a-2], lockfile_set.specs.map { |tuple| tuple.full_name } + assert_equal %w[a-2 b-3], lockfile_set.specs.map { |tuple| tuple.full_name } + + expected = [ + Gem::Platform::RUBY, + Gem::Platform.new('x86_64-linux'), + ] + + assert_equal expected, lockfile_set.specs.map { |tuple| tuple.platform } spec = lockfile_set.specs.first diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index 7d3311c14ce47a..c97e9e710cc0b4 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -33,6 +33,14 @@ def test_self_compatibility assert_same Gem::Resolver, Gem::DependencyResolver end + def test_self_compose_sets_best_set + best_set = @DR::BestSet.new + + composed = @DR.compose_sets best_set + + assert_equal best_set, composed + end + def test_self_compose_sets_multiple index_set = @DR::IndexSet.new vendor_set = @DR::VendorSet.new diff --git a/test/rubygems/test_gem_resolver_api_set.rb b/test/rubygems/test_gem_resolver_api_set.rb index 288f496c931ff8..245f6c1d24cad2 100644 --- a/test/rubygems/test_gem_resolver_api_set.rb +++ b/test/rubygems/test_gem_resolver_api_set.rb @@ -17,6 +17,14 @@ def test_initialize assert_equal Gem::Source.new(URI('https://rubygems.org')), set.source end + def test_initialize_deeper_uri + set = @DR::APISet.new 'https://rubygemsserver.com/mygems/api/v1/dependencies' + + assert_equal URI('https://rubygemsserver.com/mygems/api/v1/dependencies'), set.dep_uri + assert_equal URI('https://rubygemsserver.com/mygems/'), set.uri + assert_equal Gem::Source.new(URI('https://rubygemsserver.com/mygems/')), set.source + end + def test_initialize_uri set = @DR::APISet.new @dep_uri @@ -74,6 +82,15 @@ def test_find_all_cache assert_equal expected, set.find_all(a_dep) end + def test_find_all_local + set = @DR::APISet.new @dep_uri + set.remote = false + + a_dep = @DR::DependencyRequest.new dep('a'), nil + + assert_empty set.find_all(a_dep) + end + def test_find_all_missing spec_fetcher @@ -163,5 +180,29 @@ def test_prefetch_cache_missing set.prefetch [a_dep, b_dep] end + def test_prefetch_local + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a,b"] = Marshal.dump data + @fetcher.data["#{@dep_uri}?gems=b"] = Marshal.dump [] + + set = @DR::APISet.new @dep_uri + set.remote = false + + a_dep = @DR::DependencyRequest.new dep('a'), nil + b_dep = @DR::DependencyRequest.new dep('b'), nil + + set.prefetch [a_dep, b_dep] + + assert_empty set.instance_variable_get :@data + end + end diff --git a/test/rubygems/test_gem_resolver_best_set.rb b/test/rubygems/test_gem_resolver_best_set.rb index 5bcff4aca7d66e..2d16f8b701a88b 100644 --- a/test/rubygems/test_gem_resolver_best_set.rb +++ b/test/rubygems/test_gem_resolver_best_set.rb @@ -8,6 +8,12 @@ def setup @DR = Gem::Resolver end + def test_initialize + set = @DR::BestSet.new + + assert_empty set.sets + end + def test_find_all_index spec_fetcher do |fetcher| fetcher.spec 'a', 1 @@ -26,5 +32,49 @@ def test_find_all_index assert_equal %w[a-1], found.map { |s| s.full_name } end + def test_find_all_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::BestSet.new + set.remote = false + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_empty found + end + + def test_prefetch + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + + set.prefetch [] + + refute_empty set.sets + end + + def test_prefetch_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + set.remote = false + + set.prefetch [] + + assert_empty set.sets + end + end diff --git a/test/rubygems/test_gem_resolver_composed_set.rb b/test/rubygems/test_gem_resolver_composed_set.rb new file mode 100644 index 00000000000000..85026f7eb98f95 --- /dev/null +++ b/test/rubygems/test_gem_resolver_composed_set.rb @@ -0,0 +1,18 @@ +require 'rubygems/test_case' + +class TestGemResolverComposedSet < Gem::TestCase + + def test_remote_equals + best_set = Gem::Resolver::BestSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new best_set, current_set + + set.remote = false + + refute best_set.remote? + refute current_set.remote? + end + +end + diff --git a/test/rubygems/test_gem_resolver_git_set.rb b/test/rubygems/test_gem_resolver_git_set.rb index 4643624ee02eaa..f82b9427775ba7 100644 --- a/test/rubygems/test_gem_resolver_git_set.rb +++ b/test/rubygems/test_gem_resolver_git_set.rb @@ -70,6 +70,21 @@ def test_find_all assert_equal [@set.specs['a']], found end + def test_find_all_local + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + @set.remote = false + + dependency = dep 'a', '~> 1.0' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + assert_empty @set.find_all dependency + end + def test_root_dir assert_equal Gem.dir, @set.root_dir diff --git a/test/rubygems/test_gem_resolver_index_set.rb b/test/rubygems/test_gem_resolver_index_set.rb index 137e9b5cacabec..b0adc511c997e1 100644 --- a/test/rubygems/test_gem_resolver_index_set.rb +++ b/test/rubygems/test_gem_resolver_index_set.rb @@ -24,5 +24,40 @@ def test_initialize_source refute_same Gem::SpecFetcher.fetcher, fetcher end + def test_find_all + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::BestSet.new + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1], found.map { |s| s.full_name } + end + + def test_find_all_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::BestSet.new + set.remote = false + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + assert_empty set.find_all req + end + end diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb index af4db646a9ddeb..258f9bc8034669 100644 --- a/test/rubygems/test_gem_resolver_installer_set.rb +++ b/test/rubygems/test_gem_resolver_installer_set.rb @@ -2,6 +2,34 @@ class TestGemResolverInstallerSet < Gem::TestCase + def test_consider_local_eh + set = Gem::Resolver::InstallerSet.new :remote + + refute set.consider_local? + + set = Gem::Resolver::InstallerSet.new :both + + assert set.consider_local? + + set = Gem::Resolver::InstallerSet.new :local + + assert set.consider_local? + end + + def test_consider_remote_eh + set = Gem::Resolver::InstallerSet.new :remote + + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :both + + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :local + + refute set.consider_remote? + end + def test_load_spec specs = spec_fetcher do |fetcher| fetcher.spec 'a', 2 @@ -18,5 +46,47 @@ def test_load_spec assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name end + def test_remote_equals_both + set = Gem::Resolver::InstallerSet.new :both + set.remote = true + + assert set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :both + set.remote = false + + assert set.consider_local? + refute set.consider_remote? + end + + def test_remote_equals_local + set = Gem::Resolver::InstallerSet.new :local + set.remote = true + + assert set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :local + set.remote = false + + assert set.consider_local? + refute set.consider_remote? + end + + def test_remote_equals_remote + set = Gem::Resolver::InstallerSet.new :remote + set.remote = true + + refute set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :remote + set.remote = false + + refute set.consider_local? + refute set.consider_remote? + end + end diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb index 026492ece02efa..58bff844906c1b 100644 --- a/test/rubygems/test_gem_source_git.rb +++ b/test/rubygems/test_gem_source_git.rb @@ -27,6 +27,26 @@ def test_checkout assert_path_exists File.join @source.install_dir, 'a.gemspec' end + def test_checkout_local + @source.remote = false + + @source.checkout + + install_dir = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}" + + refute_path_exists File.join install_dir, 'a.gemspec' + end + + def test_checkout_local_cached + @source.cache + + @source.remote = false + + @source.checkout + + assert_path_exists File.join @source.install_dir, 'a.gemspec' + end + def test_checkout_submodules source = Gem::Source::Git.new @name, @repository, 'master', true @@ -54,6 +74,14 @@ def test_cache end end + def test_cache_local + @source.remote = false + + @source.cache + + refute_path_exists @source.repo_cache_dir + end + def test_dir_shortref @source.cache @@ -99,6 +127,12 @@ def test_install_dir assert_equal expected, @source.install_dir end + def test_install_dir_local + @source.remote = false + + assert_nil @source.install_dir + end + def test_repo_cache_dir expected = File.join Gem.dir, 'cache', 'bundler', 'git', "a-#{@hash}" @@ -211,6 +245,15 @@ def test_specs assert_equal extension_dir, b_spec.extension_dir end + def test_specs_local + source = Gem::Source::Git.new @name, @repository, 'master', true + source.remote = false + + capture_io do + assert_empty source.specs + end + end + def test_uri_hash assert_equal @hash, @source.uri_hash diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 7aa9d5aeb17a4a..1afb5ba247c414 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -999,8 +999,8 @@ def test_initialize_copy assert_equal 'summary', spec.summary assert_same spec.summary, new_spec.summary - assert_equal %w[lib/file.rb test/file.rb bin/exec README.txt - ext/extconf.rb].sort, + assert_equal %w[README.txt bin/exec ext/extconf.rb lib/file.rb + test/file.rb].sort, spec.files refute_same spec.files, new_spec.files, 'files' @@ -1109,7 +1109,31 @@ def test_bindir_equals_nil @a2.executable = 'app' assert_equal nil, @a2.bindir - assert_equal %w[lib/code.rb app].sort, @a2.files + assert_equal %w[app lib/code.rb].sort, @a2.files + end + + def test_extensions_equals_nil + @a2.instance_variable_set(:@extensions, nil) + assert_equal nil, @a2.instance_variable_get(:@extensions) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_test_files_equals_nil + @a2.instance_variable_set(:@test_files, nil) + assert_equal nil, @a2.instance_variable_get(:@test_files) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_executables_equals_nil + @a2.instance_variable_set(:@executables, nil) + assert_equal nil, @a2.instance_variable_get(:@executables) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_extra_rdoc_files_equals_nil + @a2.instance_variable_set(:@extra_rdoc_files, nil) + assert_equal nil, @a2.instance_variable_get(:@extra_rdoc_files) + assert_equal %w[lib/code.rb], @a2.files end def test_build_extensions @@ -1437,7 +1461,7 @@ def test_executables def test_executable_equals @a2.executable = 'app' assert_equal 'app', @a2.executable - assert_equal %w[lib/code.rb bin/app].sort, @a2.files + assert_equal %w[bin/app lib/code.rb].sort, @a2.files end def test_extensions @@ -1765,26 +1789,39 @@ def test_prerelease_spec_adds_required_rubygems_version end def test_require_paths - enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = - RbConfig::CONFIG['ENABLE_SHARED'], 'no' + enable_shared 'no' do + ext_spec - ext_spec - - @ext.require_path = 'lib' + @ext.require_path = 'lib' - ext_install_dir = Pathname(@ext.extension_dir) - full_gem_path = Pathname(@ext.full_gem_path) - relative_install_dir = ext_install_dir.relative_path_from full_gem_path + ext_install_dir = Pathname(@ext.extension_dir) + full_gem_path = Pathname(@ext.full_gem_path) + relative_install_dir = ext_install_dir.relative_path_from full_gem_path - assert_equal [relative_install_dir.to_s, 'lib'], @ext.require_paths - ensure - RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + assert_equal [relative_install_dir.to_s, 'lib'], @ext.require_paths + end end def test_source assert_kind_of Gem::Source::Installed, @a1.source end + def test_source_paths + ext_spec + + @ext.require_paths = %w[lib ext foo] + @ext.extensions << 'bar/baz' + + expected = %w[ + lib + ext + foo + bar + ] + + assert_equal expected, @ext.source_paths + end + def test_full_require_paths ext_spec @@ -2435,7 +2472,7 @@ def test_validate_files assert_equal '["lib2"] are not files', e.message end - assert_equal %w[lib/code.rb test/suite.rb bin/exec ext/a/extconf.rb lib2].sort, + assert_equal %w[bin/exec ext/a/extconf.rb lib/code.rb lib2 test/suite.rb].sort, @a1.files end @@ -2911,9 +2948,9 @@ def util_setup_validate def with_syck begin + verbose, $VERBOSE = $VERBOSE, nil require "yaml" old_engine = YAML::ENGINE.yamler - verbose, $VERBOSE = $VERBOSE, nil YAML::ENGINE.yamler = 'syck' load 'rubygems/syck_hack.rb' rescue NameError diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index 1eea30fb9403d6..11fdaf68e22118 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -131,6 +131,23 @@ def test_remove_executables_user_format_disabled Gem::Installer.exec_format = nil end + def test_remove_not_in_home + uninstaller = Gem::Uninstaller.new nil, :install_dir => "#{@gemhome}2" + + e = assert_raises Gem::GemNotInHomeException do + use_ui ui do + uninstaller.remove @spec + end + end + + expected = + "Gem '#{@spec.full_name}' is not installed in directory #{@gemhome}2" + + assert_equal expected, e.message + + assert_path_exists @spec.gem_dir + end + def test_path_ok_eh uninstaller = Gem::Uninstaller.new nil diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index e0499fe73f9783..5a65b5c9c7b506 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -3,6 +3,9 @@ class TestGemVersion < Gem::TestCase + class V < ::Gem::Version + end + def test_bump assert_bumped_version_equal "5.3", "5.2.4" end @@ -37,6 +40,13 @@ def test_class_create assert_equal v('1.1'), Gem::Version.create(ver) end + def test_class_new_subclass + v1 = Gem::Version.new '1' + v2 = V.new '1' + + refute_same v1, v2 + end + def test_eql_eh assert_version_eql "1.2", "1.2" refute_version_eql "1.2", "1.2.0" diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb index 38d8333f2a0669..f10c5efaf84018 100644 --- a/test/socket/test_unix.rb +++ b/test/socket/test_unix.rb @@ -5,6 +5,7 @@ require "test/unit" require "tempfile" +require "timeout" require "tmpdir" require "thread" require "io/nonblock" @@ -369,6 +370,28 @@ def test_dgram_pair s2.close if s2 end + def test_dgram_pair_sendrecvmsg_errno_set + s1, s2 = to_close = UNIXSocket.pair(Socket::SOCK_DGRAM) + pipe = IO.pipe + to_close.concat(pipe) + set_errno = lambda do + begin + pipe[0].read_nonblock(1) + fail + rescue => e + assert(IO::EAGAINWaitReadable === e) + end + end + Timeout.timeout(10) do + set_errno.call + assert_equal(2, s1.sendmsg("HI")) + set_errno.call + assert_equal("HI", s2.recvmsg[0]) + end + ensure + to_close.each(&:close) if to_close + end + def test_epipe # [ruby-dev:34619] s1, s2 = UNIXSocket.pair s1.shutdown(Socket::SHUT_WR) diff --git a/test/test_delegate.rb b/test/test_delegate.rb index ca65ef3daadb52..6270cc61b6e45d 100644 --- a/test/test_delegate.rb +++ b/test/test_delegate.rb @@ -180,4 +180,61 @@ def test_global_method_if_no_target x = assert_nothing_raised(ArgumentError, bug9155) {break Bug9155.new(1)} assert_equal(1, x.to_i, bug9155) end + + class Bug9403 + Name = '[ruby-core:59718] [Bug #9403]' + SD = SimpleDelegator.new(new) + class << SD + def method_name + __method__ + end + def callee_name + __callee__ + end + alias aliased_name callee_name + def dir_name + __dir__ + end + end + dc = DelegateClass(self) + dc.class_eval do + def method_name + __method__ + end + def callee_name + __callee__ + end + alias aliased_name callee_name + def dir_name + __dir__ + end + end + DC = dc.new(new) + end + + def test_method_in_simple_delegator + assert_equal(:method_name, Bug9403::SD.method_name, Bug9403::Name) + end + + def test_callee_in_simple_delegator + assert_equal(:callee_name, Bug9403::SD.callee_name, Bug9403::Name) + assert_equal(:aliased_name, Bug9403::SD.aliased_name, Bug9403::Name) + end + + def test_dir_in_simple_delegator + assert_equal(__dir__, Bug9403::SD.dir_name, Bug9403::Name) + end + + def test_method_in_delegator_class + assert_equal(:method_name, Bug9403::DC.method_name, Bug9403::Name) + end + + def test_callee_in_delegator_class + assert_equal(:callee_name, Bug9403::DC.callee_name, Bug9403::Name) + assert_equal(:aliased_name, Bug9403::DC.aliased_name, Bug9403::Name) + end + + def test_dir_in_delegator_class + assert_equal(__dir__, Bug9403::DC.dir_name, Bug9403::Name) + end end diff --git a/test/test_weakref.rb b/test/test_weakref.rb index 85820b17b8af70..f12e943423c61c 100644 --- a/test/test_weakref.rb +++ b/test/test_weakref.rb @@ -19,9 +19,14 @@ def test_ref end def test_recycled - weak = make_weakref - ObjectSpace.garbage_collect - ObjectSpace.garbage_collect + weaks = [] + weak = nil + 100.times do + weaks << make_weakref + ObjectSpace.garbage_collect + ObjectSpace.garbage_collect + break if weak = weaks.find {|w| !w.weakref_alive?} + end assert_raise(WeakRef::RefError) {weak.to_s} assert_not_predicate(weak, :weakref_alive?) end diff --git a/test/thread/test_queue.rb b/test/thread/test_queue.rb index 438e1e75e3edd4..c99475d8dc872d 100644 --- a/test/thread/test_queue.rb +++ b/test/thread/test_queue.rb @@ -55,6 +55,13 @@ def test_sized_queue_assign_max assert_equal(1, q.max) assert_raise(ArgumentError) { q.max = -1 } assert_equal(1, q.max) + + before = q.max + q.max.times { q << 1 } + t1 = Thread.new { q << 1 } + sleep 0.01 until t1.stop? + q.max = q.max + 1 + assert_equal before + 1, q.max end def test_queue_pop_interrupt @@ -122,6 +129,28 @@ def test_queue_clear_return_value assert_same q, retval end + def test_sized_queue_clear + # Fill queue, then test that SizedQueue#clear wakes up all waiting threads + sq = SizedQueue.new(2) + 2.times { sq << 1 } + + t1 = Thread.new do + sq << 1 + end + + t2 = Thread.new do + sq << 1 + end + + t3 = Thread.new do + Thread.pass + sq.clear + end + + [t3, t2, t1].each(&:join) + assert_equal sq.length, 2 + end + def test_sized_queue_push_return_value q = SizedQueue.new(1) retval = q.push(1) diff --git a/thread_pthread.c b/thread_pthread.c index 57daa3b45d06a9..aa8962a315fc5f 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1423,7 +1423,7 @@ timer_thread_sleep(rb_global_vm_lock_t* unused) #if defined(__linux__) && defined(PR_SET_NAME) # define SET_THREAD_NAME(name) prctl(PR_SET_NAME, name) -#elif defined(__APPLE__) +#elif defined(HAVE_PTHREAD_SETNAME_NP) /* pthread_setname_np() on Darwin does not have target thread argument */ # define SET_THREAD_NAME(name) pthread_setname_np(name) #else @@ -1479,17 +1479,16 @@ rb_thread_create_timer_thread(void) exit(EXIT_FAILURE); } # ifdef PTHREAD_STACK_MIN - if (PTHREAD_STACK_MIN < 4096 * 3) { + { + const size_t min_size = (4096 * 4); /* Allocate the machine stack for the timer thread - * at least 12KB (3 pages). FreeBSD 8.2 AMD64 causes - * machine stack overflow only with PTHREAD_STACK_MIN. + * at least 16KB (4 pages). FreeBSD 8.2 AMD64 causes + * machine stack overflow only with PTHREAD_STACK_MIN. */ - pthread_attr_setstacksize(&attr, - 4096 * 3 + (THREAD_DEBUG ? BUFSIZ : 0)); - } - else { - pthread_attr_setstacksize(&attr, - PTHREAD_STACK_MIN + (THREAD_DEBUG ? BUFSIZ : 0)); + size_t stack_size = PTHREAD_STACK_MIN; /* may be dynamic, get only once */ + if (stack_size < min_size) stack_size = min_size; + if (THREAD_DEBUG) stack_size += BUFSIZ; + pthread_attr_setstacksize(&attr, stack_size); } # endif #endif diff --git a/variable.c b/variable.c index 350bb582db343b..424730dcb9dced 100644 --- a/variable.c +++ b/variable.c @@ -2517,8 +2517,9 @@ cvar_list(void *data) * class Two < One * @@var2 = 2 * end - * One.class_variables #=> [:@@var1] - * Two.class_variables #=> [:@@var2, :@@var1] + * One.class_variables #=> [:@@var1] + * Two.class_variables #=> [:@@var2, :@@var1] + * Two.class_variables(false) #=> [:@@var2] */ VALUE diff --git a/version.h b/version.h index a26d675eb9b3d9..e8e07e0109357e 100644 --- a/version.h +++ b/version.h @@ -1,10 +1,10 @@ #define RUBY_VERSION "2.1.1" -#define RUBY_RELEASE_DATE "2013-12-31" -#define RUBY_PATCHLEVEL 0 +#define RUBY_RELEASE_DATE "2014-02-24" +#define RUBY_PATCHLEVEL 76 -#define RUBY_RELEASE_YEAR 2013 -#define RUBY_RELEASE_MONTH 12 -#define RUBY_RELEASE_DAY 31 +#define RUBY_RELEASE_YEAR 2014 +#define RUBY_RELEASE_MONTH 2 +#define RUBY_RELEASE_DAY 24 #include "ruby/version.h" diff --git a/vm_insnhelper.c b/vm_insnhelper.c index eb3ba3762334ce..1228b3f4df6976 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1829,7 +1829,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) ci->me = me; ci->defined_class = defined_class; if (me->def->type != VM_METHOD_TYPE_REFINED) { - goto normal_method_dispatch; + goto start_method_dispatch; } } @@ -1838,11 +1838,8 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) ci->me = ci->me->def->body.orig_me; if (UNDEFINED_METHOD_ENTRY_P(ci->me)) { ci->me = 0; - goto start_method_dispatch; - } - else { - goto normal_method_dispatch; } + goto start_method_dispatch; } else { klass = ci->me->klass; @@ -2004,7 +2001,8 @@ vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_inf current_defined_class = RCLASS_REFINED_CLASS(current_defined_class); } - if (!FL_TEST(current_defined_class, RMODULE_INCLUDED_INTO_REFINEMENT) && + if (BUILTIN_TYPE(current_defined_class) != T_MODULE && + !FL_TEST(current_defined_class, RMODULE_INCLUDED_INTO_REFINEMENT) && !rb_obj_is_kind_of(ci->recv, current_defined_class)) { VALUE m = RB_TYPE_P(current_defined_class, T_ICLASS) ? RBASIC(current_defined_class)->klass : current_defined_class; diff --git a/vm_method.c b/vm_method.c index ac3afafe69afac..5c26770ccf577f 100644 --- a/vm_method.c +++ b/vm_method.c @@ -316,6 +316,7 @@ make_method_entry_refined(rb_method_entry_t *me) *new_def->body.orig_me = *me; rb_vm_check_redefinition_opt_method(me, me->klass); if (me->def) me->def->alias_count++; + me->flag = NOEX_WITH_SAFE(NOEX_PUBLIC); me->def = new_def; } diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 305f37df5569ee..d6289bc53d381f 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -677,7 +677,6 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub #define HAVE_GETCWD 1 #define HAVE_TRUNCATE 1 #define HAVE_FTRUNCATE 1 -#define HAVE_FSEEKO 1 #define HAVE_TIMES 1 #define HAVE_FCNTL 1 #define HAVE_LINK 1 @@ -1034,14 +1033,17 @@ $(RCFILES): $(RBCONFIG) $(srcdir)/revision.h $(srcdir)/win32/resource.rb -so_name=$(RUBY_SO_NAME) \ . $(icondirs) $(win_srcdir) -$(arch)-fake.rb: $(MKFILES) +$(arch)-fake.rb: $(MKFILES) $(srcdir)/version.h @echo Creating <<$@ class Object + remove_const :CROSS_COMPILING if defined?(CROSS_COMPILING) CROSS_COMPILING = RUBY_PLATFORM remove_const :RUBY_PLATFORM remove_const :RUBY_VERSION + remove_const :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION) RUBY_PLATFORM = "$(arch)" - RUBY_VERSION = "$(MAJOR).$(MINOR).$(TEENY)" + RUBY_VERSION = $(RUBY_PROGRAM_VERSION) + RUBY_DESCRIPTION = "ruby #{RUBY_VERSION} (" + $(RUBY_PROGRAM_RELEASE_DATE) + ") [#{RUBY_PLATFORM}]" end class File remove_const :ALT_SEPARATOR diff --git a/win32/setup.mak b/win32/setup.mak index 458212bb7bb680..b6358e5dd537b5 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -117,6 +117,8 @@ int main(void) {return (EnumProcesses(NULL,0,NULL) ? 0 : 1);} MAJOR = RUBY_API_VERSION_MAJOR MINOR = RUBY_API_VERSION_MINOR TEENY = RUBY_API_VERSION_TEENY +RUBY_PROGRAM_VERSION = RUBY_VERSION +RUBY_PROGRAM_RELEASE_DATE = RUBY_RELEASE_DATE MSC_VER = _MSC_VER << diff --git a/win32/win32.c b/win32/win32.c index 9cbd07f6697a97..2c888ae4c4a192 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -6965,7 +6965,7 @@ rb_w32_fd_is_text(int fd) return _osfile(fd) & FTEXT; } -#if RUBY_MSVCRT_VERSION < 80 && !defined(__MINGW64__) +#if RUBY_MSVCRT_VERSION < 80 && !defined(HAVE__GMTIME64_S) /* License: Ruby's */ static int unixtime_to_systemtime(const time_t t, SYSTEMTIME *st) @@ -7027,7 +7027,11 @@ systemtime_to_localtime(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *gst, SYSTEMTIME * } #endif -#ifdef __MINGW64__ +#ifdef HAVE__GMTIME64_S +# ifndef HAVE__LOCALTIME64_S +/* assume same as _gmtime64_s() */ +# define HAVE__LOCALTIME64_S 1 +# endif # ifndef MINGW_HAS_SECURE_API _CRTIMP errno_t __cdecl _gmtime64_s(struct tm* tm, const __time64_t *time); _CRTIMP errno_t __cdecl _localtime64_s(struct tm* tm, const __time64_t *time); @@ -7046,7 +7050,7 @@ gmtime_r(const time_t *tp, struct tm *rp) errno = e; return NULL; } -#if RUBY_MSVCRT_VERSION >= 80 || defined(__MINGW64__) +#if RUBY_MSVCRT_VERSION >= 80 || defined(HAVE__GMTIME64_S) e = gmtime_s(rp, tp); if (e != 0) goto error; #else @@ -7070,7 +7074,7 @@ localtime_r(const time_t *tp, struct tm *rp) errno = e; return NULL; } -#if RUBY_MSVCRT_VERSION >= 80 || defined(__MINGW64__) +#if RUBY_MSVCRT_VERSION >= 80 || defined(HAVE__LOCALTIME64_S) e = localtime_s(rp, tp); if (e) goto error; #else