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

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

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


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy