summaryrefslogtreecommitdiff
path: root/spec/ruby/core/complex/conj_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/complex/conj_spec.rb')
0 files changed, 0 insertions, 0 deletions
99.8%;'/> -rw-r--r--array.c9
-rw-r--r--bcc32/Makefile.sub26
-rw-r--r--bcc32/setup.mak14
-rw-r--r--bignum.c161
-rw-r--r--configure.in67
-rw-r--r--defines.h9
-rw-r--r--distruby.rb32
-rw-r--r--dln.c29
-rw-r--r--error.c14
-rw-r--r--eval.c51
-rw-r--r--ext/Win32API/Win32API.c2
-rw-r--r--ext/Win32API/lib/win32/registry.rb2
-rw-r--r--ext/Win32API/lib/win32/resolv.rb2
-rw-r--r--ext/bigdecimal/bigdecimal.c59
-rw-r--r--ext/bigdecimal/extconf.rb10
-rw-r--r--ext/curses/extconf.rb2
-rw-r--r--ext/dl/dl.c2
-rw-r--r--ext/dl/lib/dl/win32.rb2
-rw-r--r--ext/dl/ptr.c41
-rw-r--r--ext/dl/sym.c2
-rw-r--r--ext/etc/etc.c2
-rw-r--r--ext/extmk.rb70
-rw-r--r--ext/iconv/iconv.c5
-rw-r--r--ext/openssl/lib/net/ftptls.rb10
-rw-r--r--ext/openssl/lib/net/telnets.rb3
-rw-r--r--ext/openssl/lib/openssl/ssl.rb2
-rw-r--r--ext/openssl/ossl.h1
-rw-r--r--ext/openssl/ossl_config.c5
-rw-r--r--ext/openssl/ossl_pkcs5.h6
-rw-r--r--ext/openssl/ossl_x509name.c4
-rw-r--r--ext/pty/lib/expect.rb2
-rw-r--r--ext/pty/pty.c5
-rw-r--r--ext/readline/extconf.rb5
-rw-r--r--ext/readline/readline.c19
-rw-r--r--ext/sdbm/_sdbm.c2
-rw-r--r--ext/socket/getnameinfo.c5
-rw-r--r--ext/socket/socket.c23
-rw-r--r--ext/stringio/stringio.c20
-rw-r--r--ext/syck/syck.h2
-rw-r--r--ext/tk/tcltklib.c11
-rw-r--r--ext/win32ole/win32ole.c40
-rw-r--r--file.c253
-rw-r--r--gc.c61
-rw-r--r--hash.c61
-rw-r--r--intern.h1
-rw-r--r--io.c72
-rw-r--r--lib/README2
-rw-r--r--lib/base64.rb2
-rw-r--r--lib/benchmark.rb7
-rw-r--r--lib/cgi.rb11
-rw-r--r--lib/cgi/session.rb16
-rw-r--r--lib/irb.rb18
-rw-r--r--lib/mkmf.rb16
-rw-r--r--lib/monitor.rb21
-rw-r--r--lib/net/http.rb3
-rw-r--r--lib/net/imap.rb11
-rw-r--r--lib/net/telnet.rb2
-rw-r--r--lib/open-uri.rb10
-rw-r--r--lib/optparse.rb2
-rw-r--r--lib/rdoc/options.rb4
-rw-r--r--lib/rdoc/parsers/parse_c.rb2
-rw-r--r--lib/resolv.rb2
-rw-r--r--lib/rexml/dtd/dtd.rb2
-rw-r--r--lib/rexml/encodings/CP-1252.rb110
-rw-r--r--lib/rexml/encodings/ISO-8859-15.rb50
-rw-r--r--lib/rexml/encodings/SHIFT-JIS.rb4
-rw-r--r--lib/rexml/source.rb2
-rw-r--r--lib/rinda/tuplespace.rb13
-rw-r--r--lib/timeout.rb23
-rw-r--r--lib/uri/common.rb2
-rw-r--r--lib/uri/generic.rb3
-rw-r--r--lib/webrick/httpservlet/abstract.rb2
-rw-r--r--lib/webrick/httpservlet/cgi_runner.rb4
-rw-r--r--lib/webrick/httpservlet/filehandler.rb71
-rw-r--r--lib/xmlrpc/client.rb7
-rw-r--r--lib/xmlrpc/parser.rb4
-rw-r--r--lib/xmlrpc/server.rb6
-rw-r--r--lib/xmlrpc/utils.rb2
-rw-r--r--marshal.c10
-rw-r--r--misc/ruby-mode.el2
-rw-r--r--missing/isinf.c7
-rw-r--r--missing/strftime.c58
-rw-r--r--numeric.c160
-rw-r--r--object.c22
-rw-r--r--parse.y56
-rw-r--r--process.c118
-rw-r--r--random.c5
-rw-r--r--range.c5
-rw-r--r--regex.c37
-rw-r--r--ruby.c204
-rw-r--r--sample/test.rb5
-rw-r--r--signal.c22
-rw-r--r--sprintf.c67
-rw-r--r--string.c2
-rw-r--r--struct.c7
-rw-r--r--test/rinda/test_rinda.rb14
-rw-r--r--test/ruby/test_beginendblock.rb12
-rw-r--r--test/ruby/test_bignum.rb8
-rw-r--r--test/ruby/test_hash.rb564
-rw-r--r--test/ruby/test_marshal.rb20
-rw-r--r--test/ruby/test_method.rb11
-rw-r--r--test/ruby/test_system.rb5
-rw-r--r--test/webrick/.htaccess1
-rw-r--r--test/webrick/test_cgi.rb9
-rw-r--r--test/webrick/test_filehandler.rb135
-rw-r--r--test/webrick/utils.rb12
-rwxr-xr-xtest/webrick/webrick_long_filename.cgi36
-rw-r--r--time.c9
-rw-r--r--util.c4
-rw-r--r--variable.c11
-rw-r--r--version.h12
-rw-r--r--win32/Makefile.sub8
-rw-r--r--win32/mkexports.rb15
-rw-r--r--win32/setup.mak2
-rw-r--r--win32/win32.c166
-rw-r--r--win32/win32.h1
-rw-r--r--wince/setup.mak2
119 files changed, 3481 insertions, 950 deletions
diff --git a/ChangeLog b/ChangeLog
index 39fba3ca8d..a9f565dbb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,926 @@
+Sun Jun 15 20:28:45 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/resolv.rb (Resolv::Hosts): should not use win32/resolv on cygwin.
+ [ruby-dev:29945], [ruby-dev:34095]
+
+ * lib/win32/registry.rb (Win32::Registry.expand_environ): try upcased
+ name too for cygwin. [ruby-dev:29945]
+
+ * lib/win32/resolv.rb (Win32::Resolv.get_hosts_path): use expand_path.
+
+Sun Jun 15 20:27:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * misc/ruby-mode.el (ruby-mode): should use `run-mode-hooks' instead
+ of calling `run-hooks' directly to run the mode hook. patch from
+ Chiyuan Zhang <pluskid AT gmail.com> in [ruby-core:15915]
+
+Sun Jun 15 20:07:30 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * numeric.c (fix_coerce): try conversion before type check.
+ [ruby-core:15838]
+
+Sun Jun 15 19:55:46 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (BIGZEROP): fix for longer Bignum zeros. [ruby-Bugs-17454]
+
+Sun Jun 15 19:53:16 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (big2str_find_n1): check integer overflow.
+
+Sun Jun 15 19:51:37 2008 Tanaka Akira <akr@fsij.org>
+
+ * gc.c (STACK_LENGTH) [SPARC] : 0x80 offset removed. [ruby-dev:33857]
+
+Sun Jun 15 19:49:10 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/readline/readline.c (readline_event): prevent polling. based on
+ a patch from error errorsson in [ruby-Bugs-17675].
+
+Sun Jun 15 19:24:42 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (yycompile): clear ruby_eval_tree_begin if parse failed.
+
+Sun Jun 15 19:23:23 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (yycompile): clear ruby_eval_tree_begin too before parse.
+
+Sun Jun 15 19:21:26 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/pty/lib/expect.rb (IO#expect): check if peer is closed.
+ [ruby-Bugs-17940]
+
+Sun Jun 15 19:19:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/iconv/iconv.c (iconv_convert): check upper bound. a patch from
+ Daniel Luz at [ruby-Bugs-17910].
+
+Sun Jun 15 19:07:41 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (ftruncate): check if available.
+
+ * file.c (rb_file_truncate): check if ftruncate instead of truncate.
+
+Sun Jun 15 18:59:04 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (sigsetmask): check when signal semantics is not POSIX.
+
+ * signal.c (USE_TRAP_MASK): set true if sigprocmask or sigsetmask is
+ available.
+
+Sat Jun 14 16:12:17 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/timeout.rb (Timeout::timeout): made sensitive to location on the
+ stack. [ruby-core:15458]
+
+Fri Jun 13 13:10:12 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/dl/ptr.c (dlmem_each_i): typo fixed. a patch from IKOMA
+ Yoshiki <ikoma@mb.i-chubu.ne.jp> in [ruby-dev:33776].
+
+Fri Jun 13 12:10:58 2008 URABE Shyouhei <shyouhei@ice.uec.ac.jp>
+
+ * gc.c (rb_newobj): prohibit call of rb_newobj() during gc.
+ Submitted by Sylvain Joyeux [ruby-core:12099].
+
+ * ext/dl/ptr.c: do not use LONG2NUM() inside dlptr_free().
+ Slightly modified fix bassed on a patch by Sylvain Joyeux
+ [ruby-core:12099] [ ruby-bugs-11859 ] [ ruby-bugs-11882 ]
+ [ ruby-patches-13151 ].
+
+Fri Jun 13 12:09:02 2008 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * lib/benchmark.rb (Job::Benchmark#item): fix typo.
+
+Fri Jun 13 12:03:31 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_to_f): use strtod() for more
+ precision. [ruby-talk:290296]
+
+ * ext/bigdecimal/bigdecimal.c (BASE_FIG): made constant.
+
+ * ext/bigdecimal/extconf.rb: ditto. [ruby-dev:33658]
+
+Fri Jun 13 11:58:34 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/irb.rb (IRB::Irb::eval_input): rescues Interrupt and other than
+ SystemExit and SignalException. [ruby-core:15359]
+
+Fri Jun 13 11:56:28 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/benchmark.rb (Benchmark::realtime): make Benchmark#realtime
+ a bit faster. a patch from Alexander Dymo <dymo@ukrpost.ua> in
+ [ruby-core:15337].
+
+Fri Jun 13 11:42:52 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * io.c (rb_open_file): should check NUL in path.
+ <http://www.rubyist.net/~matz/20080125.html#c01>.
+
+ * io.c (rb_io_s_popen): ditto.
+
+ * io.c (rb_io_reopen): ditto.
+
+ * io.c (next_argv): ditto.
+
+ * io.c (rb_io_s_foreach): ditto.
+
+ * io.c (rb_io_s_readlines): ditto.
+
+ * io.c (rb_io_s_read): ditto.
+
+Wed Jun 11 15:06:00 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/uri/generic.rb (URI::Generic::inspect): use Kernel#to_s instead
+ object_id with printf. [ruby-dev:33347]
+
+Wed Jun 11 14:58:49 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in: Remove wrong assumptions about Cygwin. a patch from
+ Corinna Vinschen in [ruby-Bugs-17018].
+
+Mon Jun 9 18:03:32 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (eval): check if backtrace is empty. [ruby-core:15040]
+
+Sun Jun 8 06:07:02 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (rb_define_alloc_func, rb_undef_alloc_func): should
+ define/undef on a signleton class. [ruby-core:09959]
+
+Sun Jun 8 06:03:45 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * time.c (time_arg): use converted object. [ruby-core:14759]
+
+Sun Jun 8 06:01:25 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * io.c (fptr_finalize): clear errno first. [ruby-talk:284492]
+
+Sun Jun 8 05:53:46 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (TIMEZONE_VOID): check whether timezone requires zero
+ arguments. [ruby-dev:32631]
+
+Sun Jun 8 05:35:32 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (f_rest_arg): check if duplicated. [ruby-core:14140]
+
+Sun Jun 8 05:21:46 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (RUBY_CHECK_VARTYPE): check if a variable is defined
+ and its type.
+
+ * configure.in (timezone, altzone): check for recent cygwin.
+
+ * missing/strftime.c (strftime): fix for timezone. [ruby-dev:32536]
+
+ * lib/mkmf.rb (try_var): should fail for functions.
+
+ * ext/readline/extconf.rb: should use have_func for functions instead
+ of have_var.
+
+Sun Jun 8 05:09:29 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/uri/common.rb (URI::REGEXP::PATTERN): typo in REG_NAME
+ regular expression. a patch from Ueda Satoshi
+ <s-ueda AT livedoor.jp>. [ruby-dev:32514]
+
+Sun Jun 8 05:05:05 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/cgi.rb (read_multipart): exclude blanks from header values.
+ [ruby-list:44327]
+
+Sun Jun 8 05:00:44 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (rb_cstr_to_inum): trailing spaces may exist at sqeezing
+ preceeding 0s. [ruby-core:13873]
+
+Sun Jun 8 04:56:55 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (error_print): put newline unless multiple line message ends
+ with a newline. [ruby-dev:32429]
+
+Sun Jun 8 04:54:36 2008 James Edward Gray II <jeg2@ruby-lang.org>
+
+ Merged 14070 from trunk.
+
+ * lib/xmlrpc/server.rb (XMLRPC::Server#server): Improve signal handling so
+ pressing control-c in the controlling terminal or sending SIGTERM stops
+ the XML-RPC server.
+
+Sun Jun 8 04:46:45 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (newline_node): set line from outermost node before removing
+ NODE_BEGIN. [ruby-dev:32406]
+
+Sun Jun 8 04:37:34 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (stmt): remove unnecessary NODE_BEGIN. [ruby-core:13814]
+
+Sun Jun 8 04:18:50 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * object.c (nil_plus): remove unused function. [ruby-core:13737]
+
+Sun Jun 8 04:15:40 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (rb_alias): do not call hook functions until initialization
+ finishes. [ruby-talk:279538]
+
+Sun Jun 8 04:12:50 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
+
+ * ext/win32ole/win32ole.c (ole_invoke): bug fix. [ruby-talk:279100]
+
+Sun Jun 8 03:54:52 2008 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * ext/curses/extconf.rb: check macro if cannot find func.
+ [ruby-list:44224]
+
+Sun Jun 8 03:50:40 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/cgi/session.rb (CGI::Session::FileStore::restore): use
+ lockfile for exclusive locks. a patch from <tommy AT tmtm.org>.
+ [ruby-dev:32296]
+
+Sun Jun 8 03:46:55 2008 Tanaka Akira <akr@fsij.org>
+
+ * missing/isinf.c (isinf): don't define if the macro is defined.
+
+Sun Jun 8 03:34:23 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * numeric.c (round): fallback definition.
+
+ * numeric.c (flo_divmod, flo_round): use round() always.
+ [ruby-dev:32269]
+
+Sun Jun 8 03:34:23 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * numeric.c (flodivmod): work around for infinity.
+
+ * numeric.c (flo_divmod): work around for platforms have no round().
+ [ruby-dev:32247]
+
+Sun Jun 8 03:34:23 2008 URABE Shyouhei <shyouhei@ice.uec.ac.jp>
+
+ * numeric.c (flo_divmod): round to the nearest integer.
+ [ ruby-Bugs-14540 ]
+
+Sun Jun 8 03:08:11 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/rexml/encodings/SHIFT-JIS.rb (REXML::Encoding): place -x for
+ nkf conversion. a patch from <moonwolf AT moonwolf.com>.
+ [ruby-dev:32183]
+
+Sun Jun 8 03:05:59 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/optparse.rb (OptionParser::Switch::summarize): fix for long form
+ option with very long argument. a patch from Kobayashi Noritada
+ <nori1 AT dolphin.c.u-tokyo.ac.jp> in [ruby-list:44179].
+
+Sun Jun 8 03:03:27 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * numeric.c (fix_pow): returns infinity for 0**-1. [ruby-dev:32084]
+
+Sun Jun 8 02:57:32 2008 James Edward Gray II <jeg2@ruby-lang.org>
+
+ Merged 13781 from trunk.
+
+ * lib/net/telnet.rb (Net::Telnet#login): Allowing "passphrase" in
+ addition to "password" for Telnet login prompts. [ruby-Bugs-10746]
+
+Wed Oct 25 06:46:21 2007 James Edward Gray II <jeg2@ruby-lang.org>
+
+ Merged 13779 from trunk.
+
+ * lib/net/telnet.rb (Net::Telnet#login): Making the password prompt
+ pattern case insensitive. [ruby-Bugs-10746]
+
+Sun Jun 8 02:54:30 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * io.c (rb_io_tell, rb_io_seek): check errno too. [ruby-dev:32093]
+
+Sun Jun 8 01:51:52 2008 James Edward Gray II <jeg2@ruby-lang.org>
+
+ Merged 13767, 13768, 13769, and 13770 from trunk.
+
+ * lib/xmlrpc/parser.rb (XMLRPC::Convert::dateTime): Fixing a bug that
+ caused time zone conversion to fail for some ISO 8601 date formats.
+ [ruby-Bugs-12677]
+
+ * lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): Explicitly start
+ the HTTP connection to support keepalive requests. [ruby-Bugs-9353]
+
+ * lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): Improving the error
+ message for Content-Type check failures. [ruby-core:12163]
+
+ * lib/xmlrpc/utils.rb (XMLRPC::ParseContentType#parse_content_type):
+ Making Content-Type checks case insensitive. [ruby-Bugs-3367]
+
+Sun Jun 8 01:45:27 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * marshal.c (r_bytes0): refined length check. [ruby-dev:32059]
+
+Sun Jun 8 01:45:27 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * marshal.c (r_bytes0): check if source has enough data.
+ [ruby-dev:32054]
+
+Sun Jun 8 01:37:58 2008 Tanaka Akira <akr@fsij.org>
+
+ * ext/socket/socket.c (s_accept_nonblock): make accepted fd
+ nonblocking. [ruby-talk:274079]
+
+Sun Jun 8 01:28:42 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * win32/mkexports.rb: deal with __fastcall name decorations.
+ [ruby-list:44111]
+
+Sun Jun 8 01:23:29 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/rexml/source.rb (REXML::SourceFactory::SourceFactory): typo
+ fixed. [ruby-list:44099]
+
+Sun Jun 8 01:17:45 2008 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * {bcc32,win32}/Makefile.sub (COMMON_MACROS): workaround for old SDK's
+ bug. [ruby-core:12584]
+
+Sun Jun 8 00:56:44 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
+
+ * lib/net/http.rb, lib/open-uri.rb: remove
+ Net::HTTP#enable_post_connection_check. [ruby-dev:31960]
+
+ * lib/net/imap.rb: hostname should be verified against server's
+ indentity as persented in the server's certificate. [ruby-dev:31960]
+
+ * ext/openssl/lib/net/telnets.rb, ext/openssl/lib/net/ftptls.rb: ditto.
+
+Thu Jun 5 16:19:27 2008 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (make_cmdvector): adjust escaped successive
+ double-quote handling. (merge from trunk)
+
+Thu Jun 5 12:24:25 2008 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (init_env): initialize HOME and USER environment
+ variables unless set. [ruby-core:12328] (merge from trunk)
+
+ * win32/win32.c (NtInitialize, getlogin): ditto.
+
+ * configure.in, win32/Makefile.sub (LIBS): need to link shell32
+ library for SH* functions on mswin32 and mingw32.
+
+Thu Jun 5 12:21:06 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * gc.c (id2ref): valid id should not refer T_VALUE nor T_ICLASS.
+ [ruby-dev:31911]
+
+Wed Jun 4 16:39:56 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * Makefile.in (ext/extinit.o): use $(OUTFLAG) as well as other
+ objects. [ruby-Bugs-14228]
+
+Tue Jun 3 16:13:40 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (yyerror): limit error message length. [ruby-dev:31848]
+
+ * regex.c (re_mbc_startpos): separated from re_adjust_startpos.
+
+Tue Jun 3 15:27:11 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * gc.c (os_obj_of, os_each_obj): hide objects to be finalized.
+ [ruby-dev:31810]
+
+Wed Jun 4 19:15:57 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (remove_method): should not remove undef place holder.
+ [ruby-dev:31817]
+
+Tue Jun 3 15:05:48 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * process.c (struct rb_exec_arg): proc should be a VALUE.
+
+ * process.c (rb_f_exec): suppress a warning.
+
+ * process.c (rb_detach_process): cast for the platforms where size of
+ pointer differs from size of int.
+
+ * process.c (rb_f_exec, rb_f_system): should not exceptions after
+ fork. [ruby-core:08262]
+
+Wed May 21 01:32:56 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
+
+ * lib/webrick/httpservlet/filehandler.rb: should normalize path
+ name in path_info to prevent script disclosure vulnerability on
+ DOSISH filesystems. (fix: CVE-2008-1891)
+ Note: NTFS/FAT filesystem should not be published by the platforms
+ other than Windows. Pathname interpretation (including short
+ filename) is less than perfect.
+
+ * lib/webrick/httpservlet/abstract.rb
+ (WEBrick::HTTPServlet::AbstracServlet#redirect_to_directory_uri):
+ should escape the value of Location: header.
+
+ * lib/webrick/httpservlet/cgi_runner.rb: accept interpreter
+ command line arguments.
+
+Sun May 18 01:57:44 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (isdirsep): backslash is valid path separator on cygwin too.
+ backported from 1.8 HEAD.
+
+Sat May 17 23:53:57 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (file_expand_path): fix for short file name on Cygwin.
+
+Sat May 17 23:50:29 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (OpenFile): prevent conflict on Windows.
+
+ * file.c (USE_NTFS): fixed merge miss.
+
+Sat May 17 12:36:46 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (file_expand_path): rb_str_set_len is not backported.
+
+Sat May 17 12:15:48 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (file_expand_path): support for alternative data stream
+ and ignored trailing garbages of NTFS.
+
+ * file.c (rb_file_s_basename): ditto.
+
+ * file.c (rb_file_s_extname): ditto.
+
+Mon Mar 3 23:36:41 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
+
+ * lib/webrick/httpservlet/filehandler.rb: should normalize path
+ separators in path_info to prevent directory traversal attacks
+ on DOSISH platforms.
+ reported by Digital Security Research Group [DSECRG-08-026].
+
+ * lib/webrick/httpservlet/filehandler.rb: pathnames which have
+ not to be published should be checked case-insensitively.
+
+Sun Sep 23 21:57:25 2007 GOTOU Yuuzou <gotoyuzo@notwork.org>
+
+ * lib/net/http.rb: an SSL verification (the server hostname should
+ be matched with its certificate's commonName) is added.
+ this verification can be skipped by
+ "Net::HTTP#enable_post_connection_check=(false)".
+ suggested by Chris Clark <cclark at isecpartners.com>
+
+ * lib/net/open-uri.rb: use Net::HTTP#enable_post_connection_check to
+ perform SSL post connection check.
+
+ * ext/openssl/lib/openssl/ssl.c
+ (OpenSSL::SSL::SSLSocket#post_connection_check): refine error message.
+
+Sun Sep 23 06:08:38 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/stringio/stringio.c (strio_init): separate from strio_initialize
+ to share with strio_reopen properly. [ruby-Bugs-13919]
+
+Sun Sep 23 05:42:35 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * lib/rdoc/options.rb (Options::check_diagram): dot -V output
+ changed. [ ruby-Bugs-11978 ], Thanks Florian Frank.
+
+Mon Sep 17 04:47:02 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ruby.c (proc_options): -W should be allowed in RUBYOPT
+ environment variable. [ruby-core:12118]
+
+Mon Sep 17 04:31:46 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * range.c (range_step): fixed integer overflow. [ruby-dev:31763]
+
+Fri Sep 7 14:57:36 2007 URABE Shyouhei <shyouhei@ice.uec.ac.jp>
+
+ * ruby.c (rubylib_mangled_path): eliminate RSTRING_PTR
+ [ruby-dev:31679]
+
+ * ruby.c(push_include_cygwin): ditto.
+
+Fri Sep 7 14:32:38 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_subseq): need integer overflow check.
+ [ruby-dev:31736]
+
+ * array.c (rb_ary_splice): ditto. [ruby-dev:31737]
+
+ * array.c (rb_ary_fill): ditto. [ruby-dev:31738]
+
+ * string.c (rb_str_splice): integer overflow for length.
+ [ruby-dev:31739]
+
+Fri Sep 7 14:27:33 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (mnew): should preserve noex as safe_level.
+
+ * eval.c (rb_call0): tighten security check condition..
+
+Fri Sep 7 14:19:16 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (group_member): check if presents.
+
+ * configure.in (XCFLAGS): add _GNU_SOURCE on linux.
+
+ * file.c (group_member): use system routine if available.
+
+Fri Sep 7 14:14:19 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * include/ruby/defines.h (flush_register_windows): call "ta 0x03"
+ even on Linux/Sparc. [ruby-dev:31674]
+
+Fri Sep 7 14:12:37 2007 Masaki Suketa <masaki.suketa@nifty.ne.jp>
+
+ * ext/win32ole/win32ole.c (ole_type_progid, reg_enum_key,
+ reg_get_val, ole_wc2mb): fix the bug. Thanks, arton.
+ [ruby-dev:31576]
+
+Fri Sep 7 14:02:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * process.c (detach_process_watcher): should not pass the pointer
+ to an auto variable to the thread to be created. pointed and
+ fix by KUBO Takehiro <kubo at jiubao.org> [ruby-dev:30618]
+
+Fri Sep 7 13:52:36 2007 Tanaka Akira <akr@fsij.org>
+
+ * bignum.c (big_lshift): make shift offset long type.
+ (big_rshift): ditto.
+ (rb_big_lshift): ditto.
+ (big_rshift): ditto.
+ [ruby-dev:31434]
+
+Thu Aug 16 08:44:55 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * hash.c (rb_hash_delete_key): delete the entry without calling block.
+
+ * hash.c (rb_hash_shift): should consider iter_lev too.
+
+ * hash.c (delete_if_i): use rb_hash_delete_key() so that the block
+ isn't called twice. [ruby-core:11556]
+
+Thu Aug 16 08:43:50 2007 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
+
+ * lib/rinda/tuplespace.rb: fix Rinda::TupleSpace keeper thread bug.
+ the thread is started too early. [ruby-talk:264062]
+
+ * test/rinda/test_rinda.rb: ditto.
+
+Thu Aug 16 08:40:38 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/pty/pty.c (establishShell): handshaking before close slave
+ device. [ruby-talk:263410]
+
+Thu Aug 16 08:29:39 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (ac_cv_func_isinf): set yes also on OpenSolaris.
+ [ruby-Bugs-12859]
+
+Thu Aug 16 08:28:16 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/rexml/encodings/{ISO-8859-15,CP-1252}.rb: fixed invalid syntax.
+
+Thu Aug 16 08:26:08 2007 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * lib/README: fixed a typo.
+
+Thu Aug 16 08:20:50 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/extmk.rb (extmake): save all CONFIG values.
+
+ * ext/extmk.rb (extmake): remove mkmf.log at clean, and extconf.h at
+ distclean, respectively.
+
+ * ext/extmk.rb: remove rdoc at clean, and installed list file at
+ distclean, respectively.
+
+Thu Aug 16 07:58:18 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * sprintf.c (rb_f_sprintf): should not check positional number as
+ width. [ruby-core:11838]
+
+Thu Aug 16 07:52:24 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * dln.c (conv_to_posix_path): removed.
+
+ * ruby.c (rubylib_mangled_path, rubylib_mangled_path2): return
+ VALUE instead of a pointer to static buffer.
+
+ * ruby.c (push_include_cygwin): fixed buffer overflow.
+ [ruby-dev:31297]
+
+ * ruby.c (ruby_init_loadpath): not convert built-in paths.
+
+Thu Aug 16 07:51:37 2007 Akinori MUSHA <knu@iDaemons.org>
+
+ * defines.h: Pull the RUBY_MBCHAR_MAXSIZE definition from trunk,
+ which is necessary for dir.c to compile on djgpp and emx.
+
+Thu Aug 16 07:42:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * intern.h (is_ruby_native_thread): removed since declared as an int
+ function in ruby.h already.
+
+Thu Aug 16 07:40:41 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * file.c (rb_file_s_rename): deleted code to get rid of a bug of
+ old Cygwin.
+
+ * file.c (rb_file_truncate): added prototype of GetLastError()
+ on cygwin. [ruby-dev:31239]
+
+ * intern.h (is_ruby_native_thread): prototype.
+
+ * missing/strftime.c (strftime): fix printf format and actual
+ arguments.
+
+ * ext/Win32API/Win32API.c (Win32API_initialize): ditto.
+
+ * ext/tk/tcltklib.c (ip_finalize): ditto.
+
+ * ext/dl/ptr.c (rb_dlptr_inspect): ditto. [ruby-dev:31268]
+
+ * ext/dl/sym.c (rb_dlsym_inspect): ditto.
+
+ * ext/socket/getnameinfo.c: include stdio.h always.
+
+ * ext/win32ole/win32ole.c (ole_hresult2msg, folevariable_name,
+ folevariable_ole_type, folevariable_ole_type_detail,
+ folevariable_value, folemethod_visible): missing return value.
+
+Thu Aug 16 07:32:13 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/mkmf.rb (create_makefile): make OBJS depend on RUBY_EXTCONF_H
+ only if extconf.h is created.
+
+Thu Aug 16 07:29:33 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * {win32,wince,bcc32}/setup.mak (-version-): no RUBY_EXTERN magic.
+
+Thu Aug 16 06:43:03 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/mkmf.rb (init_mkmf): should remove mkmf.log too.
+
+Thu Aug 16 06:40:58 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/openssl/ossl_config.c (ossl_config_set_section): do not
+ initialize aggregations with dynamic values. [ruby-talk:259306]
+
+Thu Aug 16 06:39:19 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (get_backtrace): check the result more.
+ [ruby-dev:31261] [ruby-bugs-12398]
+
+Thu Aug 16 06:32:25 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (rb_big_lshift, rb_big_rshift): separated functions
+ to get rid of infinite recursion. fixed calculation in edge
+ cases. [ruby-dev:31244]
+
+ * numeric.c (rb_fix_lshift, rb_fix_rshift): ditto.
+
+Thu Aug 16 06:26:58 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (rb_big_pow): refine overflow check. [ruby-dev:31242]
+
+Thu Aug 16 06:25:48 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * time.c (time_succ): Time#succ should return a time object in the
+ same timezone mode to the original. [ruby-talk:260256]
+
+Thu Aug 16 06:24:39 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * numeric.c (fix_pow): integer power calculation: 0**n => 0,
+ 1**n => 1, -1**n => 1 (n: even) / -1 (n: odd).
+
+Thu Aug 16 06:11:34 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * lib/base64.rb (Base64::b64encode): should not specify /o option
+ for regular expression. [ruby-dev:31221]
+
+Thu Aug 16 06:08:53 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * sprintf.c (rb_f_sprintf): more checks for format argument.
+ [ruby-core:11569], [ruby-core:11570], [ruby-core:11571],
+ [ruby-core:11573]
+
+Thu Aug 16 05:39:31 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (bignorm): do not empty Bignum. [ruby-dev:31229]
+
+Thu Aug 16 05:12:05 2007 pegacorn <subscriber.jp AT gmail.com>
+
+ * ext/openssl/ossl.h: include ossl_pkcs5.h. [ruby-dev:31231]
+
+ * ext/openssl/ossl_pkcs5.h: new file for PKCS5. [ruby-dev:31231]
+
+ * ext/openssl/ossl_x509name.c (ossl_x509name_to_s): use ossl_raise()
+ instead of rb_raise(). [ruby-dev:31222]
+
+ * ext/sdbm/_sdbm.c: DOSISH platforms need io.h. [ruby-dev:31232]
+
+ * ext/syck/syck.h: include stdlib.h for malloc() and free().
+ [ruby-dev:31232]
+
+ * ext/syck/syck.h (syck_parser_set_input_type): prototype added.
+ [ruby-dev:31231]
+
+ * win32/win32.c: include mbstring.h for _mbspbrk(). [ruby-dev:31232]
+
+ * win32.h (rb_w32_getcwd): prototype added. [ruby-dev:31232]
+
+Thu Aug 16 05:02:39 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (rb_cstr_to_inum): check leading non-digits.
+ [ruby-core:11691]
+
+Thu Aug 16 05:00:01 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * numeric.c (fix_pow): 0**2 should not raise floating point
+ exception. [ruby-dev:31216]
+
+Thu Aug 16 04:56:35 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * win32/win32.c (CreateChild): enclose command line except for
+ command.com which can not handle quotes. [ruby-talk:258939]
+
+Thu Aug 16 04:54:45 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/mkmf.rb (link_command, cc_command, cpp_command): do not expand
+ ::CONFIG which is an alias of MAKEFILE_CONFIG.
+
+Thu Aug 16 04:53:21 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * struct.c (rb_struct_init_copy): disallow changing the size.
+ [ruby-dev:31168]
+
+Thu Aug 16 04:52:11 2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
+
+ * random.c: documentation fix. srand(0) initializes PRNG with '0',
+ not with random_seed.
+
+Thu Aug 16 04:49:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bcc32/{Makefile.sub,setup.mak}: remove surplus slash from srcdir.
+
+Thu Aug 16 04:40:37 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * sprintf.c (rb_f_sprintf): sign bit extension should not be done
+ if FPLUS flag is specified. [ruby-list:39224]
+
+Thu Aug 16 04:39:15 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_initialize): should call rb_ary_modify() first.
+ [ruby-core:11562]
+
+Thu Aug 16 04:38:39 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (yylex): return non-valid token for an invalid
+ instance/class variable name. a patch from from Yusuke ENDOH
+ <mame AT tsg.ne.jp>. [ruby-dev:31095]
+
+Thu Aug 16 04:36:41 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (dsym): return non-null NODE even if yyerror(). based on a
+ patch from from Yusuke ENDOH <mame AT tsg.ne.jp>. [ruby-dev:31085]
+
+Thu Aug 16 04:34:56 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * process.c (proc_exec_v, rb_proc_exec): preserve errno.
+
+Thu Aug 16 04:30:45 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * variable.c (rb_path2class): get rid of dangling pointer caused by
+ optimized out value.
+
+Thu Aug 16 04:24:28 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * ext/dl/lib/dl/win32.rb: seems that dl doesn't accept void argument.
+ fixed [ruby-bugs:PR#5489].
+
+Thu Aug 16 04:23:44 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser): handle more
+ extensions. [ruby-dev:30972]
+
+Thu Aug 16 04:14:17 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * process.c (ruby_setreuid, ruby_setregid): rename to get rid of name
+ clash.
+Thu Aug 16 04:11:17 2007 Ryan Davis <ryand@zenspider.com>
+
+ * lib/rexml/dtd/dtd.rb: Fixed typo in code. Fixes bug #10420
+
+Thu Aug 16 04:08:20 2007 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap.rb (ResponseParser#next_token): fixed
+ error message. (backported from HEAD)
+
+ * lib/net/imap.rb (ResponseParser#parse_error): fixed
+ the condition not to refer @token.symbol unexpectedly.
+ Thanks, Dick Monahan. (backported from HEAD)
+
+Thu Aug 16 04:05:20 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * marshal.c (w_extended): erroneous check condition when dump
+ method is defined. [ruby-core:10646]
+
+Sat Jun 9 10:40:00 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * stable version 1.8.5-p52 released.
+
+Thu Jun 7 14:53:46 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * eval.c (method_inspect): show proper class name.
+ [ruby-talk:248647], Thanks Calamitas.
+
+Mon May 28 19:37:24 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (move_to_next_entry): revert r12338. not necessary
+ on ruby_1_8_5.
+
+Sun May 27 05:52:37 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * eval.c (mnew): call of super via a method object should work again.
+ [ruby-talk:248647], Thanks Calamitas.
+
+ * test/ruby/test_method.rb (TestMethod::test_method_super): test for
+ above fix.
+
+Wed May 23 06:51:46 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * lib/cgi.rb (CGI#[]): get rid of exceptions being raised.
+ [ruby-dev:30740], Thanks Kentaro KAWAMOTO.
+
+Wed May 23 06:14:15 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * win32/win32.c (move_to_next_entry): loc also must move forward.
+ [ruby-talk:251987]
+
+Wed May 23 05:55:04 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (init_stdhandle): stderr should be without buffering,
+ but mswin32 use buffering when stderr is not connected to tty.
+
+Wed May 23 03:33:55 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * lib/monitor.rb (ConditionVariable#wait, mon_enter, mon_exit_for_cond):
+ ensures Thread.critical to be false. [ruby-talk:248300]
+
+Wed May 23 03:25:13 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * util.c (ruby_strtod): exponent is radix 10. [ruby-talk:248272]
+
+Wed May 23 02:09:32 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_yield_0): should not clear state on TAG_NEXT when
+ it's invoked from within lambda body. [ruby-talk:248136]
+
+ * eval.c (proc_invoke): handle TAG_NEXT which would be caused by
+ next in the lambda body as well.
+
+Wed May 23 01:55:49 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (rb_w32_fclose, rb_w32_close): need to save errno
+ before calling original fclose()/close().
+
+Wed May 23 01:42:29 2007 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap.rb (disconnect): call shutdown for
+ SSLSocket. Thanks, Technorama Ltd.
+
+Wed May 23 01:28:14 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * error.c (rb_notimplement), io.c (pipe_open): removed definite
+ articles and UNIX manual section from messages. [ruby-dev:30690]
+
+ * io.c (pipe_open): raise NotImplementedError for command "-" on
+ platforms where fork(2) is not available. [ruby-dev:30681]
+
+Wed May 23 00:06:19 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * ext/socket/socket.c (s_recv, s_recvfrom): some systems (such as
+ windows) doesn't set fromlen if the socket is connection-oriented.
+ reported by Bram Whillock in [ruby-core:10512] [ruby-Bugs#9061]
+
+Tue Mar 20 15:37:24 2007 URABE Shyouhei <shyouhei@ruby-lang.org>
+
+ * distruby.rb: Add zip generation.
+
+Fri Mar 16 21:48:11 2007 Akinori MUSHA <knu@iDaemons.org>
+
+ * ext/dl/dl.c (rb_ary2cary): Fix a bug in type validation;
+ submitted by sheepman <sheepman AT sheepman.sakura.ne.jp>
+ in [ruby-dev:30554].
+
+Fri Mar 16 18:28:06 2007 Akinori MUSHA <knu@iDaemons.org>
+
+ * ext/etc/etc.c (etc_getgrgid): Fix a bug in Etc::getgrgid()
+ always returning the (real) group entry of the running process;
+ reported by: UEDA Hiroyuki <ueda AT netforest.ad.jp>
+ in [ruby-dev:30586].
+
Wed Mar 14 12:30:00 2007 Shigeo Kobayashi <shigeo@tinyforest.jp>
* ext/bigdecimal/bigdecimal.c: BigDecimal("-.31") is now
@@ -12050,7 +12973,7 @@ Wed Feb 18 17:18:01 2004 WATANABE Hirofumi <eban@ruby-lang.org>
Wed Feb 18 10:40:38 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* sprintf.c (rb_f_sprintf): do not prepend dots for negative
- numbers if FZERO is specified. [ruby-dev:39218]
+ numbers if FZERO is specified. [ruby-list:39218]
Tue Feb 17 23:40:34 2004 Guy Decoux <ts@moulon.inra.fr>
diff --git a/Makefile.in b/Makefile.in
index 254f1656ee..8fd59babcd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -175,4 +175,4 @@ distclean-local::
@$(RM) ext/config.cache $(RBCONFIG)
ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
- $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -o$@ -c ext/extinit.c
+ $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c
diff --git a/array.c b/array.c
index d456373fe4..baae2706e5 100644
--- a/array.c
+++ b/array.c
@@ -272,6 +272,7 @@ rb_ary_initialize(argc, argv, ary)
long len;
VALUE size, val;
+ rb_ary_modify(ary);
if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
RARRAY(ary)->len = 0;
if (rb_block_given_p()) {
@@ -295,7 +296,6 @@ rb_ary_initialize(argc, argv, ary)
if (len > 0 && len * (long)sizeof(VALUE) <= len) {
rb_raise(rb_eArgError, "array size too big");
}
- rb_ary_modify(ary);
if (len > RARRAY(ary)->aux.capa) {
REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
RARRAY(ary)->aux.capa = len;
@@ -598,7 +598,7 @@ rb_ary_subseq(ary, beg, len)
if (beg > RARRAY(ary)->len) return Qnil;
if (beg < 0 || len < 0) return Qnil;
- if (beg + len > RARRAY(ary)->len) {
+ if (RARRAY(ary)->len < len || RARRAY(ary)->len < beg + len) {
len = RARRAY(ary)->len - beg;
if (len < 0)
len = 0;
@@ -953,7 +953,7 @@ rb_ary_splice(ary, beg, len, rpl)
rb_raise(rb_eIndexError, "index %ld out of array", beg);
}
}
- if (beg + len > RARRAY(ary)->len) {
+ if (RARRAY(ary)->len < len || RARRAY(ary)->len < beg + len) {
len = RARRAY(ary)->len - beg;
}
@@ -2258,6 +2258,9 @@ rb_ary_fill(argc, argv, ary)
}
rb_ary_modify(ary);
end = beg + len;
+ if (end < 0) {
+ rb_raise(rb_eArgError, "argument too big");
+ }
if (end > RARRAY(ary)->len) {
if (end >= RARRAY(ary)->aux.capa) {
REALLOC_N(RARRAY(ary)->ptr, VALUE, end);
diff --git a/bcc32/Makefile.sub b/bcc32/Makefile.sub
index 030a799e99..de7a2beeb8 100644
--- a/bcc32/Makefile.sub
+++ b/bcc32/Makefile.sub
@@ -135,7 +135,7 @@ MISSING = acosh.obj crypt.obj erf.obj win32.obj
STACK = 0x2000000
!endif
-XCFLAGS = -DRUBY_EXPORT -I. -I$(srcdir) -I$(srcdir)missing
+XCFLAGS = -DRUBY_EXPORT -I. -I$(srcdir) -I$(srcdir)/missing
ARFLAGS = /a
LD = ilink32 -q -Gn
@@ -154,7 +154,7 @@ PROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)
WPROGRAM=$(RUBYW_INSTALL_NAME)$(EXEEXT)
RUBYDEF = $(RUBY_SO_NAME).def
MINIRUBY = .\miniruby$(EXEEXT)
-RUNRUBY = .\ruby$(EXEEXT) "$(srcdir)runruby.rb" --extout="$(EXTOUT)" --
+RUNRUBY = .\ruby$(EXEEXT) "$(srcdir)/runruby.rb" --extout="$(EXTOUT)" --
ORGLIBPATH = $(LIB)
@@ -172,8 +172,8 @@ OBJEXT = obj
WINMAINOBJ = winmain.$(OBJEXT)
MINIOBJS = dmydln.$(OBJEXT)
-.path.c = .;$(srcdir);$(srcdir)win32;$(srcdir)missing
-.path.h = .;$(srcdir);$(srcdir)win32;$(srcdir)missing
+.path.c = .;$(srcdir);$(srcdir)/win32;$(srcdir)/missing
+.path.h = .;$(srcdir);$(srcdir)/win32;$(srcdir)/missing
.path.y = $(srcdir)
.path. = $(srcdir)
@@ -181,14 +181,14 @@ MINIOBJS = dmydln.$(OBJEXT)
$(CC) $(CFLAGS) $(XCFLAGS) -I. $(CPPFLAGS) -c $(<:/=\)
.rc.res:
- $(RC) $(RFLAGS) -I. -I$(<D). $(iconinc) -I$(srcdir)win32 $(RFLAGS) -fo$@ $(<:/=\)
+ $(RC) $(RFLAGS) -I. -I$(<D). $(iconinc) -I$(srcdir)/win32 $(RFLAGS) -fo$@ $(<:/=\)
.y.c:
$(YACC) $(YFLAGS) $(<:\=/)
sed -e "s!^ *extern char \*getenv();!/* & */!;s/^\(#.*\)y\.tab/\1parse/" y.tab.c > $(@F)
@del y.tab.c
-all: $(srcdir)bcc32/Makefile.sub $(srcdir)common.mk
+all: $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk
ruby: $(PROGRAM)
rubyw: $(WPROGRAM)
@@ -203,8 +203,8 @@ config: config.status
config.status: $(CONFIG_H)
-$(CONFIG_H): $(MKFILES) $(srcdir)bcc32/Makefile.sub
- @$(srcdir:/=\)win32\ifchange.bat config.h &&|
+$(CONFIG_H): $(MKFILES) $(srcdir)/bcc32/Makefile.sub
+ @$(srcdir:/=\)\win32\ifchange.bat config.h &&|
\#define HAVE_SYS_TYPES_H 1
\#define HAVE_SYS_STAT_H 1
\#define HAVE_STDLIB_H 1
@@ -284,7 +284,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)bcc32/Makefile.sub
|
@exit > $@
-config.status: $(MKFILES) $(srcdir)bcc32/Makefile.sub $(srcdir)common.mk
+config.status: $(MKFILES) $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk
@echo Creating $@
@type > $@ &&|
# Generated automatically by Makefile.sub.
@@ -389,7 +389,7 @@ s,@COMPILE_CXX@,$$(CXX) $$(INCFLAGS) $$(CXXFLAGS) $$(CPPFLAGS) -P -c $$(<:/=\),;
s,@COMPILE_RULES@,{$$(srcdir)}.%s{}.%s: {$$(topdir)}.%s{}.%s: {$$(hdrdir)}.%s{}.%s: .%s.%s:,;t t
s,@RULE_SUBST@,{.;$$(VPATH)}%s,;t t
s,@COMMON_LIBS@,m advapi32 avicap32 avifil32 cap comctl32 comdlg32 dlcapi gdi32 glu32 imagehlp imm32 inetmib1 kernel32 loadperf lsapi32 lz32 mapi32 mgmtapi mpr msacm32 msvfw32 nddeapi netapi32 ole32 oleaut32 oledlg olepro32 opengl32 pdh pkpd32 rasapi32 rasdlg rassapi rpcrt4 setupapi shell32 shfolder snmpapi sporder tapi32 url user32 vdmdbg version win32spl winmm wintrust wsock32,;t t
-s,@COMMON_MACROS@,WIN32_LEAN_AND_MEAN;t t
+s,@COMMON_MACROS@,WIN32_LEAN_AND_MEAN WIN32,;t t
s,@COMMON_HEADERS@,winsock2.h windows.h,;t t
s,@TRY_LINK@,$$(CC) -oconftest $$(INCFLAGS) -I$$(hdrdir) $$(CPPFLAGS) $$(CFLAGS) $$(LIBPATH) $$(LDFLAGS) $$(src) $$(LOCAL_LIBS) $$(LIBS),;t t
s,@EXPORT_PREFIX@,_,;t t
@@ -426,14 +426,14 @@ $(LIBRUBY_SO): $(LIBRUBY_A) $(DLDOBJS) $(RUBYDEF) $(RUBY_SO_NAME).res
$(LIBRUBY): $(LIBRUBY_SO)
$(RUBYDEF): $(LIBRUBY_A) $(PREP)
- $(MINIRUBY) $(srcdir)bcc32/mkexports.rb -output=$@ -base=$(RUBY_SO_NAME) $(LIBRUBY_A)
+ $(MINIRUBY) $(srcdir)/bcc32/mkexports.rb -output=$@ -base=$(RUBY_SO_NAME) $(LIBRUBY_A)
$(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc: rbconfig.rb
- @$(MINIRUBY) $(srcdir)win32/resource.rb \
+ @$(MINIRUBY) $(srcdir)/win32/resource.rb \
-ruby_name=$(RUBY_INSTALL_NAME) \
-rubyw_name=$(RUBYW_INSTALL_NAME) \
-so_name=$(RUBY_SO_NAME) \
- . $(icondirs) $(srcdir)win32
+ . $(icondirs) $(srcdir)/win32
post-install-ext::
$(MINIRUBY) -I$(srcdir)lib -rrbconfig -rfileutils \
diff --git a/bcc32/setup.mak b/bcc32/setup.mak
index 1c922c208f..b7a2539d0a 100644
--- a/bcc32/setup.mak
+++ b/bcc32/setup.mak
@@ -1,13 +1,13 @@
# -*- makefile -*-
!if "$(srcdir)" != ""
-bcc32dir = $(srcdir)bcc32/
+bcc32dir = $(srcdir)/bcc32
!elseif "$(bcc32dir)" == "bcc32/"
-srcdir = ./
+srcdir = .
!elseif "$(bcc32dir:/bcc32/=)/bcc32/" == "$(bcc32dir)"
-srcdir = $(bcc32dir:/bcc32/=/)
+srcdir = $(bcc32dir:/bcc32/=)
!else
-srcdir = $(bcc32dir)../
+srcdir = $(bcc32dir)/..
!endif
!ifndef prefix
prefix = /usr
@@ -62,7 +62,7 @@ if exist usebormm.tds echo MEMLIB = usebormm.lib
@usebormm.bat >> $(MAKEFILE)
@del usebormm.*
- @cpp32 -I$(srcdir) -DRUBY_EXTERN="//" -P- -o$(MAKEFILE) > nul &&|
+ @cpp32 -I$(srcdir) -P- -o$(MAKEFILE) > nul &&|
\#include "version.h"
MAJOR = RUBY_VERSION_MAJOR
MINOR = RUBY_VERSION_MINOR
@@ -122,12 +122,12 @@ $(BANG)endif
\# RUBY_INSTALL_NAME = ruby
\# RUBY_SO_NAME = $$(RT)-$$(RUBY_INSTALL_NAME)$$(MAJOR)$$(MINOR)
\# CFLAGS = -q $$(DEBUGFLAGS) $$(OPTFLAGS) $$(PROCESSOR_FLAG) -w- -wsus -wcpt -wdup -wext -wrng -wrpt -wzdi
-\# CPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)missing -DLIBRUBY_SO=\"$$(LIBRUBY_SO)\"
+\# CPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)/missing -DLIBRUBY_SO=\"$$(LIBRUBY_SO)\"
\# STACK = 0x2000000
\# LDFLAGS = -S:$$(STACK)
\# RFLAGS = $$(iconinc)
\# EXTLIBS = cw32.lib import32.lib user32.lib kernel32.lib
-$(BANG)include $$(srcdir)bcc32/Makefile.sub
+$(BANG)include $$(srcdir)/bcc32/Makefile.sub
|
@$(srcdir:/=\)\win32\rm.bat config.h config.status
@echo type "`$(MAKE)'" to make ruby for $(OS).
diff --git a/bignum.c b/bignum.c
index 3057f1d45a..ee9c38aff9 100644
--- a/bignum.c
+++ b/bignum.c
@@ -36,7 +36,21 @@ VALUE rb_cBignum;
#define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
#define BDIGMAX ((BDIGIT)-1)
-#define BIGZEROP(x) (RBIGNUM(x)->len == 0 || (RBIGNUM(x)->len == 1 && BDIGITS(x)[0] == 0))
+#define BIGZEROP(x) (RBIGNUM(x)->len == 0 || \
+ (BDIGITS(x)[0] == 0 && \
+ (RBIGNUM(x)->len == 1 || bigzero_p(x))))
+
+static int bigzero_p(VALUE);
+static int
+bigzero_p(x)
+ VALUE x;
+{
+ long i;
+ for (i = 0; i < RBIGNUM(x)->len; ++i) {
+ if (BDIGITS(x)[i]) return 0;
+ }
+ return 1;
+}
static VALUE
bignew_1(klass, len, sign)
@@ -74,6 +88,7 @@ get2comp(x)
BDIGIT *ds = BDIGITS(x);
BDIGIT_DBL num;
+ if (!i) return;
while (i--) ds[i] = ~ds[i];
i = 0; num = 1;
do {
@@ -106,7 +121,7 @@ bignorm(x)
long len = RBIGNUM(x)->len;
BDIGIT *ds = BDIGITS(x);
- while (len-- && !ds[len]) ;
+ while (--len && !ds[len]) ;
RBIGNUM(x)->len = ++len;
if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) {
@@ -331,6 +346,13 @@ rb_cstr_to_inum(str, base, badcheck)
VALUE z;
BDIGIT *zds;
+#define conv_digit(c) \
+ (!ISASCII(c) ? -1 : \
+ isdigit(c) ? ((c) - '0') : \
+ islower(c) ? ((c) - 'a' + 10) : \
+ isupper(c) ? ((c) - 'A' + 10) : \
+ -1)
+
if (!str) {
if (badcheck) goto bad;
return INT2FIX(0);
@@ -423,7 +445,13 @@ rb_cstr_to_inum(str, base, badcheck)
}
if (*str == '0') { /* squeeze preceeding 0s */
while (*++str == '0');
- --str;
+ if (!(c = *str) || ISSPACE(c)) --str;
+ }
+ c = *str;
+ c = conv_digit(c);
+ if (c < 0 || c >= base) {
+ if (badcheck) goto bad;
+ return INT2FIX(0);
}
len *= strlen(str)*sizeof(char);
@@ -457,7 +485,7 @@ rb_cstr_to_inum(str, base, badcheck)
z = bignew(len, sign);
zds = BDIGITS(z);
for (i=len;i--;) zds[i]=0;
- while (c = *str++) {
+ while ((c = *str++) != 0) {
if (c == '_') {
if (badcheck) {
if (nondigit) goto bad;
@@ -465,19 +493,7 @@ rb_cstr_to_inum(str, base, badcheck)
}
continue;
}
- else if (!ISASCII(c)) {
- break;
- }
- else if (isdigit(c)) {
- c -= '0';
- }
- else if (islower(c)) {
- c -= 'a' - 10;
- }
- else if (isupper(c)) {
- c -= 'A' - 10;
- }
- else {
+ else if ((c = conv_digit(c)) < 0) {
break;
}
if (c >= base) break;
@@ -634,6 +650,9 @@ rb_big2str(x, base)
if (BIGZEROP(x)) {
return rb_str_new2("0");
}
+ if (i >= LONG_MAX/SIZEOF_BDIGITS/CHAR_BIT) {
+ rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
+ }
j = SIZEOF_BDIGITS*CHAR_BIT*i;
switch (base) {
case 2: break;
@@ -1058,6 +1077,7 @@ rb_big_neg(x)
if (!RBIGNUM(x)->sign) get2comp(z);
ds = BDIGITS(z);
i = RBIGNUM(x)->len;
+ if (!i) return INT2FIX(~0);
while (i--) ds[i] = ~ds[i];
RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
if (RBIGNUM(x)->sign) get2comp(z);
@@ -1506,6 +1526,20 @@ rb_big_remainder(x, y)
return bignorm(z);
}
+static VALUE big_lshift _((VALUE, unsigned long));
+static VALUE big_rshift _((VALUE, unsigned long));
+
+static VALUE big_shift(x, n)
+ VALUE x;
+ int n;
+{
+ if (n < 0)
+ return big_lshift(x, (unsigned int)n);
+ else if (n > 0)
+ return big_rshift(x, (unsigned int)n);
+ return x;
+}
+
/*
* call-seq:
* big.divmod(numeric) => array
@@ -1608,8 +1642,10 @@ rb_big_pow(x, y)
yy = FIX2LONG(y);
if (yy > 0) {
VALUE z = x;
+ const long BIGLEN_LIMIT = 1024*1024 / SIZEOF_BDIGITS;
- if (RBIGNUM(x)->len * SIZEOF_BDIGITS * yy > 1024*1024) {
+ if ((RBIGNUM(x)->len > BIGLEN_LIMIT) ||
+ (RBIGNUM(x)->len > BIGLEN_LIMIT / yy)) {
rb_warn("in a**b, b may be too big");
d = (double)yy;
break;
@@ -1807,7 +1843,15 @@ rb_big_xor(xx, yy)
return bignorm(z);
}
-static VALUE rb_big_rshift _((VALUE,VALUE));
+static VALUE
+check_shiftdown(VALUE y, VALUE x)
+{
+ if (!RBIGNUM(x)->len) return INT2FIX(0);
+ if (RBIGNUM(y)->len > SIZEOF_LONG / SIZEOF_BDIGITS) {
+ return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(-1);
+ }
+ return Qnil;
+}
/*
* call-seq:
@@ -1820,15 +1864,46 @@ VALUE
rb_big_lshift(x, y)
VALUE x, y;
{
+ long shift;
+ int neg = 0;
+
+ for (;;) {
+ if (FIXNUM_P(y)) {
+ shift = FIX2LONG(y);
+ if (shift < 0) {
+ neg = 1;
+ shift = -shift;
+ }
+ break;
+ }
+ else if (TYPE(y) == T_BIGNUM) {
+ if (!RBIGNUM(y)->sign) {
+ VALUE t = check_shiftdown(y, x);
+ if (!NIL_P(t)) return t;
+ neg = 1;
+ }
+ shift = big2ulong(y, "long", Qtrue);
+ break;
+ }
+ y = rb_to_int(y);
+ }
+
+ if (neg) return big_rshift(x, shift);
+ return big_lshift(x, shift);
+}
+
+static VALUE
+big_lshift(x, shift)
+ VALUE x;
+ unsigned long shift;
+{
BDIGIT *xds, *zds;
- int shift = NUM2INT(y);
- int s1 = shift/BITSPERDIG;
+ long s1 = shift/BITSPERDIG;
int s2 = shift%BITSPERDIG;
VALUE z;
BDIGIT_DBL num = 0;
long len, i;
- if (shift < 0) return rb_big_rshift(x, INT2FIX(-shift));
len = RBIGNUM(x)->len;
z = bignew(len+s1+1, RBIGNUM(x)->sign);
zds = BDIGITS(z);
@@ -1852,21 +1927,53 @@ rb_big_lshift(x, y)
* Shifts big right _numeric_ positions (left if _numeric_ is negative).
*/
-static VALUE
+VALUE
rb_big_rshift(x, y)
VALUE x, y;
{
+ long shift;
+ int neg = 0;
+
+ for (;;) {
+ if (FIXNUM_P(y)) {
+ shift = FIX2LONG(y);
+ if (shift < 0) {
+ neg = 1;
+ shift = -shift;
+ }
+ break;
+ }
+ else if (TYPE(y) == T_BIGNUM) {
+ if (RBIGNUM(y)->sign) {
+ VALUE t = check_shiftdown(y, x);
+ if (!NIL_P(t)) return t;
+ }
+ else {
+ neg = 1;
+ }
+ shift = big2ulong(y, "long", Qtrue);
+ break;
+ }
+ y = rb_to_int(y);
+ }
+
+ if (neg) return big_lshift(x, shift);
+ return big_rshift(x, shift);
+}
+
+static VALUE
+big_rshift(x, shift)
+ VALUE x;
+ unsigned long shift;
+{
BDIGIT *xds, *zds;
- int shift = NUM2INT(y);
long s1 = shift/BITSPERDIG;
- long s2 = shift%BITSPERDIG;
+ int s2 = shift%BITSPERDIG;
VALUE z;
BDIGIT_DBL num = 0;
long i, j;
volatile VALUE save_x;
- if (shift < 0) return rb_big_lshift(x, INT2FIX(-shift));
-
if (s1 > RBIGNUM(x)->len) {
if (RBIGNUM(x)->sign)
return INT2FIX(0);
diff --git a/configure.in b/configure.in
index b3288f8c03..e31a6fec49 100644
--- a/configure.in
+++ b/configure.in
@@ -336,16 +336,13 @@ human*) ac_cv_func_getpgrp_void=yes
ac_cv_func_setitimer=no
;;
beos*) ac_cv_func_link=no;;
-cygwin*) rb_cv_have_daylight=no
- ac_cv_var_tzname=no
- ac_cv_func__setjmp=no
- ac_cv_func_setitimer=no
- ;;
+cygwin*) ;;
mingw*) if test "$with_winsock2" = yes; then
LIBS="-lws2_32 $LIBS"
else
LIBS="-lwsock32 $LIBS"
fi
+ LIBS="-lshell32 $LIBS"
ac_cv_header_a_out_h=no
ac_cv_header_pwd_h=no
ac_cv_header_utime_h=no
@@ -422,10 +419,10 @@ bow) ac_cv_func_setitimer=no
;;
superux*) ac_cv_func_setitimer=no
;;
-solaris*2.10) if test -z "$GCC"; then
- ac_cv_func_isinf=yes
+solaris*2.1*) if test -z "$GCC"; then
+ ac_cv_func_isinf=yes
fi
- LIBS="-lm $LIBS"
+ LIBS="-lm $LIBS"
;;
*) LIBS="-lm $LIBS";;
esac
@@ -484,14 +481,15 @@ AC_REPLACE_FUNCS(dup2 memmove strcasecmp strncasecmp strerror strftime\
strchr strstr strtoul crypt flock vsnprintf\
isnan finite isinf hypot acosh erf)
AC_CHECK_FUNCS(fmod killpg wait4 waitpid syscall chroot fsync getcwd eaccess\
- truncate chsize times utimes fcntl lockf lstat symlink link\
+ truncate ftruncate chsize times utimes fcntl lockf lstat symlink link\
readlink setitimer setruid seteuid setreuid setresuid\
setproctitle setrgid setegid setregid setresgid issetugid pause\
lchown lchmod getpgrp setpgrp getpgid setpgid initgroups\
getgroups setgroups getpriority getrlimit setrlimit sysconf\
- dlopen sigprocmask\
- sigaction _setjmp setsid telldir seekdir fchmod mktime timegm\
- cosh sinh tanh setuid setgid setenv unsetenv)
+ group_member dlopen sigprocmask\
+ sigaction _setjmp setsid telldir seekdir fchmod\
+ mktime timegm gettimeofday\
+ cosh sinh tanh round setuid setgid setenv unsetenv)
AC_ARG_ENABLE(setreuid,
[ --enable-setreuid use setreuid()/setregid() according to need even if obsolete.],
[use_setreuid=$enableval])
@@ -517,6 +515,42 @@ AC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight,
if test "$rb_cv_have_daylight" = yes; then
AC_DEFINE(HAVE_DAYLIGHT)
fi
+AC_DEFUN([RUBY_CHECK_VARTYPE], [dnl
+AC_CACHE_CHECK([for external $1], rb_cv_var_$1,
+ [rb_cv_var_$1=no
+ AC_TRY_COMPILE([#define _XOPEN_SOURCE 1
+ $2
+ const volatile void *volatile t;],
+ [t = &(&$1)[0];],
+ [for t in $3; do
+ AC_TRY_COMPILE([#define _XOPEN_SOURCE 1
+ $2
+ extern $t $1;
+ const volatile void *volatile t;],
+ [t = &(&$1)[0];],
+ [rb_cv_var_$1=$t; break])
+ done])])
+if test "[$rb_cv_var_]$1" != no; then
+ AC_DEFINE([HAVE_VAR_]m4_toupper($1))
+ AC_DEFINE_UNQUOTED([TYPEOF_VAR_]m4_toupper($1), $rb_cv_var_$1)
+fi])
+RUBY_CHECK_VARTYPE(timezone, [#include <time.h>], [long int])
+RUBY_CHECK_VARTYPE(altzone, [#include <time.h>], [long int])
+if test "$rb_cv_var_timezone" = no; then
+ AC_CHECK_FUNCS(timezone)
+ if test "$ ac_cv_func_timezone" = yes; then
+ AC_CACHE_CHECK([whether timezone requires zero arguments], rb_cv_func_timezone_void,
+ [AC_TRY_COMPILE([#include <time.h>],
+ [(void)timezone(0, 0);],
+ [rb_cv_func_timezone_void=no],
+ [rb_cv_func_timezone_void=yes])]
+ )
+ if test $rb_cv_func_timezone_void = yes; then
+ AC_DEFINE(TIMEZONE_VOID)
+ fi
+ fi
+fi
+
AC_CACHE_CHECK(for negative time_t for gmtime(3), rb_cv_negative_time_t,
[AC_TRY_RUN([
#include <time.h>
@@ -558,6 +592,7 @@ fi
if test "$ac_cv_func_sigprocmask" = yes && test "$ac_cv_func_sigaction" = yes; then
AC_DEFINE(POSIX_SIGNAL)
else
+ AC_CHECK_FUNCS(sigsetmask)
AC_CACHE_CHECK(for BSD signal semantics, rb_cv_bsd_signal,
[AC_TRY_RUN([
#include <stdio.h>
@@ -580,7 +615,7 @@ main()
],
rb_cv_bsd_signal=yes,
rb_cv_bsd_signal=no,
- rb_cv_bsd_signal=no)])
+ rb_cv_bsd_signal=$ac_cv_func_sigsetmask)])
if test "$rb_cv_bsd_signal" = yes; then
AC_DEFINE(BSD_SIGNAL)
fi
@@ -1145,7 +1180,7 @@ case "$target_os" in
human*)
AC_CHECK_LIB(signal, _harderr)
AC_CHECK_LIB(hmem, hmemset)
- AC_CHECK_FUNCS(select gettimeofday)
+ AC_CHECK_FUNCS(select)
AC_CACHE_CHECK(whether PD libc _dtos18 fail to convert big number,
rb_cv_missing__dtos18,
[AC_TRY_RUN(
@@ -1359,6 +1394,9 @@ fi
AC_SUBST(RDOCTARGET)
case "$target_os" in
+ linux*)
+ XCFLAGS="$XCFLAGS -D_GNU_SOURCE=1"
+ ;;
netbsd*)
CFLAGS="$CFLAGS -pipe"
;;
@@ -1415,7 +1453,6 @@ case "$target_os" in
LIBRUBY_SO='cyg$(RUBY_SO_NAME)'${MAJOR}${MINOR}.dll
LIBRUBY='lib$(RUBY_SO_NAME).dll.a'
fi
- AC_LIBOBJ([strftime])
;;
mingw*)
RUBY_SO_NAME=${rb_cv_msvcrt}-'$(RUBY_INSTALL_NAME)'${MAJOR}${MINOR}
diff --git a/defines.h b/defines.h
index 89167e537e..ef80989925 100644
--- a/defines.h
+++ b/defines.h
@@ -203,6 +203,11 @@ void xfree _((void*));
#define EXTERN RUBY_EXTERN /* deprecated */
#endif
+#ifndef RUBY_MBCHAR_MAXSIZE
+#define RUBY_MBCHAR_MAXSIZE INT_MAX
+ /* MB_CUR_MAX will not work well in C locale */
+#endif
+
#if defined(sparc) || defined(__sparc__)
static inline void
flush_register_windows(void)
@@ -213,9 +218,7 @@ flush_register_windows(void)
#endif
# if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)
("flushw")
-# elif defined(linux) || defined(__linux__)
- ("ta 0x83")
-# else /* Solaris, OpenBSD, NetBSD, etc. */
+# else
("ta 0x03")
# endif /* trap always to flush register windows if we are on a Sparc system */
;
diff --git a/distruby.rb b/distruby.rb
index dcc3e76ce8..613da0eb9c 100644
--- a/distruby.rb
+++ b/distruby.rb
@@ -7,7 +7,9 @@ else
dirname = sprintf 'ruby-%s-p%u', RUBY_VERSION, RUBY_PATCHLEVEL
tagname = dirname.gsub /ruby-(\d)\.(\d)\.(\d)-p/, 'v\1_\2_\3_'
end
-tarname = dirname + '.tar.gz'
+tgzname = dirname + '.tar.gz'
+tbzname = dirname + '.tar.bz2'
+zipname = dirname + '.zip'
repos = 'http://svn.ruby-lang.org/repos/ruby/tags/' + tagname
STDERR.puts 'exporting sources...'
@@ -21,16 +23,24 @@ Dir.chdir dirname do
system 'bison', '-y', '-o', 'parse.c', 'parse.y'
end
-STDERR.puts 'generating tarball...'
-system 'tar', 'chofzp', tarname, dirname
-
-open tarname, 'rb' do |fp|
- require 'digest/md5'
- require 'digest/sha1'
- str = fp.read
- md5 = Digest::MD5.hexdigest str
- sha = Digest::SHA1.hexdigest str
- printf "MD5(%s)= %s\nSHA1(%s)= %s\n", tarname, md5, tarname, sha
+STDERR.puts 'generating tarballs...'
+ENV['GZIP'] = '-9'
+system 'tar', 'chofzp', tgzname, dirname
+system 'tar', 'chojfp', tbzname, dirname
+system 'zip', '-q9r', zipname, dirname
+
+require 'digest/md5'
+require 'digest/sha2'
+for name in [tgzname, tbzname, zipname] do
+ open name, 'rb' do |fp|
+ str = fp.read
+ md5 = Digest::MD5.hexdigest str
+ sha = Digest::SHA256.hexdigest str
+ printf "MD5(%s)= %s\nSHA256(%s)= %s\nSIZE(%s)= %s\n\n",
+ name, md5,
+ name, sha,
+ name, str.size
+ end
end
diff --git a/dln.c b/dln.c
index 016d0c12a2..fd59bdab8e 100644
--- a/dln.c
+++ b/dln.c
@@ -1676,35 +1676,6 @@ dln_find_file(fname, path)
#endif
}
-#if defined(__CYGWIN32__)
-const char *
-conv_to_posix_path(win32, posix, len)
- char *win32;
- char *posix;
- int len;
-{
- char *first = win32;
- char *p = win32;
- char *dst = posix;
-
- posix[0] = '\0';
- for (p = win32; *p; p++)
- if (*p == ';') {
- *p = 0;
- cygwin32_conv_to_posix_path(first, posix);
- posix += strlen(posix);
- *posix++ = ':';
- first = p + 1;
- *p = ';';
- }
- if (len < strlen(first))
- fprintf(stderr, "PATH length too long: %s\n", first);
- else
- cygwin32_conv_to_posix_path(first, posix);
- return dst;
-}
-#endif
-
static char fbuf[MAXPATHLEN];
static char *
diff --git a/error.c b/error.c
index 34af299823..6ebc927853 100644
--- a/error.c
+++ b/error.c
@@ -488,14 +488,14 @@ static VALUE
exc_backtrace(exc)
VALUE exc;
{
- ID bt = rb_intern("bt");
+ static ID bt;
- if (!rb_ivar_defined(exc, bt)) return Qnil;
- return rb_ivar_get(exc, bt);
+ if (!bt) bt = rb_intern("bt");
+ return rb_attr_get(exc, bt);
}
-static VALUE
-check_backtrace(bt)
+VALUE
+rb_check_backtrace(bt)
VALUE bt;
{
long i;
@@ -532,7 +532,7 @@ exc_set_backtrace(exc, bt)
VALUE exc;
VALUE bt;
{
- return rb_iv_set(exc, "bt", check_backtrace(bt));
+ return rb_iv_set(exc, "bt", rb_check_backtrace(bt));
}
/*
@@ -1083,7 +1083,7 @@ void
rb_notimplement()
{
rb_raise(rb_eNotImpError,
- "the %s() function is unimplemented on this machine",
+ "%s() function is unimplemented on this machine",
rb_id2name(ruby_frame->last_func));
}
diff --git a/eval.c b/eval.c
index 991792c875..e0a7e17af6 100644
--- a/eval.c
+++ b/eval.c
@@ -458,7 +458,8 @@ rb_define_alloc_func(klass, func)
VALUE (*func) _((VALUE));
{
Check_Type(klass, T_CLASS);
- rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), NOEX_PRIVATE);
+ rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),
+ NOEX_PRIVATE);
}
void
@@ -466,7 +467,7 @@ rb_undef_alloc_func(klass)
VALUE klass;
{
Check_Type(klass, T_CLASS);
- rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
+ rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
}
static NODE*
@@ -574,8 +575,13 @@ remove_method(klass, mid)
if (mid == __id__ || mid == __send__ || mid == init) {
rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
}
- if (!st_delete(RCLASS(klass)->m_tbl, &mid, (st_data_t *)&body) ||
- !body->nd_body) {
+ if (st_lookup(RCLASS(klass)->m_tbl, mid, (st_data_t *)&body)) {
+ if (!body || !body->nd_body) body = 0;
+ else {
+ st_delete(RCLASS(klass)->m_tbl, &mid, (st_data_t *)&body);
+ }
+ }
+ if (!body) {
rb_name_error(mid, "method `%s' not defined in %s",
rb_id2name(mid), rb_class2name(klass));
}
@@ -1200,6 +1206,8 @@ error_pos()
}
}
+VALUE rb_check_backtrace(VALUE);
+
static VALUE
get_backtrace(info)
VALUE info;
@@ -1207,7 +1215,7 @@ get_backtrace(info)
if (NIL_P(info)) return Qnil;
info = rb_funcall(info, rb_intern("backtrace"), 0);
if (NIL_P(info)) return Qnil;
- return rb_check_array_type(info);
+ return rb_check_backtrace(info);
}
static void
@@ -1294,8 +1302,9 @@ error_print()
warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);
warn_print(")\n");
}
- if (tail) {
+ if (tail && elen>len+1) {
warn_print2(tail, elen-len-1);
+ if (einfo[elen-1] != '\n') warn_print2("\n", 1);
}
}
}
@@ -2161,6 +2170,9 @@ rb_alias(klass, name, def)
st_insert(RCLASS(klass)->m_tbl, name,
(st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin),
NOEX_WITH_SAFE(orig->nd_noex)));
+
+ if (!ruby_running) return;
+
if (singleton) {
rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
}
@@ -4994,8 +5006,10 @@ rb_yield_0(val, self, klass, flags, avalue)
CHECK_INTS;
goto redo;
case TAG_NEXT:
- state = 0;
- result = prot_tag->retval;
+ if (!lambda) {
+ state = 0;
+ result = prot_tag->retval;
+ }
break;
case TAG_BREAK:
if (TAG_DST()) {
@@ -5739,7 +5753,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
volatile int safe = -1;
if (NOEX_SAFE(flags) > ruby_safe_level &&
- !(flags&NOEX_TAINTED) && ruby_safe_level == 0 && NOEX_SAFE(flags) > 2) {
+ ruby_safe_level == 0 && NOEX_SAFE(flags) > 2) {
rb_raise(rb_eSecurityError, "calling insecure method: %s",
rb_id2name(id));
}
@@ -6477,16 +6491,17 @@ eval(self, src, scope, file, line)
if (state) {
if (state == TAG_RAISE) {
if (strcmp(file, "(eval)") == 0) {
- VALUE mesg, errat;
+ VALUE mesg, errat, bt2;
errat = get_backtrace(ruby_errinfo);
- mesg = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
- if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
+ mesg = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
+ if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
+ (bt2 = backtrace(-2), RARRAY(bt2)->len > 0)) {
if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
rb_str_update(mesg, 0, 0, rb_str_new2(": "));
rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
}
- RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
+ RARRAY(errat)->ptr[0] = RARRAY(bt2)->ptr[0];
}
}
rb_exc_raise(ruby_errinfo);
@@ -8531,6 +8546,7 @@ proc_invoke(proc, args, self, klass)
proc_jump_error(TAG_RETRY, Qnil); /* xxx */
JUMP_TAG(state);
break;
+ case TAG_NEXT:
case TAG_BREAK:
if (!pcall && result != Qundef) {
proc_jump_error(state, result);
@@ -8900,7 +8916,6 @@ mnew(klass, obj, id, mklass)
(FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) {
rklass = RCLASS(rklass)->super;
}
- if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;
method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);
data->klass = klass;
data->recv = obj;
@@ -8908,7 +8923,7 @@ mnew(klass, obj, id, mklass)
data->body = body;
data->rklass = rklass;
data->oid = oid;
- data->safe_level = NOEX_WITH_SAFE(0);
+ data->safe_level = NOEX_WITH_SAFE(noex);
OBJ_INFECT(method, klass);
return method;
@@ -9375,8 +9390,12 @@ method_inspect(method)
else {
rb_str_buf_cat2(str, rb_class2name(data->rklass));
if (data->rklass != data->klass) {
+ VALUE klass = data -> klass;
+ if (TYPE(klass) == T_ICLASS) {
+ klass = RBASIC(klass)->klass;
+ }
rb_str_buf_cat2(str, "(");
- rb_str_buf_cat2(str, rb_class2name(data->klass));
+ rb_str_buf_cat2(str, rb_class2name(klass));
rb_str_buf_cat2(str, ")");
}
}
diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c
index 96ce8c6636..a4fd0396f0 100644
--- a/ext/Win32API/Win32API.c
+++ b/ext/Win32API/Win32API.c
@@ -108,7 +108,7 @@ Win32API_initialize(self, dllname, proc, import, export)
}
if (16 < RARRAY(a_import)->len) {
- rb_raise(rb_eRuntimeError, "too many parameters: %d\n", RARRAY(a_import)->len);
+ rb_raise(rb_eRuntimeError, "too many parameters: %ld\n", RARRAY(a_import)->len);
}
rb_iv_set(self, "__import__", a_import);
diff --git a/ext/Win32API/lib/win32/registry.rb b/ext/Win32API/lib/win32/registry.rb
index 2671551a33..9a2f3827b7 100644
--- a/ext/Win32API/lib/win32/registry.rb
+++ b/ext/Win32API/lib/win32/registry.rb
@@ -493,7 +493,7 @@ module Win32
# utility functions
#
def self.expand_environ(str)
- str.gsub(/%([^%]+)%/) { ENV[$1] || $& }
+ str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }
end
@@type2name = { }
diff --git a/ext/Win32API/lib/win32/resolv.rb b/ext/Win32API/lib/win32/resolv.rb
index 6534d20760..92336fac28 100644
--- a/ext/Win32API/lib/win32/resolv.rb
+++ b/ext/Win32API/lib/win32/resolv.rb
@@ -11,7 +11,7 @@ module Win32
def self.get_hosts_path
path = get_hosts_dir
- path = File.join(path.gsub(/\\/, File::SEPARATOR), 'hosts')
+ path = File.expand_path('hosts', path)
File.exist?(path) ? path : nil
end
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index fd0cd65418..6f215afa48 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -586,19 +586,22 @@ BigDecimal_to_f(VALUE self)
{
ENTER(1);
Real *p;
- double d, d2;
+ double d;
S_LONG e;
+ char *buf;
GUARD_OBJ(p,GetVpValue(self,1));
if(VpVtoD(&d, &e, p)!=1) return rb_float_new(d);
+ buf = ALLOCA_N(char,(unsigned int)VpNumOfChars(p,"E"));
+ VpToString(p, buf, 0, 0);
errno = 0;
- d2 = pow(10.0,(double)e);
- if((errno == ERANGE && e>0) || (d2>1.0 && (fabs(d) > (DBL_MAX / d2)))) {
+ d = strtod(buf, 0);
+ if(errno == ERANGE) {
VpException(VP_EXCEPTION_OVERFLOW,"BigDecimal to Float conversion",0);
if(d>0.0) return rb_float_new(DBL_MAX);
else return rb_float_new(-DBL_MAX);
}
- return rb_float_new(d*d2);
+ return rb_float_new(d);
}
/* The coerce method provides support for Ruby type coercion. It is not
@@ -1062,7 +1065,7 @@ static VALUE
BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
{
VALUE f;
- Real *d,*rv;
+ Real *d,*rv=0;
f = BigDecimal_divremain(self,r,&d,&rv);
if(f!=(VALUE)0) return f;
return ToValue(rv);
@@ -1516,7 +1519,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
} else if(*psz=='+') {
fPlus = 2; psz++;
}
- while(ch=*psz++) {
+ while((ch=*psz++)!=0) {
if(ISSPACE(ch)) continue;
if(!ISDIGIT(ch)) {
if(ch=='F' || ch=='f') fmt = 1; /* F format */
@@ -1956,17 +1959,27 @@ static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */
static U_LONG gnPrecLimit = 0; /* Global upper limit of the precision newly allocated */
static U_LONG gfRoundMode = VP_ROUND_HALF_UP; /* Mode for general rounding operation */
+#ifndef BASE_FIG
static U_LONG BASE_FIG = 4; /* =log10(BASE) */
static U_LONG BASE = 10000L; /* Base value(value must be 10**BASE_FIG) */
/* The value of BASE**2 + BASE must be represented */
/* within one U_LONG. */
static U_LONG HALF_BASE = 5000L;/* =BASE/2 */
-static S_LONG DBLE_FIG = 8; /* figure of double */
static U_LONG BASE1 = 1000L; /* =BASE/10 */
+#else
+#ifndef BASE
+#error BASE_FIG is defined but BASE is not
+#endif
+#define HALF_BASE (BASE/2)
+#define BASE1 (BASE/10)
+#endif
+#ifndef DBLE_FIG
+#define DBLE_FIG (DBL_DIG+1) /* figure of double */
+#endif
static Real *VpConstOne; /* constant 1.0 */
static Real *VpPt5; /* constant 0.5 */
-static U_LONG maxnr = 100; /* Maximum iterations for calcurating sqrt. */
+#define maxnr 100UL /* Maximum iterations for calcurating sqrt. */
/* used in VpSqrt() */
/* ETC */
@@ -2083,8 +2096,8 @@ VpSetRoundMode(unsigned long n)
* (to let the compiler know they may be changed in outside
* (... but not actually..)).
*/
-volatile double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
-volatile double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
+volatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
+volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
static double
Zero(void)
{
@@ -2356,16 +2369,15 @@ VpNumOfChars(Real *vp,char *pszFmt)
VP_EXPORT U_LONG
VpInit(U_LONG BaseVal)
{
- U_LONG w;
- double v;
-
/* Setup +/- Inf NaN -0 */
VpGetDoubleNaN();
VpGetDoublePosInf();
VpGetDoubleNegInf();
VpGetDoubleNegZero();
+#ifndef BASE_FIG
if(BaseVal <= 0) {
+ U_LONG w;
/* Base <= 0, then determine Base by calcuration. */
BASE = 1;
while(
@@ -2382,6 +2394,8 @@ VpInit(U_LONG BaseVal)
BASE1 = BASE / 10;
BASE_FIG = 0;
while(BaseVal /= 10) ++BASE_FIG;
+#endif
+
/* Allocates Vp constants. */
VpConstOne = VpAlloc((U_LONG)1, "1");
VpPt5 = VpAlloc((U_LONG)1, ".5");
@@ -2390,15 +2404,6 @@ VpInit(U_LONG BaseVal)
gnAlloc = 0;
#endif /* _DEBUG */
- /* Determine # of digits available in one 'double'. */
-
- v = 1.0;
- DBLE_FIG = 0;
- while(v + 1.0 > 1.0) {
- ++DBLE_FIG;
- v /= 10;
- }
-
#ifdef _DEBUG
if(gfDebug) {
printf("VpInit: BaseVal = %lu\n", BaseVal);
@@ -2501,7 +2506,7 @@ VpAlloc(U_LONG mx, char *szVal)
psz = ALLOCA_N(char,strlen(szVal)+1);
i = 0;
ipn = 0;
- while(psz[i]=szVal[ipn]) {
+ while((psz[i]=szVal[ipn])!=0) {
if(ISDIGIT(psz[i])) ++ni;
if(psz[i]=='_') {
if(ni>0) {ipn++;continue;}
@@ -2544,7 +2549,7 @@ VpAlloc(U_LONG mx, char *szVal)
else if(szVal[i] == '+') ++i;
/* Skip digits */
ni = 0; /* digits in mantissa */
- while(v = szVal[i]) {
+ while((v = szVal[i]) != 0) {
if(!ISDIGIT(v)) break;
++i;
++ni;
@@ -2558,7 +2563,7 @@ VpAlloc(U_LONG mx, char *szVal)
if(szVal[i] == '.') { /* xxx. */
++i;
ipf = i;
- while(v = szVal[i]) { /* get fraction part. */
+ while((v = szVal[i]) != 0) { /* get fraction part. */
if(!ISDIGIT(v)) break;
++i;
++nf;
@@ -2576,7 +2581,7 @@ VpAlloc(U_LONG mx, char *szVal)
ipe = i;
v = szVal[i];
if((v == '-') ||(v == '+')) ++i;
- while(v=szVal[i]) {
+ while((v=szVal[i])!=0) {
if(!ISDIGIT(v)) break;
++i;
++ne;
@@ -4428,7 +4433,7 @@ VpLeftRound(Real *y, int f, int nf)
if(!VpHasVal(y)) return 0; /* Unable to round */
v = y->frac[0];
nf -= VpExponent(y)*BASE_FIG;
- while(v=v/10) nf--;
+ while((v /= 10) != 0) nf--;
nf += (BASE_FIG-1);
return VpMidRound(y,f,nf);
}
diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb
index a68a656044..864aaad862 100644
--- a/ext/bigdecimal/extconf.rb
+++ b/ext/bigdecimal/extconf.rb
@@ -1,2 +1,12 @@
require 'mkmf'
+
+base_fig = 0
+src = ("(BASE > 0) && "
+ "(BASE * (BASE+1)) > BASE && "
+ "(BASE * (BASE+1)) / BASE == (BASE+1)")
+while try_static_assert(src, nil, "-DBASE=10#{'0'*base_fig}UL")
+ base_fig += 1
+end
+$defs << "-DBASE=1#{'0'*base_fig}UL" << "-DBASE_FIG=#{base_fig}"
+
create_makefile('bigdecimal')
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
index 01fe971093..0124bbbf4a 100644
--- a/ext/curses/extconf.rb
+++ b/ext/curses/extconf.rb
@@ -20,7 +20,7 @@ end
if make
for f in %w(beep bkgd bkgdset curs_set deleteln doupdate flash getbkgd getnstr init isendwin keyname keypad resizeterm scrl set setscrreg ungetch wattroff wattron wattrset wbkgd wbkgdset wdeleteln wgetnstr wresize wscrl wsetscrreg def_prog_mode reset_prog_mode timeout wtimeout nodelay init_color wcolor_set)
- have_func(f)
+ have_func(f) || (have_macro(f, curses) && $defs.push(format("-DHAVE_%s", f.upcase)))
end
flag = "-D_XOPEN_SOURCE_EXTENDED"
src = "int test_var[(sizeof(char*)>sizeof(int))*2-1];"
diff --git a/ext/dl/dl.c b/ext/dl/dl.c
index 042afd3159..71c353bda3 100644
--- a/ext/dl/dl.c
+++ b/ext/dl/dl.c
@@ -459,7 +459,7 @@ rb_ary2cary(char t, VALUE v, long *size)
VALUE val0;
val0 = rb_check_array_type(v);
- if(NIL_P(TYPE(val0))) {
+ if(NIL_P(val0)) {
rb_raise(rb_eDLTypeError, "an array is expected.");
}
v = val0;
diff --git a/ext/dl/lib/dl/win32.rb b/ext/dl/lib/dl/win32.rb
index 92f473d392..0fed47c324 100644
--- a/ext/dl/lib/dl/win32.rb
+++ b/ext/dl/lib/dl/win32.rb
@@ -6,7 +6,7 @@ class Win32API
DLL = {}
def initialize(dllname, func, import, export = "0")
- prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI")
+ prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1')
handle = DLL[dllname] ||= DL::Handle.new(dllname)
@sym = handle.sym(func, prototype)
end
diff --git a/ext/dl/ptr.c b/ext/dl/ptr.c
index 5c313fad55..a3bbcc915c 100644
--- a/ext/dl/ptr.c
+++ b/ext/dl/ptr.c
@@ -4,30 +4,22 @@
#include <ruby.h>
#include <ctype.h>
-#include <version.h> /* for ruby version code */
+#include "st.h"
#include "dl.h"
VALUE rb_cDLPtrData;
VALUE rb_mDLMemorySpace;
-static VALUE DLMemoryTable;
+static st_table* st_memory_table;
#ifndef T_SYMBOL
# define T_SYMBOL T_FIXNUM
#endif
-#if RUBY_VERSION_CODE < 171
-static VALUE
-rb_hash_delete(VALUE hash, VALUE key)
-{
- return rb_funcall(hash, rb_intern("delete"), 1, key);
-}
-#endif
-
static void
rb_dlmem_delete(void *ptr)
{
rb_secure(4);
- rb_hash_delete(DLMemoryTable, DLLONG2NUM(ptr));
+ st_delete(st_memory_table, (st_data_t*)&ptr, NULL);
}
static void
@@ -37,7 +29,7 @@ rb_dlmem_aset(void *ptr, VALUE obj)
rb_dlmem_delete(ptr);
}
else{
- rb_hash_aset(DLMemoryTable, DLLONG2NUM(ptr), DLLONG2NUM(obj));
+ st_insert(st_memory_table, (st_data_t)ptr, (st_data_t)obj);
}
}
@@ -46,8 +38,8 @@ rb_dlmem_aref(void *ptr)
{
VALUE val;
- val = rb_hash_aref(DLMemoryTable, DLLONG2NUM(ptr));
- return val == Qnil ? Qnil : (VALUE)DLNUM2LONG(val);
+ if(!st_lookup(st_memory_table, (st_data_t)ptr, &val)) return Qnil;
+ return val == Qundef ? Qnil : val;
}
void
@@ -466,8 +458,9 @@ rb_dlptr_inspect(VALUE self)
char str[1024];
Data_Get_Struct(self, struct ptr_data, data);
- snprintf(str, 1023, "#<%s:0x%p ptr=0x%p size=%ld free=0x%p>",
- rb_class2name(CLASS_OF(self)), data, data->ptr, data->size, data->free);
+ snprintf(str, 1023, "#<%s:0x%lx ptr=0x%lx size=%ld free=0x%lx>",
+ rb_class2name(CLASS_OF(self)), data, data->ptr, data->size,
+ (long)data->free);
return rb_str_new2(str);
}
@@ -1009,20 +1002,18 @@ rb_dlptr_size(int argc, VALUE argv[], VALUE self)
}
}
-static VALUE
-dlmem_each_i(VALUE assoc, void *data)
+static int
+dlmem_each_i(void* key, VALUE value, void* arg)
{
- VALUE key, val;
- key = rb_ary_entry(assoc, 0);
- val = rb_ary_entry(assoc, 1);
- rb_yield(rb_assoc_new(key,(VALUE)DLNUM2LONG(val)));
+ VALUE vkey = DLLONG2NUM(key);
+ rb_yield(rb_assoc_new(vkey, value));
return Qnil;
}
VALUE
rb_dlmem_each(VALUE self)
{
- rb_iterate(rb_each, DLMemoryTable, dlmem_each_i, 0);
+ st_foreach(st_memory_table, dlmem_each_i, 0);
return Qnil;
}
@@ -1061,7 +1052,7 @@ Init_dlptr()
rb_define_method(rb_cDLPtrData, "size=", rb_dlptr_size, -1);
rb_mDLMemorySpace = rb_define_module_under(rb_mDL, "MemorySpace");
- DLMemoryTable = rb_hash_new();
- rb_define_const(rb_mDLMemorySpace, "MemoryTable", DLMemoryTable);
+ st_memory_table = st_init_numtable();
+ rb_define_const(rb_mDLMemorySpace, "MemoryTable", Qnil); /* historical */
rb_define_module_function(rb_mDLMemorySpace, "each", rb_dlmem_each, 0);
}
diff --git a/ext/dl/sym.c b/ext/dl/sym.c
index 6e4337c0b7..2ca16a8698 100644
--- a/ext/dl/sym.c
+++ b/ext/dl/sym.c
@@ -268,7 +268,7 @@ rb_dlsym_inspect(VALUE self)
str_size = RSTRING(proto)->len + 100;
str = dlmalloc(str_size);
snprintf(str, str_size - 1,
- "#<DL::Symbol:0x%p func=0x%p '%s'>",
+ "#<DL::Symbol:0x%lx func=0x%lx '%s'>",
sym, sym->func, RSTRING(proto)->ptr);
val = rb_tainted_str_new2(str);
dlfree(str);
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 0372592049..084405408f 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -337,7 +337,7 @@ etc_getgrgid(obj, id)
struct group *grp;
rb_secure(4);
- gid = getgid();
+ gid = PW_VAL2GID(id);
grp = getgrgid(gid);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid);
return setup_group(grp);
diff --git a/ext/extmk.rb b/ext/extmk.rb
index bbcb3c09b8..86d59b0946 100644
--- a/ext/extmk.rb
+++ b/ext/extmk.rb
@@ -104,10 +104,10 @@ def extmake(target)
Dir.chdir target
top_srcdir = $top_srcdir
topdir = $topdir
- mk_srcdir = CONFIG["srcdir"]
- mk_topdir = CONFIG["topdir"]
+ hdrdir = $hdrdir
prefix = "../" * (target.count("/")+1)
- $hdrdir = $top_srcdir = relative_from(top_srcdir, prefix)
+ $top_srcdir = relative_from(top_srcdir, prefix)
+ $hdrdir = relative_from(hdrdir, prefix)
$topdir = prefix + $topdir
$target = target
$mdir = target
@@ -117,12 +117,31 @@ def extmake(target)
makefile = "./Makefile"
ok = File.exist?(makefile)
unless $ignore
- Config::CONFIG["hdrdir"] = $hdrdir
- Config::CONFIG["srcdir"] = $srcdir
- Config::CONFIG["topdir"] = $topdir
- CONFIG["hdrdir"] = ($hdrdir == top_srcdir) ? top_srcdir : "$(topdir)"+top_srcdir[2..-1]
- CONFIG["srcdir"] = "$(hdrdir)/ext/#{$mdir}"
- CONFIG["topdir"] = $topdir
+ rbconfig0 = Config::CONFIG
+ mkconfig0 = CONFIG
+ rbconfig = {
+ "hdrdir" => $hdrdir,
+ "srcdir" => $srcdir,
+ "topdir" => $topdir,
+ }
+ mkconfig = {
+ "top_srcdir" => ($hdrdir == top_srcdir) ? top_srcdir : "$(topdir)"+top_srcdir[2..-1],
+ "hdrdir" => "$(top_srcdir)",
+ "srcdir" => "$(top_srcdir)/ext/#{$mdir}",
+ "topdir" => $topdir,
+ }
+ rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}
+ mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}
+ Config.module_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, rbconfig)
+ remove_const(:MAKEFILE_CONFIG)
+ const_set(:MAKEFILE_CONFIG, mkconfig)
+ }
+ Object.class_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, mkconfig)
+ }
begin
$extconf_h = nil
ok &&= extract_makefile(makefile)
@@ -171,7 +190,11 @@ def extmake(target)
$ignore or $continue or return false
end
$compiled[target] = true
- if $clean and $clean != true
+ if $clean
+ FileUtils.rm_f("mkmf.log")
+ if $clean != true
+ FileUtils.rm_f([makefile, $extconf_h || "extconf.h"])
+ end
File.unlink(makefile) rescue nil
end
if $static
@@ -185,13 +208,21 @@ def extmake(target)
$extpath |= $LIBPATH
end
ensure
- Config::CONFIG["srcdir"] = $top_srcdir
- Config::CONFIG["topdir"] = topdir
- CONFIG["srcdir"] = mk_srcdir
- CONFIG["topdir"] = mk_topdir
- CONFIG.delete("hdrdir")
- $hdrdir = $top_srcdir = top_srcdir
+ unless $ignore
+ Config.module_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, rbconfig0)
+ remove_const(:MAKEFILE_CONFIG)
+ const_set(:MAKEFILE_CONFIG, mkconfig0)
+ }
+ Object.class_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, mkconfig0)
+ }
+ end
+ $top_srcdir = top_srcdir
$topdir = topdir
+ $hdrdir = hdrdir
Dir.chdir dir
end
begin
@@ -275,6 +306,7 @@ def parse_args()
$continue = $mflags.set?(?k)
if $extout
$extout = '$(topdir)/'+$extout
+ Config::CONFIG["extout"] = CONFIG["extout"] = $extout
$extout_prefix = $extout ? "$(extout)$(target_prefix)/" : ""
$mflags << "extout=#$extout" << "extout_prefix=#$extout_prefix"
end
@@ -313,7 +345,7 @@ elsif sep = config_string('BUILD_FILE_SEPARATOR')
else
$ruby = '$(topdir)/miniruby' + EXEEXT
end
-$ruby << " -I'$(topdir)' -I'$(hdrdir)/lib'"
+$ruby << " -I'$(topdir)' -I'$(top_srcdir)/lib'"
$config_h = '$(topdir)/config.h'
MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)}
@@ -398,12 +430,14 @@ dir = Dir.pwd
FileUtils::makedirs('ext')
Dir::chdir('ext')
+hdrdir = $hdrdir
$hdrdir = $top_srcdir = relative_from(srcdir, $topdir = "..")
exts.each do |d|
extmake(d) or abort
end
-$hdrdir = $top_srcdir = srcdir
+$top_srcdir = srcdir
$topdir = "."
+$hdrdir = hdrdir
extinit = Struct.new(:c, :o) {
def initialize(src)
diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c
index 918dd51630..484abd203d 100644
--- a/ext/iconv/iconv.c
+++ b/ext/iconv/iconv.c
@@ -423,8 +423,11 @@ iconv_convert
length = 0;
else if ((length -= start) < 0)
length = 0;
- else
+ else {
inptr += start;
+ if (length > slen)
+ length = slen;
+ }
}
instart = inptr;
inlen = length;
diff --git a/ext/openssl/lib/net/ftptls.rb b/ext/openssl/lib/net/ftptls.rb
index 43cc136bf6..e82eff72fa 100644
--- a/ext/openssl/lib/net/ftptls.rb
+++ b/ext/openssl/lib/net/ftptls.rb
@@ -29,13 +29,23 @@ require 'net/ftp'
module Net
class FTPTLS < FTP
+ def connect(host, port=FTP_PORT)
+ @hostname = host
+ super
+ end
+
def login(user = "anonymous", passwd = nil, acct = nil)
+ store = OpenSSL::X509::Store.new
+ store.set_default_paths
ctx = OpenSSL::SSL::SSLContext.new('SSLv23')
+ ctx.cert_store = store
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.key = nil
ctx.cert = nil
voidcmd("AUTH TLS")
@sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)
@sock.connect
+ @sock.post_connection_check(@hostname)
super(user, passwd, acct)
voidcmd("PBSZ 0")
end
diff --git a/ext/openssl/lib/net/telnets.rb b/ext/openssl/lib/net/telnets.rb
index d277a5c2a6..c869b5da1c 100644
--- a/ext/openssl/lib/net/telnets.rb
+++ b/ext/openssl/lib/net/telnets.rb
@@ -134,6 +134,9 @@ module Net
@sock.verify_callback = @options['VerifyCallback']
@sock.verify_depth = @options['VerifyDepth']
@sock.connect
+ if @options['VerifyMode'] != OpenSSL::SSL::VERIFY_NONE
+ @sock.post_connection_check(@options['Host'])
+ end
@ssl = true
end
''
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index abef21d823..d1007ce6d0 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -88,7 +88,7 @@ module OpenSSL
end
}
end
- raise SSLError, "hostname not match"
+ raise SSLError, "hostname was not match with the server certificate"
end
end
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index eaa1fe6eb2..336b468eb2 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -208,6 +208,7 @@ void ossl_debug(const char *, ...);
#include "ossl_ocsp.h"
#include "ossl_pkcs12.h"
#include "ossl_pkcs7.h"
+#include "ossl_pkcs5.h"
#include "ossl_pkey.h"
#include "ossl_rand.h"
#include "ossl_ssl.h"
diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c
index 1844022506..64998bb86a 100644
--- a/ext/openssl/ossl_config.c
+++ b/ext/openssl/ossl_config.c
@@ -245,7 +245,10 @@ set_conf_section_i(VALUE i, VALUE *arg)
static VALUE
ossl_config_set_section(VALUE self, VALUE section, VALUE hash)
{
- VALUE arg[2] = { self, section };
+ VALUE arg[2];
+
+ arg[0] = self;
+ arg[1] = section;
rb_iterate(rb_each, hash, set_conf_section_i, (VALUE)arg);
return hash;
}
diff --git a/ext/openssl/ossl_pkcs5.h b/ext/openssl/ossl_pkcs5.h
new file mode 100644
index 0000000000..a3b132bc50
--- /dev/null
+++ b/ext/openssl/ossl_pkcs5.h
@@ -0,0 +1,6 @@
+#if !defined(_OSSL_PKCS5_H_)
+#define _OSSL_PKCS5_H_
+
+void Init_ossl_pkcs5(void);
+
+#endif /* _OSSL_PKCS5_H_ */
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c
index 5c7e6e89a2..1a456f2c48 100644
--- a/ext/openssl/ossl_x509name.c
+++ b/ext/openssl/ossl_x509name.c
@@ -188,11 +188,11 @@ ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
return ossl_x509name_to_s_old(self);
else iflag = NUM2ULONG(flag);
if (!(out = BIO_new(BIO_s_mem())))
- rb_raise(eX509NameError, NULL);
+ ossl_raise(eX509NameError, NULL);
GetX509Name(self, name);
if (!X509_NAME_print_ex(out, name, 0, iflag)){
BIO_free(out);
- rb_raise(eX509NameError, NULL);
+ ossl_raise(eX509NameError, NULL);
}
str = ossl_membio2str(out);
diff --git a/ext/pty/lib/expect.rb b/ext/pty/lib/expect.rb
index aa9ab895d3..08191b05b9 100644
--- a/ext/pty/lib/expect.rb
+++ b/ext/pty/lib/expect.rb
@@ -10,7 +10,7 @@ class IO
e_pat = pat
end
while true
- if IO.select([self],nil,nil,timeout).nil? then
+ if !IO.select([self],nil,nil,timeout) or eof? then
result = nil
break
end
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 626898ae76..93fb5c0118 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -197,7 +197,7 @@ establishShell(argc, argv, info)
struct pty_info *info;
{
static int i,master,slave,currentPid;
- char *p,*getenv();
+ char *p, tmp, *getenv();
struct passwd *pwent;
VALUE v;
struct exec_info arg;
@@ -273,6 +273,7 @@ establishShell(argc, argv, info)
}
close(master);
#endif
+ write(slave, "", 1);
dup2(slave,0);
dup2(slave,1);
dup2(slave,2);
@@ -288,6 +289,7 @@ establishShell(argc, argv, info)
_exit(1);
}
+ read(master, &tmp, 1);
close(slave);
info->child_pid = i;
@@ -354,6 +356,7 @@ get_device_once(master, slave, fail)
#if defined I_PUSH && !defined linux
if(ioctl(j, I_PUSH, "ptem") != -1) {
if(ioctl(j, I_PUSH, "ldterm") != -1) {
+ ioctl(j, I_PUSH, "ttcompat");
#endif
*master = i;
*slave = j;
diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb
index b67a443dad..b820c0b32f 100644
--- a/ext/readline/extconf.rb
+++ b/ext/readline/extconf.rb
@@ -42,7 +42,9 @@ else
end
end
-have_readline_var("rl_filename_completion_function")
+have_func("rl_filename_completion_function")
+have_func("rl_username_completion_function")
+have_func("rl_completion_matches")
have_readline_var("rl_deprep_term_function")
have_readline_var("rl_completion_append_character")
have_readline_var("rl_basic_word_break_characters")
@@ -57,7 +59,6 @@ have_func("rl_cleanup_after_signal")
have_func("rl_clear_signals")
have_func("rl_vi_editing_mode")
have_func("rl_emacs_editing_mode")
-have_func("rl_clear_signals")
have_func("replace_history_entry")
have_func("remove_history")
create_makefile("readline")
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 4f840ee2c0..3625fadef8 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -38,17 +38,32 @@ static ID completion_proc, completion_case_fold;
# define rl_completion_matches completion_matches
#endif
-static int readline_event(void);
static char **readline_attempted_completion_function(const char *text,
int start, int end);
+#ifdef HAVE_RL_EVENT_HOOK
+#ifdef DOSISH
+#define BUSY_WAIT 1
+#else
+#define BUSY_WAIT 0
+#endif
+
+static int readline_event(void);
static int
readline_event()
{
- CHECK_INTS;
+#if BUSY_WAIT
rb_thread_schedule();
+#else
+ fd_set rset;
+
+ FD_ZERO(&rset);
+ FD_SET(fileno(rl_instream), &rset);
+ rb_thread_select(fileno(rl_instream) + 1, &rset, NULL, NULL, NULL);
return 0;
+#endif
}
+#endif
static VALUE
readline_readline(argc, argv, self)
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
index 11353e2345..7ffcf8579c 100644
--- a/ext/sdbm/_sdbm.c
+++ b/ext/sdbm/_sdbm.c
@@ -71,7 +71,7 @@ static int duppair proto((char *, datum));
#include <stdio.h>
#include <stdlib.h>
-#ifdef MSDOS
+#ifdef DOSISH
#include <io.h>
#endif
#include <sys/types.h>
diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c
index 4c9c8f03c4..66f7e8818a 100644
--- a/ext/socket/getnameinfo.c
+++ b/ext/socket/getnameinfo.c
@@ -35,6 +35,7 @@
*/
#include "config.h"
+#include <stdio.h>
#include <sys/types.h>
#ifndef _WIN32
#if defined(__BEOS__)
@@ -51,15 +52,11 @@
#endif
#include <netdb.h>
#if defined(HAVE_RESOLV_H)
-#ifdef _SX
-#include <stdio.h>
-#endif
#include <resolv.h>
#endif
#endif
#ifdef _WIN32
#include <winsock2.h>
-#include <stdio.h>
#define snprintf _snprintf
#endif
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 963f8e2d82..8558e99ee5 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -594,7 +594,7 @@ s_recvfrom(sock, argc, argv, from)
rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
}
#endif
- if (alen) /* OSX doesn't return a 'from' result from recvfrom for connection-oriented sockets */
+ if (alen && alen != sizeof(buf)) /* OSX doesn't return a 'from' result from recvfrom for connection-oriented sockets */
return rb_assoc_new(str, ipaddr((struct sockaddr*)buf));
else
return rb_assoc_new(str, Qnil);
@@ -660,7 +660,7 @@ s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
return str;
case RECV_IP:
- if (alen) /* connection-oriented socket may not return a from result */
+ if (alen && alen != sizeof(buf)) /* connection-oriented socket may not return a from result */
addr = ipaddr((struct sockaddr*)buf);
break;
@@ -1424,6 +1424,24 @@ tcp_svr_init(argc, argv, sock)
return init_inetsock(sock, Qnil, arg1, Qnil, Qnil, INET_SERVER);
}
+static void
+make_fd_nonblock(int fd)
+{
+ int flags;
+#ifdef F_GETFL
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1) {
+ rb_sys_fail(0);
+ }
+#else
+ flags = 0;
+#endif
+ flags |= O_NONBLOCK;
+ if (fcntl(fd, F_SETFL, flags) == -1) {
+ rb_sys_fail(0);
+ }
+}
+
static VALUE
s_accept_nonblock(VALUE klass, OpenFile *fptr, struct sockaddr *sockaddr, socklen_t *len)
{
@@ -1435,6 +1453,7 @@ s_accept_nonblock(VALUE klass, OpenFile *fptr, struct sockaddr *sockaddr, sockle
if (fd2 < 0) {
rb_sys_fail("accept(2)");
}
+ make_fd_nonblock(fd2);
return init_sock(rb_obj_alloc(klass), fd2);
}
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index 09867009b5..fcc596d5f0 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -136,6 +136,7 @@ check_modifiable(ptr)
static VALUE strio_s_allocate _((VALUE));
static VALUE strio_s_open _((int, VALUE *, VALUE));
+static void strio_init _((int, VALUE *, struct StringIO *));
static VALUE strio_initialize _((int, VALUE *, VALUE));
static VALUE strio_finalize _((VALUE));
static VALUE strio_self _((VALUE));
@@ -217,13 +218,24 @@ strio_initialize(argc, argv, self)
VALUE self;
{
struct StringIO *ptr = check_strio(self);
- VALUE string, mode;
- int trunc = Qfalse;
if (!ptr) {
DATA_PTR(self) = ptr = strio_alloc();
}
rb_call_super(0, 0);
+ strio_init(argc, argv, ptr);
+ return self;
+}
+
+static void
+strio_init(argc, argv, ptr)
+ int argc;
+ VALUE *argv;
+ struct StringIO *ptr;
+{
+ VALUE string, mode;
+ int trunc = Qfalse;
+
switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
case 2:
if (FIXNUM_P(mode)) {
@@ -255,7 +267,6 @@ strio_initialize(argc, argv, self)
break;
}
ptr->string = string;
- return self;
}
static VALUE
@@ -570,7 +581,8 @@ strio_reopen(argc, argv, self)
if (argc == 1 && TYPE(*argv) != T_STRING) {
return strio_copy(self, *argv);
}
- return strio_initialize(argc, argv, self);
+ strio_init(argc, argv, StringIO(self));
+ return self;
}
/*
diff --git a/ext/syck/syck.h b/ext/syck/syck.h
index 51a0f0aa9c..bc383ff2de 100644
--- a/ext/syck/syck.h
+++ b/ext/syck/syck.h
@@ -17,6 +17,7 @@
#define YAML_DOMAIN "yaml.org,2002"
#include <stdio.h>
+#include <stdlib.h>
#include <ctype.h>
#include "st.h"
@@ -399,6 +400,7 @@ int syck_scan_scalar( int, char *, long );
void syck_parser_handler( SyckParser *, SyckNodeHandler );
void syck_parser_error_handler( SyckParser *, SyckErrorHandler );
void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );
+void syck_parser_set_input_type( SyckParser *, enum syck_parser_input );
void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead );
void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead );
void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead );
diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c
index 10b79f2970..ff1f7640bd 100644
--- a/ext/tk/tcltklib.c
+++ b/ext/tk/tcltklib.c
@@ -4364,12 +4364,11 @@ delete_slaves(ip)
/* finalize operation */
-static VALUE
+static void
lib_mark_at_exit(self)
VALUE self;
{
at_exit = 1;
- return Qnil;
}
static int
@@ -4414,13 +4413,13 @@ ip_finalize(ip)
}
if (Tcl_InterpDeleted(ip)) {
- DUMP2("ip(%lx) is already deleted", ip);
+ DUMP2("ip(%p) is already deleted", ip);
return;
}
#if TCL_NAMESPACE_DEBUG
if (ip_null_namespace(ip)) {
- DUMP2("ip(%lx) has null namespace", ip);
+ DUMP2("ip(%p) has null namespace", ip);
return;
}
#endif
@@ -7995,8 +7994,6 @@ Init_tcltklib()
/* --------------------------------------------------------------- */
- rb_define_module_function(lib, "_mark_at_exit", lib_mark_at_exit, 0);
-
rb_define_module_function(lib, "mainloop", lib_mainloop, -1);
rb_define_module_function(lib, "mainloop_thread?",
lib_evloop_thread_p, 0);
@@ -8133,7 +8130,7 @@ Init_tcltklib()
/* --------------------------------------------------------------- */
- rb_eval_string("at_exit{ TclTkLib._mark_at_exit }");
+ rb_set_end_proc(lib_mark_at_exit, 0);
/* --------------------------------------------------------------- */
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index 9a55708498..4bb318cefd 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -78,7 +78,7 @@
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
-#define WIN32OLE_VERSION "0.7.1"
+#define WIN32OLE_VERSION "0.7.4"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -476,8 +476,9 @@ ole_wc2mb(pw)
LPSTR pm;
size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);
if (size) {
- pm = ALLOC_N(char, size);
+ pm = ALLOC_N(char, size + 1);
WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);
+ pm[size] = '\0';
}
else {
pm = ALLOC_N(char, 1);
@@ -496,7 +497,7 @@ ole_hresult2msg(hr)
DWORD dwCount;
char strhr[100];
- sprintf(strhr, " HRESULT error code:0x%08x\n ", hr);
+ sprintf(strhr, " HRESULT error code:0x%08lx\n ", hr);
msg = rb_str_new2(strhr);
dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -1137,12 +1138,13 @@ reg_enum_key(hkey, i)
HKEY hkey;
DWORD i;
{
- char buf[BUFSIZ];
- DWORD size_buf = sizeof(buf);
+ char buf[BUFSIZ + 1];
+ DWORD size_buf = sizeof(buf) - 1;
FILETIME ft;
LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
NULL, NULL, NULL, &ft);
if(err == ERROR_SUCCESS) {
+ buf[BUFSIZ] = '\0';
return rb_str_new2(buf);
}
return Qnil;
@@ -1153,10 +1155,11 @@ reg_get_val(hkey, subkey)
HKEY hkey;
const char *subkey;
{
- char buf[BUFSIZ];
- LONG size_buf = sizeof(buf);
+ char buf[BUFSIZ + 1];
+ LONG size_buf = sizeof(buf) - 1;
LONG err = RegQueryValue(hkey, subkey, buf, &size_buf);
if (err == ERROR_SUCCESS) {
+ buf[BUFSIZ] = '\0';
return rb_str_new2(buf);
}
return Qnil;
@@ -2099,7 +2102,7 @@ ole_invoke(argc, argv, self, wFlags)
&result, &excepinfo, &argErr);
if (FAILED(hr)) {
/* retry to call args by value */
- if(op.dp.cArgs > cNamedArgs) {
+ if(op.dp.cArgs >= cNamedArgs) {
for(i = cNamedArgs; i < op.dp.cArgs; i++) {
n = op.dp.cArgs - i + cNamedArgs - 1;
param = rb_ary_entry(paramS, i-cNamedArgs);
@@ -3617,8 +3620,10 @@ ole_type_progid(pTypeInfo)
if (FAILED(hr))
return progid;
hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
- if (SUCCEEDED(hr))
- progid = WC2VSTR(pbuf);
+ if (SUCCEEDED(hr)) {
+ progid = ole_wc2vstr(pbuf, FALSE);
+ CoTaskMemFree(pbuf);
+ }
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return progid;
}
@@ -4032,7 +4037,8 @@ folevariable_name(self)
return rb_ivar_get(self, rb_intern("name"));
}
-static ole_variable_ole_type(pTypeInfo, var_index)
+static VALUE
+ole_variable_ole_type(pTypeInfo, var_index)
ITypeInfo *pTypeInfo;
UINT var_index;
{
@@ -4076,7 +4082,8 @@ folevariable_ole_type(self)
return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
}
-static ole_variable_ole_type_detail(pTypeInfo, var_index)
+static VALUE
+ole_variable_ole_type_detail(pTypeInfo, var_index)
ITypeInfo *pTypeInfo;
UINT var_index;
{
@@ -4112,7 +4119,8 @@ folevariable_ole_type_detail(self)
return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
}
-static ole_variable_value(pTypeInfo, var_index)
+static VALUE
+ole_variable_value(pTypeInfo, var_index)
ITypeInfo *pTypeInfo;
UINT var_index;
{
@@ -4158,7 +4166,8 @@ folevariable_value(self)
return ole_variable_value(pvar->pTypeInfo, pvar->index);
}
-static ole_variable_visible(pTypeInfo, var_index)
+static VALUE
+ole_variable_visible(pTypeInfo, var_index)
ITypeInfo *pTypeInfo;
UINT var_index;
{
@@ -4630,7 +4639,8 @@ folemethod_visible(self)
return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
}
-static ole_method_event(pTypeInfo, method_index, method_name)
+static VALUE
+ole_method_event(pTypeInfo, method_index, method_name)
ITypeInfo *pTypeInfo;
WORD method_index;
VALUE method_name;
diff --git a/file.c b/file.c
index d492b6ecd7..e92dd7962b 100644
--- a/file.c
+++ b/file.c
@@ -15,12 +15,18 @@
#ifdef _WIN32
#include "missing/file.h"
#endif
+#ifdef __CYGWIN__
+#include <windows.h>
+#include <sys/cygwin.h>
+#endif
+#define OpenFile rb_io_t
#include "ruby.h"
#include "rubyio.h"
#include "rubysig.h"
#include "util.h"
#include "dln.h"
+#include <ctype.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -815,6 +821,7 @@ rb_file_lstat(obj)
#endif
}
+#ifndef HAVE_GROUP_MEMBER
static int
group_member(gid)
GETGROUPS_T gid;
@@ -844,6 +851,7 @@ group_member(gid)
#endif
return Qfalse;
}
+#endif
#ifndef S_IXUGO
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
@@ -2236,18 +2244,12 @@ rb_file_s_rename(klass, from, to)
errno = 0;
#endif
if (rename(src, dst) < 0) {
-#if defined __CYGWIN__
- extern unsigned long __attribute__((stdcall)) GetLastError(void);
- if (errno == 0) { /* This is a bug of old Cygwin */
- /* incorrect as cygwin errno, but the last resort */
- errno = GetLastError();
- }
-#elif defined DOSISH && !defined _WIN32
- if (errno == EEXIST
+#if defined DOSISH && !defined _WIN32
+ switch (errno) {
+ case EEXIST:
#if defined (__EMX__)
- || errno == EACCES
+ case EACCES:
#endif
- ) {
if (chmod(dst, 0666) == 0 &&
unlink(dst) == 0 &&
rename(src, dst) == 0)
@@ -2296,12 +2298,17 @@ rb_file_s_umask(argc, argv)
return INT2FIX(omask);
}
-#if defined DOSISH
+#ifdef __CYGWIN__
+#undef DOSISH
+#endif
+#if defined __CYGWIN__ || defined DOSISH
#define DOSISH_UNC
+#define DOSISH_DRIVE_LETTER
#define isdirsep(x) ((x) == '/' || (x) == '\\')
#else
#define isdirsep(x) ((x) == '/')
#endif
+
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
# if defined(DJGPP)
# define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))
@@ -2310,10 +2317,16 @@ rb_file_s_umask(argc, argv)
# endif
#endif
-#ifdef __CYGWIN__
-#undef DOSISH
-#define DOSISH_UNC
-#define DOSISH_DRIVE_LETTER
+#if defined _WIN32 || defined __CYGWIN__
+#define USE_NTFS 1
+#else
+#define USE_NTFS 0
+#endif
+
+#if USE_NTFS
+#define istrailinggabage(x) ((x) == '.' || (x) == ' ')
+#else
+#define istrailinggabage(x) 0
#endif
#ifdef DOSISH_DRIVE_LETTER
@@ -2445,6 +2458,30 @@ rb_path_end(path)
return (char *)path;
}
+#if USE_NTFS
+static char *
+ntfs_tail(const char *path)
+{
+ while (*path && *path != ':') {
+ if (istrailinggabage(*path)) {
+ const char *last = path++;
+ while (istrailinggabage(*path)) path++;
+ if (!*path || *path == ':') return (char *)last;
+ }
+ else if (isdirsep(*path)) {
+ const char *last = path++;
+ while (isdirsep(*path)) path++;
+ if (!*path) return (char *)last;
+ if (*path == ':') path++;
+ }
+ else {
+ path = CharNext(path);
+ }
+ }
+ return (char *)path;
+}
+#endif
+
#define BUFCHECK(cond) do {\
long bdiff = p - buf;\
while (cond) {\
@@ -2471,7 +2508,8 @@ static VALUE
file_expand_path(fname, dname, result)
VALUE fname, dname, result;
{
- char *s, *buf, *b, *p, *pend, *root;
+ const char *s, *b;
+ char *buf, *p, *pend, *root;
long buflen, dirlen;
int tainted;
@@ -2612,15 +2650,21 @@ file_expand_path(fname, dname, result)
case '.':
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
/* We must go back to the parent */
+ char *n;
*p = '\0';
- if (!(b = strrdirsep(root))) {
+ if (!(n = strrdirsep(root))) {
*p = '/';
}
else {
- p = b;
+ p = n;
}
b = ++s;
}
+#if USE_NTFS
+ else {
+ do *++s; while (istrailinggabage(*s));
+ }
+#endif
break;
case '/':
#if defined DOSISH || defined __CYGWIN__
@@ -2633,6 +2677,19 @@ file_expand_path(fname, dname, result)
break;
}
}
+#if USE_NTFS
+ else {
+ --s;
+ case ' ': {
+ const char *e = s;
+ while (istrailinggabage(*s)) s++;
+ if (!*s) {
+ s = e;
+ goto endpath;
+ }
+ }
+ }
+#endif
break;
case '/':
#if defined DOSISH || defined __CYGWIN__
@@ -2655,15 +2712,79 @@ file_expand_path(fname, dname, result)
}
if (s > b) {
+#if USE_NTFS
+ endpath:
+ if (s > b + 6 && strncasecmp(s - 6, ":$DATA", 6) == 0) {
+ /* alias of stream */
+ /* get rid of a bug of x64 VC++ */
+ if (*(s-7) == ':') s -= 7; /* prime */
+ else if (memchr(b, ':', s - 6 - b)) s -= 6; /* alternative */
+ }
+#endif
BUFCHECK(bdiff + (s-b) >= buflen);
memcpy(++p, b, s-b);
p += s-b;
}
if (p == skiproot(buf) - 1) p++;
+ buflen = p - buf;
- if (tainted) OBJ_TAINT(result);
- RSTRING(result)->len = p - buf;
+ RSTRING(result)->len = buflen;
*p = '\0';
+#if USE_NTFS
+ if (1 &&
+#ifdef __CYGWIN__
+ !(buf[0] == '/' && !buf[1]) &&
+#endif
+ !strpbrk(b = buf, "*?")) {
+ size_t len;
+ WIN32_FIND_DATA wfd;
+#ifdef __CYGWIN__
+ int lnk_added = 0, is_symlink = 0;
+ struct stat st;
+ char w32buf[MAXPATHLEN], sep = 0;
+ p = 0;
+ if (lstat(buf, &st) == 0 && S_ISLNK(st.st_mode)) {
+ is_symlink = 1;
+ p = strrdirsep(buf);
+ if (!p) p = skipprefix(buf);
+ if (p) {
+ sep = *p;
+ *p = '\0';
+ }
+ }
+ if (cygwin_conv_to_win32_path(buf, w32buf) == 0) {
+ b = w32buf;
+ }
+ if (p) *p = sep;
+ else p = buf;
+ if (is_symlink && b == w32buf) {
+ len = strlen(p);
+ if (len > 4 && strcasecmp(p + len - 4, ".lnk") != 0) {
+ lnk_added = 1;
+ strlcat(w32buf, ".lnk", sizeof(w32buf));
+ }
+ }
+#endif
+ HANDLE h = FindFirstFile(b, &wfd);
+ if (h != INVALID_HANDLE_VALUE) {
+ FindClose(h);
+ p = strrdirsep(buf);
+ len = strlen(wfd.cFileName);
+#ifdef __CYGWIN__
+ if (lnk_added && len > 4 &&
+ strcasecmp(wfd.cFileName + len - 4, ".lnk") == 0) {
+ len -= 4;
+ }
+#endif
+ if (!p) p = buf;
+ buflen = ++p - buf + len;
+ rb_str_resize(result, buflen);
+ memcpy(p, wfd.cFileName, len + 1);
+ }
+ }
+#endif
+
+ if (tainted) OBJ_TAINT(result);
return result;
}
@@ -2707,18 +2828,21 @@ rb_file_s_expand_path(argc, argv)
}
static int
-rmext(p, e)
+rmext(p, l1, e)
const char *p, *e;
+ int l1;
{
- int l1, l2;
+ int l2;
if (!e) return 0;
- l1 = chompdirsep(p) - p;
l2 = strlen(e);
if (l2 == 2 && e[1] == '*') {
- e = strrchr(p, *e);
- if (!e) return 0;
+ unsigned char c = *e;
+ e = p + l1;
+ do {
+ if (e <= p) return 0;
+ } while (*--e != c);
return e - p;
}
if (l1 < l2) return l1;
@@ -2753,7 +2877,7 @@ rb_file_s_basename(argc, argv)
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
char *root;
#endif
- int f;
+ int f, n;
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
StringValue(fext);
@@ -2787,18 +2911,22 @@ rb_file_s_basename(argc, argv)
#endif
#endif
}
- else if (!(p = strrdirsep(name))) {
- if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
- f = chompdirsep(name) - name;
- if (f == RSTRING(fname)->len) return fname;
- }
- p = name;
- }
else {
- while (isdirsep(*p)) p++; /* skip last / */
- if (NIL_P(fext) || !(f = rmext(p, StringValueCStr(fext)))) {
- f = chompdirsep(p) - p;
+ if (!(p = strrdirsep(name))) {
+ p = name;
}
+ else {
+ while (isdirsep(*p)) p++; /* skip last / */
+ }
+#if USE_NTFS
+ n = ntfs_tail(p) - p;
+#else
+ n = chompdirsep(p) - p;
+#endif
+ if (NIL_P(fext) || !(f = rmext(p, n, StringValueCStr(fext)))) {
+ f = n;
+ }
+ if (f == RSTRING(fname)->len) return fname;
}
basename = rb_str_new(p, f);
OBJ_INFECT(basename, fname);
@@ -2873,22 +3001,49 @@ static VALUE
rb_file_s_extname(klass, fname)
VALUE klass, fname;
{
- char *name, *p, *e;
+ const char *name, *p, *e;
VALUE extname;
name = StringValueCStr(fname);
p = strrdirsep(name); /* get the last path component */
if (!p)
- p = name;
+ p = name;
else
- p++;
-
- e = strrchr(p, '.'); /* get the last dot of the last component */
- if (!e || e == p || !e[1]) /* no dot, or the only dot is first or end? */
- return rb_str_new2("");
- extname = rb_str_new(e, chompdirsep(e) - e); /* keep the dot, too! */
- OBJ_INFECT(extname, fname);
- return extname;
+ name = ++p;
+
+ e = 0;
+ while (*p) {
+ if (*p == '.' || istrailinggabage(*p)) {
+#if USE_NTFS
+ const char *last = p++, *dot = last;
+ while (istrailinggabage(*p)) {
+ if (*p == '.') dot = p;
+ p++;
+ }
+ if (!*p || *p == ':') {
+ p = last;
+ break;
+ }
+ e = dot;
+ continue;
+#else
+ e = p; /* get the last dot of the last component */
+#endif
+ }
+#if USE_NTFS
+ else if (*p == ':') {
+ break;
+ }
+#endif
+ else if (isdirsep(*p))
+ break;
+ p = CharNext(p);
+ }
+ if (!e || e == name || e+1 == p) /* no dot, or the only dot is first or end? */
+ return rb_str_new(0, 0);
+ extname = rb_str_new(e, p - e); /* keep the dot, too! */
+ OBJ_INFECT(extname, fname);
+ return extname;
}
/*
@@ -3090,7 +3245,7 @@ rb_file_truncate(obj, len)
f = GetWriteFile(fptr);
fflush(f);
fseeko(f, (off_t)0, SEEK_CUR);
-#ifdef HAVE_TRUNCATE
+#ifdef HAVE_FTRUNCATE
if (ftruncate(fileno(f), pos) < 0)
rb_sys_fail(fptr->path);
#else
@@ -3118,8 +3273,10 @@ rb_file_truncate(obj, len)
# endif
#ifdef __CYGWIN__
-static int
#include <winerror.h>
+extern unsigned long __attribute__((stdcall)) GetLastError(void);
+
+static int
cygwin_flock(int fd, int op)
{
int old_errno = errno;
diff --git a/gc.c b/gc.c
index f2530f07ef..d0d00f934e 100644
--- a/gc.c
+++ b/gc.c
@@ -392,6 +392,9 @@ rb_newobj()
{
VALUE obj;
+ if (during_gc)
+ rb_bug("object allocation during garbage collection phase");
+
if (!freelist) garbage_collect();
obj = (VALUE)freelist;
@@ -449,20 +452,19 @@ static unsigned int STACK_LEVEL_MAX = 655300;
# if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
__attribute__ ((noinline))
# endif
-static VALUE *
-stack_end_address(void)
+static void
+stack_end_address(VALUE **stack_end_p)
{
- return (VALUE *)__builtin_frame_address(0);
+ VALUE stack_end;
+ *stack_end_p = &stack_end;
}
-# define SET_STACK_END VALUE *stack_end = stack_end_address()
+# define SET_STACK_END VALUE *stack_end; stack_end_address(&stack_end)
# else
# define SET_STACK_END VALUE *stack_end = alloca(1)
# endif
# define STACK_END (stack_end)
#endif
-#if defined(sparc) || defined(__sparc__)
-# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80)
-#elif STACK_GROW_DIRECTION < 0
+#if STACK_GROW_DIRECTION < 0
# define STACK_LENGTH (rb_gc_stack_start - STACK_END)
#elif STACK_GROW_DIRECTION > 0
# define STACK_LENGTH (STACK_END - rb_gc_stack_start + 1)
@@ -1555,38 +1557,6 @@ Init_heap()
}
static VALUE
-os_live_obj()
-{
- int i;
- int n = 0;
-
- for (i = 0; i < heaps_used; i++) {
- RVALUE *p, *pend;
-
- p = heaps[i].slot; pend = p + heaps[i].limit;
- for (;p < pend; p++) {
- if (p->as.basic.flags) {
- switch (TYPE(p)) {
- case T_ICLASS:
- case T_VARMAP:
- case T_SCOPE:
- case T_NODE:
- continue;
- case T_CLASS:
- if (FL_TEST(p, FL_SINGLETON)) continue;
- default:
- if (!p->as.basic.klass) continue;
- rb_yield((VALUE)p);
- n++;
- }
- }
- }
- }
-
- return INT2FIX(n);
-}
-
-static VALUE
os_obj_of(of)
VALUE of;
{
@@ -1600,6 +1570,7 @@ os_obj_of(of)
for (;p < pend; p++) {
if (p->as.basic.flags) {
switch (TYPE(p)) {
+ case T_NONE:
case T_ICLASS:
case T_VARMAP:
case T_SCOPE:
@@ -1609,7 +1580,7 @@ os_obj_of(of)
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
if (!p->as.basic.klass) continue;
- if (rb_obj_is_kind_of((VALUE)p, of)) {
+ if (!of || rb_obj_is_kind_of((VALUE)p, of)) {
rb_yield((VALUE)p);
n++;
}
@@ -1663,11 +1634,9 @@ os_each_obj(argc, argv)
rb_secure(4);
if (rb_scan_args(argc, argv, "01", &of) == 0) {
- return os_live_obj();
- }
- else {
- return os_obj_of(of);
+ of = 0;
}
+ return os_obj_of(of);
}
static VALUE finalizers;
@@ -1911,6 +1880,7 @@ id2ref(obj, objid)
VALUE obj, objid;
{
unsigned long ptr, p0;
+ int type;
rb_secure(4);
p0 = ptr = NUM2ULONG(objid);
@@ -1927,7 +1897,8 @@ id2ref(obj, objid)
return ID2SYM(symid);
}
- if (!is_pointer_to_heap((void *)ptr)|| BUILTIN_TYPE(ptr) >= T_BLKTAG) {
+ if (!is_pointer_to_heap((void *)ptr)||
+ (type = BUILTIN_TYPE(ptr)) >= T_BLKTAG || type == T_ICLASS) {
rb_raise(rb_eRangeError, "0x%lx is not id value", p0);
}
if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) {
diff --git a/hash.c b/hash.c
index deadb4c3a4..e3f6dc2050 100644
--- a/hash.c
+++ b/hash.c
@@ -590,6 +590,23 @@ index_i(key, value, args)
return ST_CONTINUE;
}
+static VALUE
+rb_hash_delete_key(hash, key)
+ VALUE hash, key;
+{
+ st_data_t ktmp = (st_data_t)key, val;
+
+ if (RHASH(hash)->iter_lev > 0) {
+ if (st_delete_safe(RHASH(hash)->tbl, &ktmp, &val, Qundef)) {
+ FL_SET(hash, HASH_DELETED);
+ return (VALUE)val;
+ }
+ }
+ else if (st_delete(RHASH(hash)->tbl, &ktmp, &val))
+ return (VALUE)val;
+ return Qundef;
+}
+
/*
* call-seq:
* hsh.index(value) => key
@@ -669,14 +686,8 @@ rb_hash_delete(hash, key)
VALUE val;
rb_hash_modify(hash);
- if (RHASH(hash)->iter_lev > 0) {
- if (st_delete_safe(RHASH(hash)->tbl, (st_data_t*)&key, &val, Qundef)) {
- FL_SET(hash, HASH_DELETED);
- return val;
- }
- }
- else if (st_delete(RHASH(hash)->tbl, (st_data_t*)&key, &val))
- return val;
+ val = rb_hash_delete_key(hash, key);
+ if (val != Qundef) return val;
if (rb_block_given_p()) {
return rb_yield(key);
}
@@ -684,7 +695,6 @@ rb_hash_delete(hash, key)
}
struct shift_var {
- int stop;
VALUE key;
VALUE val;
};
@@ -695,13 +705,23 @@ shift_i(key, value, var)
struct shift_var *var;
{
if (key == Qundef) return ST_CONTINUE;
- if (var->stop) return ST_STOP;
- var->stop = 1;
+ if (var->key != Qundef) return ST_STOP;
var->key = key;
var->val = value;
return ST_DELETE;
}
+static int
+shift_i_safe(key, value, var)
+ VALUE key, value;
+ struct shift_var *var;
+{
+ if (key == Qundef) return ST_CONTINUE;
+ var->key = key;
+ var->val = value;
+ return ST_STOP;
+}
+
/*
* call-seq:
* hsh.shift -> anArray or obj
@@ -722,10 +742,21 @@ rb_hash_shift(hash)
struct shift_var var;
rb_hash_modify(hash);
- var.stop = 0;
- rb_hash_foreach(hash, shift_i, (st_data_t)&var);
+ var.key = Qundef;
+ if (RHASH(hash)->iter_lev > 0) {
+ rb_hash_foreach(hash, shift_i_safe, (st_data_t)&var);
+ if (var.key != Qundef) {
+ st_data_t key = var.key;
+ if (st_delete_safe(RHASH(hash)->tbl, &key, 0, Qundef)) {
+ FL_SET(hash, HASH_DELETED);
+ }
+ }
+ }
+ else {
+ rb_hash_foreach(hash, shift_i, (st_data_t)&var);
+ }
- if (var.stop) {
+ if (var.key != Qundef) {
return rb_assoc_new(var.key, var.val);
}
else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
@@ -742,7 +773,7 @@ delete_if_i(key, value, hash)
{
if (key == Qundef) return ST_CONTINUE;
if (RTEST(rb_yield_values(2, key, value))) {
- rb_hash_delete(hash, key);
+ rb_hash_delete_key(hash, key);
}
return ST_CONTINUE;
}
diff --git a/intern.h b/intern.h
index 97577a7cfd..072997503a 100644
--- a/intern.h
+++ b/intern.h
@@ -113,6 +113,7 @@ VALUE rb_mod_ancestors _((VALUE));
VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_public_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
+VALUE rb_big_rshift(VALUE, VALUE);
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
VALUE rb_obj_singleton_methods _((int, VALUE*, VALUE));
void rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));
diff --git a/io.c b/io.c
index 9275acaea7..b59b39c148 100644
--- a/io.c
+++ b/io.c
@@ -245,6 +245,7 @@ flush_before_seek(fptr)
if (fptr->mode & FMODE_WBUF) {
io_fflush(GetWriteFile(fptr), fptr);
}
+ errno = 0;
return fptr;
}
@@ -668,7 +669,7 @@ rb_io_tell(io)
GetOpenFile(io, fptr);
pos = io_tell(fptr);
- if (pos < 0) rb_sys_fail(fptr->path);
+ if (pos < 0 && errno) rb_sys_fail(fptr->path);
return OFFT2NUM(pos);
}
@@ -683,7 +684,7 @@ rb_io_seek(io, offset, whence)
pos = NUM2OFFT(offset);
GetOpenFile(io, fptr);
pos = io_seek(fptr, pos, whence);
- if (pos < 0) rb_sys_fail(fptr->path);
+ if (pos < 0 && errno) rb_sys_fail(fptr->path);
clearerr(fptr->f);
return INT2FIX(0);
@@ -2168,6 +2169,7 @@ fptr_finalize(fptr, noraise)
{
int n1 = 0, n2 = 0, f1, f2 = -1;
+ errno = 0;
if (fptr->f2) {
f2 = fileno(fptr->f2);
while (n2 = 0, fflush(fptr->f2) < 0) {
@@ -3026,11 +3028,29 @@ pipe_open(pstr, pname, mode)
{
int modef = rb_io_mode_flags(mode);
OpenFile *fptr;
-
#if defined(DJGPP) || defined(__human68k__) || defined(__VMS)
FILE *f;
+#else
+ int pid;
+#ifdef _WIN32
+ FILE *fpr, *fpw;
+#else
+ int pr[2], pw[2];
+#endif
+#endif
+ volatile int doexec;
if (!pname) pname = StringValuePtr(pstr);
+ doexec = (strcmp("-", pname) != 0);
+
+#if defined(DJGPP) || defined(__human68k__) || defined(__VMS) || defined(_WIN32)
+ if (!doexec) {
+ rb_raise(rb_eNotImpError,
+ "fork() function is unimplemented on this machine");
+ }
+#endif
+
+#if defined(DJGPP) || defined(__human68k__) || defined(__VMS)
f = popen(pname, mode);
if (!f) rb_sys_fail(pname);
@@ -3052,11 +3072,6 @@ pipe_open(pstr, pname, mode)
}
#else
#ifdef _WIN32
- int pid;
- FILE *fpr, *fpw;
-
- if (!pname) pname = StringValuePtr(pstr);
-
retry:
pid = pipe_exec(pname, rb_io_mode_modenum(mode), &fpr, &fpw);
if (pid == -1) { /* exec failed */
@@ -3086,16 +3101,10 @@ retry:
return (VALUE)port;
}
#else
- int pid, pr[2], pw[2];
- volatile int doexec;
-
- if (!pname) pname = StringValuePtr(pstr);
-
if (((modef & FMODE_READABLE) && pipe(pr) == -1) ||
((modef & FMODE_WRITABLE) && pipe(pw) == -1))
rb_sys_fail(pname);
- doexec = (strcmp("-", pname) != 0);
if (!doexec) {
fflush(stdin); /* is it really needed? */
fflush(stdout);
@@ -3247,7 +3256,7 @@ rb_io_s_popen(argc, argv, klass)
mode = rb_io_modenum_mode(FIX2INT(pmode));
}
else {
- mode = rb_io_flags_mode(rb_io_mode_flags(StringValuePtr(pmode)));
+ mode = rb_io_flags_mode(rb_io_mode_flags(StringValueCStr(pmode)));
}
SafeStringValue(pname);
port = pipe_open(pname, 0, mode);
@@ -3275,12 +3284,13 @@ rb_open_file(argc, argv, io)
VALUE io;
{
VALUE fname, vmode, perm;
- char *mode;
+ char *path, *mode;
int flags, fmode;
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
SafeStringValue(fname);
+ path = StringValueCStr(fname);
if (FIXNUM_P(vmode) || !NIL_P(perm)) {
if (FIXNUM_P(vmode)) {
flags = FIX2INT(vmode);
@@ -3291,11 +3301,11 @@ rb_open_file(argc, argv, io)
}
fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
- rb_file_sysopen_internal(io, RSTRING(fname)->ptr, flags, fmode);
+ rb_file_sysopen_internal(io, path, flags, fmode);
}
else {
- mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode);
- rb_file_open_internal(io, RSTRING(fname)->ptr, mode);
+ mode = NIL_P(vmode) ? "r" : StringValueCStr(vmode);
+ rb_file_open_internal(io, path, mode);
}
return io;
}
@@ -3648,7 +3658,7 @@ rb_io_reopen(argc, argv, file)
}
if (!NIL_P(nmode)) {
- fptr->mode = rb_io_mode_flags(StringValuePtr(nmode));
+ fptr->mode = rb_io_mode_flags(StringValueCStr(nmode));
}
if (fptr->path) {
@@ -3656,7 +3666,7 @@ rb_io_reopen(argc, argv, file)
fptr->path = 0;
}
- fptr->path = strdup(RSTRING(fname)->ptr);
+ fptr->path = strdup(StringValueCStr(fname));
mode = rb_io_flags_mode(fptr->mode);
if (!fptr->f) {
fptr->f = rb_fopen(fptr->path, mode);
@@ -3667,16 +3677,16 @@ rb_io_reopen(argc, argv, file)
return file;
}
- if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == 0) {
+ if (freopen(fptr->path, mode, fptr->f) == 0) {
rb_sys_fail(fptr->path);
}
#ifdef USE_SETVBUF
if (setvbuf(fptr->f, NULL, _IOFBF, 0) != 0)
- rb_warn("setvbuf() can't be honoured for %s", RSTRING(fname)->ptr);
+ rb_warn("setvbuf() can't be honoured for %s", fptr->path);
#endif
if (fptr->f2) {
- if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == 0) {
+ if (freopen(fptr->path, "w", fptr->f2) == 0) {
rb_sys_fail(fptr->path);
}
}
@@ -4225,7 +4235,7 @@ rb_io_initialize(argc, argv, io)
}
else {
SafeStringValue(mode);
- flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
+ flags = rb_io_mode_modenum(StringValueCStr(mode));
}
}
else {
@@ -4395,7 +4405,7 @@ next_argv()
retry:
if (RARRAY(rb_argv)->len > 0) {
filename = rb_ary_shift(rb_argv);
- fn = StringValuePtr(filename);
+ fn = StringValueCStr(filename);
if (strlen(fn) == 1 && fn[0] == '-') {
current_file = rb_stdin;
if (ruby_inplace_mode) {
@@ -5056,7 +5066,7 @@ rb_f_syscall(argc, argv)
if (!NIL_P(v)) {
StringValue(v);
rb_str_modify(v);
- arg[i] = (unsigned long)RSTRING(v)->ptr;
+ arg[i] = (unsigned long)StringValueCStr(v);
}
else {
arg[i] = (unsigned long)NUM2LONG(*argv);
@@ -5264,7 +5274,7 @@ rb_io_s_foreach(argc, argv)
else if (!NIL_P(arg.sep)) {
StringValue(arg.sep);
}
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(StringValueCStr(fname), "r");
if (NIL_P(arg.io)) return Qnil;
return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
@@ -5303,7 +5313,7 @@ rb_io_s_readlines(argc, argv, io)
SafeStringValue(fname);
arg.argc = argc - 1;
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(StringValueCStr(fname), "r");
if (NIL_P(arg.io)) return Qnil;
return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);
}
@@ -5341,7 +5351,7 @@ rb_io_s_read(argc, argv, io)
SafeStringValue(fname);
arg.argc = argc ? 1 : 0;
- arg.io = rb_io_open(RSTRING(fname)->ptr, "r");
+ arg.io = rb_io_open(StringValueCStr(fname), "r");
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
rb_io_seek(arg.io, offset, SEEK_SET);
@@ -5617,7 +5627,7 @@ opt_i_set(val)
StringValue(val);
if (ruby_inplace_mode) free(ruby_inplace_mode);
ruby_inplace_mode = 0;
- ruby_inplace_mode = strdup(RSTRING(val)->ptr);
+ ruby_inplace_mode = strdup(StringValueCStr(val));
}
/*
diff --git a/lib/README b/lib/README
index 19d6309166..d60c5cb1e9 100644
--- a/lib/README
+++ b/lib/README
@@ -6,7 +6,7 @@ benchmark.rb a benchmark utility
cgi-lib.rb simple CGI support library (old style)
cgi.rb CGI support library
cgi/session.rb CGI session class
-complex.rb complex number suppor
+complex.rb complex number support
csv.rb CSV parser/generator
date.rb date object
date/format.rb date parsing and formatting
diff --git a/lib/base64.rb b/lib/base64.rb
index 410d76ffcd..d80eb5a570 100644
--- a/lib/base64.rb
+++ b/lib/base64.rb
@@ -110,7 +110,7 @@ module Base64
# UnVieQ==
def b64encode(bin, len = 60)
- encode64(bin).scan(/.{1,#{len}}/o) do
+ encode64(bin).scan(/.{1,#{len}}/) do
print $&, "\n"
end
end
diff --git a/lib/benchmark.rb b/lib/benchmark.rb
index ea62dcd208..36cd4b55a9 100644
--- a/lib/benchmark.rb
+++ b/lib/benchmark.rb
@@ -304,7 +304,10 @@ module Benchmark
# Returns the elapsed real time used to execute the given block.
#
def realtime(&blk) # :yield:
- Benchmark::measure(&blk).real
+ r0 = Time.now
+ yield
+ r1 = Time.now
+ r1.to_f - r0.to_f
end
@@ -330,7 +333,7 @@ module Benchmark
# Registers the given label and block pair in the job list.
#
def item(label = "", &blk) # :yield:
- raise ArgmentError, "no block" unless block_given?
+ raise ArgumentError, "no block" unless block_given?
label.concat ' '
w = label.length
@width = w if @width < w
diff --git a/lib/cgi.rb b/lib/cgi.rb
index d4bea54e7e..c07f412442 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -1032,21 +1032,21 @@ class CGI
if "--" == $2
content_length = -1
end
- boundary_end = $2.dup
+ boundary_end = $2.dup
""
end
body.rewind
- /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
- filename = ($1 or "")
+ /Content-Disposition:.* filename=(?:"((?:\\.|[^\"\s])*)"|([^;\s]*))/ni.match(head)
+ filename = ($1 or $2 or "")
if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
/Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
(not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
filename = CGI::unescape(filename)
end
- /Content-Type: (.*)/ni.match(head)
+ /Content-Type: ([^\s]*)/ni.match(head)
content_type = ($1 or "")
(class << body; self; end).class_eval do
@@ -1055,7 +1055,7 @@ class CGI
define_method(:content_type) {content_type.dup.taint}
end
- /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
+ /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head)
name = $1.dup
if params.has_key?(name)
@@ -1163,6 +1163,7 @@ class CGI
# retrieved; use #params() to get the array of values.
def [](key)
params = @params[key]
+ return '' unless params
value = params[0]
if @multipart
if value
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index 82eb7534d8..5568b28dce 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -391,8 +391,9 @@ class CGI
unless @hash
@hash = {}
begin
+ lockf = File.open(@path+".lock", "r")
+ lockf.flock File::LOCK_SH
f = File.open(@path, 'r')
- f.flock File::LOCK_SH
for line in f
line.chomp!
k, v = line.split('=',2)
@@ -400,6 +401,7 @@ class CGI
end
ensure
f.close unless f.nil?
+ lockf.close if lockf
end
end
@hash
@@ -409,13 +411,17 @@ class CGI
def update
return unless @hash
begin
- f = File.open(@path, File::CREAT|File::TRUNC|File::RDWR, 0600)
- f.flock File::LOCK_EX
+ lockf = File.open(@path+".lock", File::CREAT|File::RDWR, 0600)
+ lockf.flock File::LOCK_EX
+ f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
for k,v in @hash
f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(v))
end
+ f.close
+ File.rename @path+".new", @path
ensure
- f.close unless f.nil?
+ f.close if f and !f.closed?
+ lockf.close if lockf
end
end
@@ -426,6 +432,8 @@ class CGI
# Close and delete the session's FileStore file.
def delete
+ File::unlink @path+".lock" rescue nil
+ File::unlink @path+".new" rescue nil
File::unlink @path
rescue Errno::ENOENT
end
diff --git a/lib/irb.rb b/lib/irb.rb
index 65b1512740..1f49768b7d 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -149,10 +149,15 @@ module IRB
line.untaint
@context.evaluate(line, line_no)
output_value if @context.echo?
- rescue StandardError, ScriptError, Abort
- $! = RuntimeError.new("unknown exception raised") unless $!
- print $!.class, ": ", $!, "\n"
- if $@[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && $!.class.to_s !~ /^IRB/
+ exc = nil
+ rescue Interrupt => exc
+ rescue SystemExit, SignalException
+ raise
+ rescue Exception => exc
+ end
+ if exc
+ print exc.class, ": ", exc, "\n"
+ if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/
irb_bug = true
else
irb_bug = false
@@ -161,7 +166,7 @@ module IRB
messages = []
lasts = []
levels = 0
- for m in $@
+ for m in exc.backtrace
m = @context.workspace.filter_backtrace(m) unless irb_bug
if m
if messages.size < @context.back_trace_limit
@@ -183,8 +188,7 @@ module IRB
print "Maybe IRB bug!!\n" if irb_bug
end
if $SAFE > 2
- warn "Error: irb does not work for $SAFE level higher than 2"
- exit 1
+ abort "Error: irb does not work for $SAFE level higher than 2"
end
end
end
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 43ba202bed..563ce9e5f4 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -266,8 +266,7 @@ ensure
end
def link_command(ldflags, opt="", libpath=$LIBPATH)
- Config::expand(TRY_LINK.dup,
- CONFIG.merge('hdrdir' => $hdrdir.quote,
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,
'src' => CONFTEST_C,
'INCFLAGS' => $INCFLAGS,
'CPPFLAGS' => $CPPFLAGS,
@@ -276,17 +275,20 @@ def link_command(ldflags, opt="", libpath=$LIBPATH)
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
'LIBPATH' => libpathflag(libpath),
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
- 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS"))
+ 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
+ Config::expand(TRY_LINK.dup, conf)
end
def cc_command(opt="")
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
- CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote))
+ conf)
end
def cpp_command(outfile, opt="")
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
- CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote))
+ conf)
end
def libpathflag(libpath=$LIBPATH)
@@ -431,7 +433,7 @@ def try_var(var, headers = nil, &b)
#{headers}
/*top*/
int main() { return 0; }
-int t() { const volatile void *volatile p; p = (void *)&#{var}; return 0; }
+int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
SRC
end
@@ -1375,6 +1377,7 @@ site-install-rb: install-rb
unless suffixes.empty?
mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
end
+ mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
mfile.print depout
else
headers = %w[ruby.h defines.h]
@@ -1422,6 +1425,7 @@ def init_mkmf(config = CONFIG)
$LOCAL_LIBS = ""
$cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
+ $cleanfiles << "mkmf.log"
$distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
$extout ||= nil
diff --git a/lib/monitor.rb b/lib/monitor.rb
index 4ed4e41222..4c146c8086 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -105,14 +105,17 @@ module MonitorMixin
return false
ensure
Thread.critical = true
- if timer && timer.alive?
- Thread.kill(timer)
+ begin
+ if timer && timer.alive?
+ Thread.kill(timer)
+ end
+ if @waiters.include?(Thread.current) # interrupted?
+ @waiters.delete(Thread.current)
+ end
+ @monitor.instance_eval {mon_enter_for_cond(count)}
+ ensure
+ Thread.critical = false
end
- if @waiters.include?(Thread.current) # interrupted?
- @waiters.delete(Thread.current)
- end
- @monitor.instance_eval {mon_enter_for_cond(count)}
- Thread.critical = false
end
end
@@ -210,6 +213,7 @@ module MonitorMixin
Thread.critical = true
mon_acquire(@mon_entering_queue)
@mon_count += 1
+ ensure
Thread.critical = false
end
@@ -299,8 +303,9 @@ module MonitorMixin
def mon_exit_for_cond
count = @mon_count
@mon_count = 0
- mon_release
return count
+ ensure
+ mon_release
end
end
diff --git a/lib/net/http.rb b/lib/net/http.rb
index b62f97d374..d518f32cbb 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -584,6 +584,9 @@ module Net #:nodoc:
HTTPResponse.read_new(@socket).value
end
s.connect
+ if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ s.post_connection_check(@address)
+ end
end
on_connect
end
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 29b6359e0e..57e78ec135 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -284,7 +284,11 @@ module Net
# Disconnects from the server.
def disconnect
- @sock.shutdown unless @usessl
+ if SSL::SSLSocket === @sock
+ @sock.io.shutdown
+ else
+ @sock.shutdown
+ end
@receiver_thread.join
@sock.close
end
@@ -896,6 +900,7 @@ module Net
end
@sock = SSLSocket.new(@sock, context)
@sock.connect # start ssl session.
+ @sock.post_connection_check(@host) if verify
else
@usessl = false
end
@@ -3042,7 +3047,7 @@ module Net
elsif $7
return Token.new(T_RPAR, $+)
else
- parse_error("[Net::IMAP BUG] BEG_REGEXP is invalid")
+ parse_error("[Net::IMAP BUG] DATA_REGEXP is invalid")
end
else
@str.index(/\S*/n, @pos)
@@ -3096,7 +3101,7 @@ module Net
$stderr.printf("@str: %s\n", @str.dump)
$stderr.printf("@pos: %d\n", @pos)
$stderr.printf("@lex_state: %s\n", @lex_state)
- if @token.symbol
+ if @token
$stderr.printf("@token.symbol: %s\n", @token.symbol)
$stderr.printf("@token.value: %s\n", @token.value.inspect)
end
diff --git a/lib/net/telnet.rb b/lib/net/telnet.rb
index a2f6065dd7..c54401851c 100644
--- a/lib/net/telnet.rb
+++ b/lib/net/telnet.rb
@@ -705,7 +705,7 @@ module Net
# data is also yielded to the block as it is received.
def login(options, password = nil) # :yield: recvdata
login_prompt = /[Ll]ogin[: ]*\z/n
- password_prompt = /Password[: ]*\z/n
+ password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/n
if options.kind_of?(Hash)
username = options["Name"]
password = options["Password"]
diff --git a/lib/open-uri.rb b/lib/open-uri.rb
index d69f7dbe41..0dae95b6e6 100644
--- a/lib/open-uri.rb
+++ b/lib/open-uri.rb
@@ -240,16 +240,6 @@ module OpenURI
resp = nil
http.start {
- if target.class == URI::HTTPS
- # xxx: information hiding violation
- sock = http.instance_variable_get(:@socket)
- if sock.respond_to?(:io)
- sock = sock.io # 1.9
- else
- sock = sock.instance_variable_get(:@socket) # 1.8
- end
- sock.post_connection_check(target_host)
- end
req = Net::HTTP::Get.new(request_uri, header)
if options.include? :http_basic_authentication
user, pass = options[:http_basic_authentication]
diff --git a/lib/optparse.rb b/lib/optparse.rb
index c1df9586c8..d5a759d084 100644
--- a/lib/optparse.rb
+++ b/lib/optparse.rb
@@ -383,7 +383,7 @@ class OptionParser
while s = lopts.shift
l = left[-1].length + s.length
l += arg.length if left.size == 1 && arg
- l < max or left << ''
+ l < max or sopts.empty? or left << ''
left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s
end
diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb
index 53eee992e2..31441793c4 100644
--- a/lib/rdoc/options.rb
+++ b/lib/rdoc/options.rb
@@ -539,12 +539,12 @@ class Options
ver = nil
IO.popen("dot -V 2>&1") do |io|
ver = io.read
- if ver =~ /dot\s+version(?:\s+gviz)?\s+(\d+)\.(\d+)/
+ if ver =~ /dot.+version(?:\s+gviz)?\s+(\d+)\.(\d+)/
ok = ($1.to_i > 1) || ($1.to_i == 1 && $2.to_i >= 8)
end
end
unless ok
- if ver =~ /^dot version/
+ if ver =~ /^dot.+version/
$stderr.puts "Warning: You may need dot V1.8.6 or later to use\n",
"the --diagram option correctly. You have:\n\n ",
ver,
diff --git a/lib/rdoc/parsers/parse_c.rb b/lib/rdoc/parsers/parse_c.rb
index 19b5d443f6..fdec9c6b23 100644
--- a/lib/rdoc/parsers/parse_c.rb
+++ b/lib/rdoc/parsers/parse_c.rb
@@ -167,7 +167,7 @@ module RDoc
extend ParserFactory
- parse_files_matching(/\.(c|cc|cpp|CC)$/)
+ parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
@@known_bodies = {}
diff --git a/lib/resolv.rb b/lib/resolv.rb
index 49e40bdf07..898686fd3e 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -278,7 +278,7 @@ class Resolv
end
class Hosts
- if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
+ if /mswin32|mingw|bccwin/ =~ RUBY_PLATFORM
require 'win32/resolv'
DefaultFileName = Win32::Resolv.get_hosts_path
else
diff --git a/lib/rexml/dtd/dtd.rb b/lib/rexml/dtd/dtd.rb
index 81119cfa9b..4f735d4812 100644
--- a/lib/rexml/dtd/dtd.rb
+++ b/lib/rexml/dtd/dtd.rb
@@ -25,7 +25,7 @@ module REXML
when ElementDecl.PATTERN_RE
match = $&
source = $'
- contents << EleemntDecl.new( match )
+ contents << ElementDecl.new( match )
when AttlistDecl.PATTERN_RE
matchdata = $~
source = $'
diff --git a/lib/rexml/encodings/CP-1252.rb b/lib/rexml/encodings/CP-1252.rb
index 51179f119f..950ec4b57b 100644
--- a/lib/rexml/encodings/CP-1252.rb
+++ b/lib/rexml/encodings/CP-1252.rb
@@ -11,35 +11,35 @@ module REXML
array_utf8.each do |num|
case num
# shortcut first bunch basic characters
- when 0..0xFF: array_enc << num
+ when 0..0xFF; array_enc << num
# characters added compared to iso-8859-1
- when 0x20AC: array_enc << 0x80 # 0xe2 0x82 0xac
- when 0x201A: array_enc << 0x82 # 0xe2 0x82 0x9a
- when 0x0192: array_enc << 0x83 # 0xc6 0x92
- when 0x201E: array_enc << 0x84 # 0xe2 0x82 0x9e
- when 0x2026: array_enc << 0x85 # 0xe2 0x80 0xa6
- when 0x2020: array_enc << 0x86 # 0xe2 0x80 0xa0
- when 0x2021: array_enc << 0x87 # 0xe2 0x80 0xa1
- when 0x02C6: array_enc << 0x88 # 0xcb 0x86
- when 0x2030: array_enc << 0x89 # 0xe2 0x80 0xb0
- when 0x0160: array_enc << 0x8A # 0xc5 0xa0
- when 0x2039: array_enc << 0x8B # 0xe2 0x80 0xb9
- when 0x0152: array_enc << 0x8C # 0xc5 0x92
- when 0x017D: array_enc << 0x8E # 0xc5 0xbd
- when 0x2018: array_enc << 0x91 # 0xe2 0x80 0x98
- when 0x2019: array_enc << 0x92 # 0xe2 0x80 0x99
- when 0x201C: array_enc << 0x93 # 0xe2 0x80 0x9c
- when 0x201D: array_enc << 0x94 # 0xe2 0x80 0x9d
- when 0x2022: array_enc << 0x95 # 0xe2 0x80 0xa2
- when 0x2013: array_enc << 0x96 # 0xe2 0x80 0x93
- when 0x2014: array_enc << 0x97 # 0xe2 0x80 0x94
- when 0x02DC: array_enc << 0x98 # 0xcb 0x9c
- when 0x2122: array_enc << 0x99 # 0xe2 0x84 0xa2
- when 0x0161: array_enc << 0x9A # 0xc5 0xa1
- when 0x203A: array_enc << 0x9B # 0xe2 0x80 0xba
- when 0x0152: array_enc << 0x9C # 0xc5 0x93
- when 0x017E: array_enc << 0x9E # 0xc5 0xbe
- when 0x0178: array_enc << 0x9F # 0xc5 0xb8
+ when 0x20AC; array_enc << 0x80 # 0xe2 0x82 0xac
+ when 0x201A; array_enc << 0x82 # 0xe2 0x82 0x9a
+ when 0x0192; array_enc << 0x83 # 0xc6 0x92
+ when 0x201E; array_enc << 0x84 # 0xe2 0x82 0x9e
+ when 0x2026; array_enc << 0x85 # 0xe2 0x80 0xa6
+ when 0x2020; array_enc << 0x86 # 0xe2 0x80 0xa0
+ when 0x2021; array_enc << 0x87 # 0xe2 0x80 0xa1
+ when 0x02C6; array_enc << 0x88 # 0xcb 0x86
+ when 0x2030; array_enc << 0x89 # 0xe2 0x80 0xb0
+ when 0x0160; array_enc << 0x8A # 0xc5 0xa0
+ when 0x2039; array_enc << 0x8B # 0xe2 0x80 0xb9
+ when 0x0152; array_enc << 0x8C # 0xc5 0x92
+ when 0x017D; array_enc << 0x8E # 0xc5 0xbd
+ when 0x2018; array_enc << 0x91 # 0xe2 0x80 0x98
+ when 0x2019; array_enc << 0x92 # 0xe2 0x80 0x99
+ when 0x201C; array_enc << 0x93 # 0xe2 0x80 0x9c
+ when 0x201D; array_enc << 0x94 # 0xe2 0x80 0x9d
+ when 0x2022; array_enc << 0x95 # 0xe2 0x80 0xa2
+ when 0x2013; array_enc << 0x96 # 0xe2 0x80 0x93
+ when 0x2014; array_enc << 0x97 # 0xe2 0x80 0x94
+ when 0x02DC; array_enc << 0x98 # 0xcb 0x9c
+ when 0x2122; array_enc << 0x99 # 0xe2 0x84 0xa2
+ when 0x0161; array_enc << 0x9A # 0xc5 0xa1
+ when 0x203A; array_enc << 0x9B # 0xe2 0x80 0xba
+ when 0x0152; array_enc << 0x9C # 0xc5 0x93
+ when 0x017E; array_enc << 0x9E # 0xc5 0xbe
+ when 0x0178; array_enc << 0x9F # 0xc5 0xb8
else
# all remaining basic characters can be used directly
if num <= 0xFF
@@ -60,33 +60,33 @@ module REXML
array_latin9.each do |num|
case num
# characters that added compared to iso-8859-1
- when 0x80: array_enc << 0x20AC # 0xe2 0x82 0xac
- when 0x82: array_enc << 0x201A # 0xe2 0x82 0x9a
- when 0x83: array_enc << 0x0192 # 0xc6 0x92
- when 0x84: array_enc << 0x201E # 0xe2 0x82 0x9e
- when 0x85: array_enc << 0x2026 # 0xe2 0x80 0xa6
- when 0x86: array_enc << 0x2020 # 0xe2 0x80 0xa0
- when 0x87: array_enc << 0x2021 # 0xe2 0x80 0xa1
- when 0x88: array_enc << 0x02C6 # 0xcb 0x86
- when 0x89: array_enc << 0x2030 # 0xe2 0x80 0xb0
- when 0x8A: array_enc << 0x0160 # 0xc5 0xa0
- when 0x8B: array_enc << 0x2039 # 0xe2 0x80 0xb9
- when 0x8C: array_enc << 0x0152 # 0xc5 0x92
- when 0x8E: array_enc << 0x017D # 0xc5 0xbd
- when 0x91: array_enc << 0x2018 # 0xe2 0x80 0x98
- when 0x92: array_enc << 0x2019 # 0xe2 0x80 0x99
- when 0x93: array_enc << 0x201C # 0xe2 0x80 0x9c
- when 0x94: array_enc << 0x201D # 0xe2 0x80 0x9d
- when 0x95: array_enc << 0x2022 # 0xe2 0x80 0xa2
- when 0x96: array_enc << 0x2013 # 0xe2 0x80 0x93
- when 0x97: array_enc << 0x2014 # 0xe2 0x80 0x94
- when 0x98: array_enc << 0x02DC # 0xcb 0x9c
- when 0x99: array_enc << 0x2122 # 0xe2 0x84 0xa2
- when 0x9A: array_enc << 0x0161 # 0xc5 0xa1
- when 0x9B: array_enc << 0x203A # 0xe2 0x80 0xba
- when 0x9C: array_enc << 0x0152 # 0xc5 0x93
- when 0x9E: array_enc << 0x017E # 0xc5 0xbe
- when 0x9F: array_enc << 0x0178 # 0xc5 0xb8
+ when 0x80; array_enc << 0x20AC # 0xe2 0x82 0xac
+ when 0x82; array_enc << 0x201A # 0xe2 0x82 0x9a
+ when 0x83; array_enc << 0x0192 # 0xc6 0x92
+ when 0x84; array_enc << 0x201E # 0xe2 0x82 0x9e
+ when 0x85; array_enc << 0x2026 # 0xe2 0x80 0xa6
+ when 0x86; array_enc << 0x2020 # 0xe2 0x80 0xa0
+ when 0x87; array_enc << 0x2021 # 0xe2 0x80 0xa1
+ when 0x88; array_enc << 0x02C6 # 0xcb 0x86
+ when 0x89; array_enc << 0x2030 # 0xe2 0x80 0xb0
+ when 0x8A; array_enc << 0x0160 # 0xc5 0xa0
+ when 0x8B; array_enc << 0x2039 # 0xe2 0x80 0xb9
+ when 0x8C; array_enc << 0x0152 # 0xc5 0x92
+ when 0x8E; array_enc << 0x017D # 0xc5 0xbd
+ when 0x91; array_enc << 0x2018 # 0xe2 0x80 0x98
+ when 0x92; array_enc << 0x2019 # 0xe2 0x80 0x99
+ when 0x93; array_enc << 0x201C # 0xe2 0x80 0x9c
+ when 0x94; array_enc << 0x201D # 0xe2 0x80 0x9d
+ when 0x95; array_enc << 0x2022 # 0xe2 0x80 0xa2
+ when 0x96; array_enc << 0x2013 # 0xe2 0x80 0x93
+ when 0x97; array_enc << 0x2014 # 0xe2 0x80 0x94
+ when 0x98; array_enc << 0x02DC # 0xcb 0x9c
+ when 0x99; array_enc << 0x2122 # 0xe2 0x84 0xa2
+ when 0x9A; array_enc << 0x0161 # 0xc5 0xa1
+ when 0x9B; array_enc << 0x203A # 0xe2 0x80 0xba
+ when 0x9C; array_enc << 0x0152 # 0xc5 0x93
+ when 0x9E; array_enc << 0x017E # 0xc5 0xbe
+ when 0x9F; array_enc << 0x0178 # 0xc5 0xb8
else
array_enc << num
end
diff --git a/lib/rexml/encodings/ISO-8859-15.rb b/lib/rexml/encodings/ISO-8859-15.rb
index ce565e7dd5..8c7d84c90e 100644
--- a/lib/rexml/encodings/ISO-8859-15.rb
+++ b/lib/rexml/encodings/ISO-8859-15.rb
@@ -11,25 +11,25 @@ module REXML
array_utf8.each do |num|
case num
# shortcut first bunch basic characters
- when 0..0xA3: array_enc << num
+ when 0..0xA3; array_enc << num
# characters removed compared to iso-8859-1
- when 0xA4: array_enc << '&#164;'
- when 0xA6: array_enc << '&#166;'
- when 0xA8: array_enc << '&#168;'
- when 0xB4: array_enc << '&#180;'
- when 0xB8: array_enc << '&#184;'
- when 0xBC: array_enc << '&#188;'
- when 0xBD: array_enc << '&#189;'
- when 0xBE: array_enc << '&#190;'
+ when 0xA4; array_enc << '&#164;'
+ when 0xA6; array_enc << '&#166;'
+ when 0xA8; array_enc << '&#168;'
+ when 0xB4; array_enc << '&#180;'
+ when 0xB8; array_enc << '&#184;'
+ when 0xBC; array_enc << '&#188;'
+ when 0xBD; array_enc << '&#189;'
+ when 0xBE; array_enc << '&#190;'
# characters added compared to iso-8859-1
- when 0x20AC: array_enc << 0xA4 # 0xe2 0x82 0xac
- when 0x0160: array_enc << 0xA6 # 0xc5 0xa0
- when 0x0161: array_enc << 0xA8 # 0xc5 0xa1
- when 0x017D: array_enc << 0xB4 # 0xc5 0xbd
- when 0x017E: array_enc << 0xB8 # 0xc5 0xbe
- when 0x0152: array_enc << 0xBC # 0xc5 0x92
- when 0x0153: array_enc << 0xBD # 0xc5 0x93
- when 0x0178: array_enc << 0xBE # 0xc5 0xb8
+ when 0x20AC; array_enc << 0xA4 # 0xe2 0x82 0xac
+ when 0x0160; array_enc << 0xA6 # 0xc5 0xa0
+ when 0x0161; array_enc << 0xA8 # 0xc5 0xa1
+ when 0x017D; array_enc << 0xB4 # 0xc5 0xbd
+ when 0x017E; array_enc << 0xB8 # 0xc5 0xbe
+ when 0x0152; array_enc << 0xBC # 0xc5 0x92
+ when 0x0153; array_enc << 0xBD # 0xc5 0x93
+ when 0x0178; array_enc << 0xBE # 0xc5 0xb8
else
# all remaining basic characters can be used directly
if num <= 0xFF
@@ -50,14 +50,14 @@ module REXML
array_latin9.each do |num|
case num
# characters that differ compared to iso-8859-1
- when 0xA4: array_enc << 0x20AC
- when 0xA6: array_enc << 0x0160
- when 0xA8: array_enc << 0x0161
- when 0xB4: array_enc << 0x017D
- when 0xB8: array_enc << 0x017E
- when 0xBC: array_enc << 0x0152
- when 0xBD: array_enc << 0x0153
- when 0xBE: array_enc << 0x0178
+ when 0xA4; array_enc << 0x20AC
+ when 0xA6; array_enc << 0x0160
+ when 0xA8; array_enc << 0x0161
+ when 0xB4; array_enc << 0x017D
+ when 0xB8; array_enc << 0x017E
+ when 0xBC; array_enc << 0x0152
+ when 0xBD; array_enc << 0x0153
+ when 0xBE; array_enc << 0x0178
else
array_enc << num
end
diff --git a/lib/rexml/encodings/SHIFT-JIS.rb b/lib/rexml/encodings/SHIFT-JIS.rb
index 93c7877afd..9e0f4af20e 100644
--- a/lib/rexml/encodings/SHIFT-JIS.rb
+++ b/lib/rexml/encodings/SHIFT-JIS.rb
@@ -13,8 +13,8 @@ module REXML
rescue LoadError
require 'nkf'
- SJISTOU8 = '-Swm0'
- U8TOSJIS = '-Wsm0'
+ SJISTOU8 = '-Swm0x'
+ U8TOSJIS = '-Wsm0x'
def decode_sjis(str)
NKF.nkf(SJISTOU8, str)
diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
index cacab221db..dfe6c19f07 100644
--- a/lib/rexml/source.rb
+++ b/lib/rexml/source.rb
@@ -17,7 +17,7 @@ module REXML
elsif arg.kind_of? Source
arg
else
- raise "#{source.class} is not a valid input stream. It must walk \n"+
+ raise "#{arg.class} is not a valid input stream. It must walk \n"+
"like either a String, IO, or Source."
end
end
diff --git a/lib/rinda/tuplespace.rb b/lib/rinda/tuplespace.rb
index 73e79bb401..6d58a0fd15 100644
--- a/lib/rinda/tuplespace.rb
+++ b/lib/rinda/tuplespace.rb
@@ -404,7 +404,6 @@ module Rinda
def write(tuple, sec=nil)
entry = TupleEntry.new(tuple, sec)
- start_keeper
synchronize do
if entry.expired?
@read_waiter.find_all_template(entry).each do |template|
@@ -414,6 +413,7 @@ module Rinda
notify_event('delete', entry.value)
else
@bag.push(entry)
+ start_keeper if entry.expires
@read_waiter.find_all_template(entry).each do |template|
template.read(tuple)
end
@@ -439,7 +439,6 @@ module Rinda
def move(port, tuple, sec=nil)
template = WaitTemplateEntry.new(self, tuple, sec)
yield(template) if block_given?
- start_keeper
synchronize do
entry = @bag.find(template)
if entry
@@ -452,6 +451,7 @@ module Rinda
begin
@take_waiter.push(template)
+ start_keeper if template.expires
while true
raise RequestCanceledError if template.canceled?
raise RequestExpiredError if template.expired?
@@ -476,7 +476,6 @@ module Rinda
def read(tuple, sec=nil)
template = WaitTemplateEntry.new(self, tuple, sec)
yield(template) if block_given?
- start_keeper
synchronize do
entry = @bag.find(template)
return entry.value if entry
@@ -484,6 +483,7 @@ module Rinda
begin
@read_waiter.push(template)
+ start_keeper if template.expires
template.wait
raise RequestCanceledError if template.canceled?
raise RequestExpiredError if template.expired?
@@ -566,8 +566,11 @@ module Rinda
def start_keeper
return if @keeper && @keeper.alive?
@keeper = Thread.new do
- while need_keeper?
- keep_clean
+ while true
+ synchronize do
+ break unless need_keeper?
+ keep_clean
+ end
sleep(@period)
end
end
diff --git a/lib/timeout.rb b/lib/timeout.rb
index dc92964c0b..5a99c28092 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -32,8 +32,13 @@ module Timeout
##
# Raised by Timeout#timeout when the block times out.
- class Error<Interrupt
+ class Error < Interrupt
end
+ class ExitException < ::Exception # :nodoc:
+ end
+
+ THIS_FILE = /\A#{Regexp.quote(__FILE__)}:/o
+ CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0
##
# Executes the method's block. If the block execution terminates before +sec+
@@ -44,9 +49,10 @@ module Timeout
# Timeout' into your classes so they have a #timeout method, as well as a
# module method, so you can call it directly as Timeout.timeout().
- def timeout(sec, exception=Error)
+ def timeout(sec, klass = nil)
return yield if sec == nil or sec.zero?
raise ThreadError, "timeout within critical session" if Thread.critical
+ exception = klass || Class.new(ExitException)
begin
x = Thread.current
y = Thread.start {
@@ -55,6 +61,17 @@ module Timeout
}
yield sec
# return true
+ rescue exception => e
+ rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o
+ (bt = e.backtrace).reject! {|m| rej =~ m}
+ level = -caller(CALLER_OFFSET).size
+ while THIS_FILE =~ bt[level]
+ bt.delete_at(level)
+ level += 1
+ end
+ raise if klass # if exception class is specified, it
+ # would be expected outside.
+ raise Error, e.message, e.backtrace
ensure
y.kill if y and y.alive?
end
@@ -72,7 +89,7 @@ end
# Defined for backwards compatibility with earlier versions of timeout.rb, see
# Timeout#timeout.
-def timeout(n, e=Timeout::Error, &block) # :nodoc:
+def timeout(n, e = nil, &block) # :nodoc:
Timeout::timeout(n, e, &block)
end
diff --git a/lib/uri/common.rb b/lib/uri/common.rb
index 7a5207a315..9f58cdf918 100644
--- a/lib/uri/common.rb
+++ b/lib/uri/common.rb
@@ -110,7 +110,7 @@ module URI
SERVER = "(?:#{USERINFO}@)?#{HOSTPORT}"
# reg_name = 1*( unreserved | escaped | "$" | "," |
# ";" | ":" | "@" | "&" | "=" | "+" )
- REG_NAME = "(?:[#{UNRESERVED}$,;+@&=+]|#{ESCAPED})+"
+ REG_NAME = "(?:[#{UNRESERVED}$,;:@&=+]|#{ESCAPED})+"
# authority = server | reg_name
AUTHORITY = "(?:#{SERVER}|#{REG_NAME})"
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index b7a4cf6ef0..1bc90cb890 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -1100,8 +1100,9 @@ module URI
end
end
+ @@to_s = Kernel.instance_method(:to_s)
def inspect
- sprintf("#<%s:%#0x URL:%s>", self.class.to_s, self.object_id, self.to_s)
+ @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
end
def coerce(oth)
diff --git a/lib/webrick/httpservlet/abstract.rb b/lib/webrick/httpservlet/abstract.rb
index 03861e8fc7..5375c4622d 100644
--- a/lib/webrick/httpservlet/abstract.rb
+++ b/lib/webrick/httpservlet/abstract.rb
@@ -58,7 +58,7 @@ module WEBrick
def redirect_to_directory_uri(req, res)
if req.path[-1] != ?/
- location = req.path + "/"
+ location = WEBrick::HTTPUtils.escape_path(req.path + "/")
if req.query_string && req.query_string.size > 0
location << "?" << req.query_string
end
diff --git a/lib/webrick/httpservlet/cgi_runner.rb b/lib/webrick/httpservlet/cgi_runner.rb
index 1069a68d58..006abd458e 100644
--- a/lib/webrick/httpservlet/cgi_runner.rb
+++ b/lib/webrick/httpservlet/cgi_runner.rb
@@ -39,7 +39,9 @@ dir = File::dirname(ENV["SCRIPT_FILENAME"])
Dir::chdir dir
if interpreter = ARGV[0]
- exec(interpreter, ENV["SCRIPT_FILENAME"])
+ argv = ARGV.dup
+ argv << ENV["SCRIPT_FILENAME"]
+ exec(*argv)
# NOTREACHED
end
exec ENV["SCRIPT_FILENAME"]
diff --git a/lib/webrick/httpservlet/filehandler.rb b/lib/webrick/httpservlet/filehandler.rb
index 410cc6f9a9..24f59d7142 100644
--- a/lib/webrick/httpservlet/filehandler.rb
+++ b/lib/webrick/httpservlet/filehandler.rb
@@ -163,6 +163,7 @@ module WEBrick
end
end
end
+ prevent_directory_traversal(req, res)
super(req, res)
end
@@ -198,10 +199,38 @@ module WEBrick
private
+ def trailing_pathsep?(path)
+ # check for trailing path separator:
+ # File.dirname("/aaaa/bbbb/") #=> "/aaaa")
+ # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb")
+ # File.dirname("/aaaa/bbbb") #=> "/aaaa")
+ # File.dirname("/aaaa/bbbbx") #=> "/aaaa")
+ return File.dirname(path) != File.dirname(path+"x")
+ end
+
+ def prevent_directory_traversal(req, res)
+ # Preventing directory traversal on Windows platforms;
+ # Backslashes (0x5c) in path_info are not interpreted as special
+ # character in URI notation. So the value of path_info should be
+ # normalize before accessing to the filesystem.
+
+ if trailing_pathsep?(req.path_info)
+ # File.expand_path removes the trailing path separator.
+ # Adding a character is a workaround to save it.
+ # File.expand_path("/aaa/") #=> "/aaa"
+ # File.expand_path("/aaa/" + "x") #=> "/aaa/x"
+ expanded = File.expand_path(req.path_info + "x")
+ expanded.chop! # remove trailing "x"
+ else
+ expanded = File.expand_path(req.path_info)
+ end
+ req.path_info = expanded
+ end
+
def exec_handler(req, res)
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
if set_filename(req, res)
- handler = get_handler(req)
+ handler = get_handler(req, res)
call_callback(:HandlerCallback, req, res)
h = handler.get_instance(@config, res.filename)
h.service(req, res)
@@ -211,9 +240,13 @@ module WEBrick
return false
end
- def get_handler(req)
- suffix1 = (/\.(\w+)$/ =~ req.script_name) && $1.downcase
- suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ req.script_name) && $1.downcase
+ def get_handler(req, res)
+ suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
+ if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
+ if @options[:AcceptableLanguages].include?($2.downcase)
+ suffix2 = $1.downcase
+ end
+ end
handler_table = @options[:HandlerTable]
return handler_table[suffix1] || handler_table[suffix2] ||
HandlerTable[suffix1] || HandlerTable[suffix2] ||
@@ -226,15 +259,13 @@ module WEBrick
path_info.unshift("") # dummy for checking @root dir
while base = path_info.first
- check_filename(req, res, base)
break if base == "/"
- break unless File.directory?(res.filename + base)
+ break unless File.directory?(File.expand_path(res.filename + base))
shift_path_info(req, res, path_info)
call_callback(:DirectoryCallback, req, res)
end
if base = path_info.first
- check_filename(req, res, base)
if base == "/"
if file = search_index_file(req, res)
shift_path_info(req, res, path_info, file)
@@ -255,12 +286,10 @@ module WEBrick
end
def check_filename(req, res, name)
- @options[:NondisclosureName].each{|pattern|
- if File.fnmatch("/#{pattern}", name)
- @logger.warn("the request refers nondisclosure name `#{name}'.")
- raise HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- }
+ if nondisclosure_name?(name) || windows_ambiguous_name?(name)
+ @logger.warn("the request refers nondisclosure name `#{name}'.")
+ raise HTTPStatus::NotFound, "`#{req.path}' not found."
+ end
end
def shift_path_info(req, res, path_info, base=nil)
@@ -268,7 +297,8 @@ module WEBrick
base = base || tmp
req.path_info = path_info.join
req.script_name << base
- res.filename << base
+ res.filename = File.expand_path(res.filename + base)
+ check_filename(req, res, File.basename(res.filename))
end
def search_index_file(req, res)
@@ -308,9 +338,15 @@ module WEBrick
end
end
+ def windows_ambiguous_name?(name)
+ return true if /[. ]+\z/ =~ name
+ return true if /::\$DATA\z/ =~ name
+ return false
+ end
+
def nondisclosure_name?(name)
@options[:NondisclosureName].each{|pattern|
- if File.fnmatch(pattern, name)
+ if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
return true
end
}
@@ -326,7 +362,8 @@ module WEBrick
list = Dir::entries(local_path).collect{|name|
next if name == "." || name == ".."
next if nondisclosure_name?(name)
- st = (File::stat(local_path + name) rescue nil)
+ next if windows_ambiguous_name?(name)
+ st = (File::stat(File.join(local_path, name)) rescue nil)
if st.nil?
[ name, nil, -1 ]
elsif st.directory?
@@ -366,7 +403,7 @@ module WEBrick
res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
res.body << "<HR>\n"
- list.unshift [ "..", File::mtime(local_path+".."), -1 ]
+ list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
list.each{ |name, time, size|
if name == ".."
dname = "Parent Directory"
diff --git a/lib/xmlrpc/client.rb b/lib/xmlrpc/client.rb
index 4d23e31e3e..b3682f6b09 100644
--- a/lib/xmlrpc/client.rb
+++ b/lib/xmlrpc/client.rb
@@ -530,6 +530,9 @@ module XMLRPC
}
else
# reuse the HTTP object for each call => connection alive is possible
+ # we must start connection explicitely first time so that http.request
+ # does not assume that we don't want keepalive
+ @http.start if not @http.started?
# post request
resp = @http.post2(@path, request, header)
@@ -549,9 +552,9 @@ module XMLRPC
ct = parse_content_type(resp["Content-Type"]).first
if ct != "text/xml"
if ct == "text/html"
- raise "Wrong content-type: \n#{data}"
+ raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}"
else
- raise "Wrong content-type"
+ raise "Wrong content-type (received '#{ct}' but expected 'text/xml')"
end
end
diff --git a/lib/xmlrpc/parser.rb b/lib/xmlrpc/parser.rb
index e4f21edec6..7490f34e84 100644
--- a/lib/xmlrpc/parser.rb
+++ b/lib/xmlrpc/parser.rb
@@ -92,7 +92,7 @@ module XMLRPC
if $7
ofs = $8.to_i*3600 + $9.to_i*60
ofs = -ofs if $7=='+'
- utc = Time.utc(a.reverse) + ofs
+ utc = Time.utc(*a) + ofs
a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
end
XMLRPC::DateTime.new(*a)
@@ -106,7 +106,7 @@ module XMLRPC
if $7
ofs = $8.to_i*3600 + $9.to_i*60
ofs = -ofs if $7=='+'
- utc = Time.utc(a.reverse) + ofs
+ utc = Time.utc(*a) + ofs
a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]
end
XMLRPC::DateTime.new(*a)
diff --git a/lib/xmlrpc/server.rb b/lib/xmlrpc/server.rb
index 7900a1d920..5166d7619f 100644
--- a/lib/xmlrpc/server.rb
+++ b/lib/xmlrpc/server.rb
@@ -639,11 +639,11 @@ class Server < WEBrickServlet
def serve
if RUBY_PLATFORM =~ /mingw|mswin32/
- signal = 1
+ signals = [1]
else
- signal = "HUP"
+ signals = %w[INT TERM HUP]
end
- trap(signal) { @server.shutdown }
+ signals.each { |signal| trap(signal) { @server.shutdown } }
@server.start
end
diff --git a/lib/xmlrpc/utils.rb b/lib/xmlrpc/utils.rb
index b0a4a0d987..2b51083c78 100644
--- a/lib/xmlrpc/utils.rb
+++ b/lib/xmlrpc/utils.rb
@@ -157,7 +157,7 @@ module XMLRPC
module ParseContentType
def parse_content_type(str)
a, *b = str.split(";")
- return a.strip, *b
+ return a.strip.downcase, *b
end
end
diff --git a/marshal.c b/marshal.c
index 386a3e6206..cccf26fd7b 100644
--- a/marshal.c
+++ b/marshal.c
@@ -373,8 +373,8 @@ w_extended(klass, arg, check)
{
char *path;
- if (FL_TEST(klass, FL_SINGLETON)) {
- if (check && RCLASS(klass)->m_tbl->num_entries ||
+ if (check && FL_TEST(klass, FL_SINGLETON)) {
+ if (RCLASS(klass)->m_tbl->num_entries ||
(RCLASS(klass)->iv_tbl && RCLASS(klass)->iv_tbl->num_entries > 1)) {
rb_raise(rb_eTypeError, "singleton can't be dumped");
}
@@ -468,7 +468,7 @@ w_object(obj, arg, limit)
return;
}
- if (ivtbl = rb_generic_ivar_table(obj)) {
+ if ((ivtbl = rb_generic_ivar_table(obj)) != 0) {
w_byte(TYPE_IVAR, arg);
}
if (obj == Qnil) {
@@ -652,13 +652,13 @@ w_object(obj, arg, limit)
{
VALUE v;
- w_class(TYPE_DATA, obj, arg, Qtrue);
if (!rb_respond_to(obj, s_dump_data)) {
rb_raise(rb_eTypeError,
"no marshal_dump is defined for class %s",
rb_obj_classname(obj));
}
v = rb_funcall(obj, s_dump_data, 0);
+ w_class(TYPE_DATA, obj, arg, Qtrue);
w_object(v, arg, limit);
}
break;
@@ -873,7 +873,7 @@ r_bytes0(len, arg)
if (len == 0) return rb_str_new(0, 0);
if (TYPE(arg->src) == T_STRING) {
- if (RSTRING(arg->src)->len > arg->offset) {
+ if (RSTRING(arg->src)->len - arg->offset >= len) {
str = rb_str_new(RSTRING(arg->src)->ptr+arg->offset, len);
arg->offset += len;
}
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el
index 21e1b4664c..3fe99017d9 100644
--- a/misc/ruby-mode.el
+++ b/misc/ruby-mode.el
@@ -255,7 +255,7 @@ The variable ruby-indent-level controls the amount of indentation.
(make-local-variable 'add-log-current-defun-function)
(setq add-log-current-defun-function 'ruby-add-log-current-method)
- (run-hooks 'ruby-mode-hook))
+ (run-mode-hooks 'ruby-mode-hook))
(defun ruby-current-indentation ()
(save-excursion
diff --git a/missing/isinf.c b/missing/isinf.c
index e44ef6c3c1..c9e49c6795 100644
--- a/missing/isinf.c
+++ b/missing/isinf.c
@@ -28,12 +28,19 @@ isinf(n)
#include <ieeefp.h>
#endif
+/*
+ * isinf may be provided only as a macro.
+ * ex. HP-UX, Solaris 10
+ * http://www.gnu.org/software/automake/manual/autoconf/Function-Portability.html
+ */
+#ifndef isinf
int
isinf(n)
double n;
{
return (!finite(n) && !isnan(n));
}
+#endif
#else
diff --git a/missing/strftime.c b/missing/strftime.c
index 5522226ec1..caa5eb8719 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -115,17 +115,22 @@ extern char *strchr();
#define range(low, item, hi) max(low, min(item, hi))
+#ifdef __CYGWIN__
+#define DLL_IMPORT __declspec(dllimport)
+#endif
+#ifdef __WIN32__
+#define DLL_IMPORT __declspec(dllimport)
+#endif
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
-extern char *tzname[2];
-extern int daylight;
-#ifdef SOLARIS
-extern long timezone, altzone;
-#else
-#ifdef __hpux
-extern long timezone;
-#else
-extern int timezone, altzone;
+extern DLL_IMPORT char *tzname[2];
+#ifdef HAVE_DAYLIGHT
+extern DLL_IMPORT int daylight;
+#endif
+#ifdef HAVE_VAR_TIMEZONE
+extern DLL_IMPORT TYPEOF_VAR_TIMEZONE timezone;
#endif
+#ifdef HAVE_VAR_ALTZONE
+extern DLL_IMPORT TYPEOF_VAR_ALTZONE altzone;
#endif
#endif
@@ -189,16 +194,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
#endif /* POSIX_SEMANTICS */
#ifndef HAVE_TM_ZONE
#ifndef HAVE_TM_NAME
-#ifndef HAVE_TZNAME
- extern char *timezone();
struct timeval tv;
struct timezone zone;
-#else
-#ifdef __hpux
- struct timeval tv;
- struct timezone zone;
-#endif
-#endif /* HAVE_TZNAME */
#endif /* HAVE_TM_NAME */
#endif /* HAVE_TM_ZONE */
@@ -422,21 +419,18 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
*/
off = timeptr->tm_gmtoff / 60;
#else /* !HAVE_TM_ZONE */
-#if HAVE_TZNAME
- /*
- * Systems with tzname[] probably have timezone as
- * secs west of GMT. Convert to mins east of GMT.
- */
-#ifdef __hpux
+#ifdef HAVE_GETTIMEOFDAY
gettimeofday(&tv, &zone);
off = -zone.tz_minuteswest;
#else
+#if HAVE_VAR_TIMEZONE
+#if HAVE_VAR_ALTZONE
off = -(daylight ? timezone : altzone) / 60;
+#else
+ off = -timezone / 60;
+#endif
+#endif
#endif
-#else /* !HAVE_TZNAME */
- gettimeofday(&tv, &zone);
- off = -zone.tz_minuteswest;
-#endif /* !HAVE_TZNAME */
#endif /* !HAVE_TM_ZONE */
#endif /* !HAVE_TM_NAME */
if (off < 0) {
@@ -445,7 +439,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
} else {
tbuf[0] = '+';
}
- sprintf(tbuf+1, "%02d%02d", off/60, off%60);
+ sprintf(tbuf+1, "%02u%02u", (unsigned)off/60, (unsigned)off%60);
break;
#endif /* MAILHEADER_EXT */
@@ -460,13 +454,15 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
#ifdef HAVE_TM_NAME
strcpy(tbuf, timeptr->tm_name);
#else
+#ifdef HAVE_TIMEZONE
gettimeofday(& tv, & zone);
-#ifdef __CYGWIN__
+#ifdef TIMEZONE_VOID
strcpy(tbuf, timezone());
#else
strcpy(tbuf, timezone(zone.tz_minuteswest,
timeptr->tm_isdst > 0));
-#endif
+#endif /* TIMEZONE_VOID */
+#endif /* HAVE_TIMEZONE */
#endif /* HAVE_TM_NAME */
#endif /* HAVE_TM_ZONE */
#endif /* HAVE_TZNAME */
@@ -645,7 +641,7 @@ iso8601wknum(const struct tm *timeptr)
* main body of the standard. Thus it requires week 53.
*/
- int weeknum, jan1day, diff;
+ int weeknum, jan1day;
/* get week number, Monday as first day of the week */
weeknum = weeknumber(timeptr, 1);
diff --git a/numeric.c b/numeric.c
index fae862ae0a..52775a744a 100644
--- a/numeric.c
+++ b/numeric.c
@@ -63,6 +63,25 @@
#define DBL_EPSILON 2.2204460492503131e-16
#endif
+#ifndef HAVE_ROUND
+double
+round(x)
+ double x;
+{
+ double f;
+
+ if (x > 0.0) {
+ f = floor(x);
+ x = f + (x - f >= 0.5);
+ }
+ else if (x < 0.0) {
+ f = ceil(x);
+ x = f - (f - x >= 0.5);
+ }
+ return x;
+}
+#endif
+
static ID id_coerce, id_to_i, id_eq;
VALUE rb_cNumeric;
@@ -662,7 +681,10 @@ flodivmod(x, y, divp, modp)
mod = x - z * y;
}
#endif
- div = (x - mod) / y;
+ if (isinf(x) && !isinf(y) && !isnan(y))
+ div = x;
+ else
+ div = (x - mod) / y;
if (y*mod < 0) {
mod += y;
div -= 1.0;
@@ -735,11 +757,14 @@ flo_divmod(x, y)
}
flodivmod(RFLOAT(x)->value, fy, &div, &mod);
if (FIXABLE(div)) {
- val = div;
- a = LONG2FIX(val);
+ val = round(div);
+ a = LONG2FIX(val);
+ }
+ else if (isnan(div) || isinf(div)) {
+ a = rb_float_new(div);
}
else {
- a = rb_dbl2big(div);
+ a = rb_dbl2big(div);
}
b = rb_float_new(mod);
return rb_assoc_new(a, b);
@@ -1291,8 +1316,7 @@ flo_round(num)
double f = RFLOAT(num)->value;
long val;
- if (f > 0.0) f = floor(f+0.5);
- if (f < 0.0) f = ceil(f-0.5);
+ f = round(f);
if (!FIXABLE(f)) {
return rb_dbl2big(f);
@@ -1513,6 +1537,7 @@ long
rb_num2long(val)
VALUE val;
{
+ again:
if (NIL_P(val)) {
rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
}
@@ -1530,7 +1555,7 @@ rb_num2long(val)
char *s;
sprintf(buf, "%-.10g", RFLOAT(val)->value);
- if (s = strchr(buf, ' ')) *s = '\0';
+ if ((s = strchr(buf, ' ')) != 0) *s = '\0';
rb_raise(rb_eRangeError, "float %s out of range of integer", buf);
}
@@ -1539,7 +1564,7 @@ rb_num2long(val)
default:
val = rb_to_int(val);
- return NUM2LONG(val);
+ goto again;
}
}
@@ -1681,7 +1706,7 @@ rb_num2ll(val)
char *s;
sprintf(buf, "%-.10g", RFLOAT(val)->value);
- if (s = strchr(buf, ' ')) *s = '\0';
+ if ((s = strchr(buf, ' ')) != 0) *s = '\0';
rb_raise(rb_eRangeError, "float %s out of range of long long", buf);
}
@@ -2179,6 +2204,15 @@ fix_divmod(x, y)
return rb_num_coerce_bin(x, y);
}
+static VALUE
+int_even_p(VALUE num)
+{
+ if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
/*
* call-seq:
* fix ** other => Numeric
@@ -2195,22 +2229,51 @@ static VALUE
fix_pow(x, y)
VALUE x, y;
{
+ static const double zero = 0.0;
+ long a = FIX2LONG(x);
+
if (FIXNUM_P(y)) {
- long a, b;
+ long b;
b = FIX2LONG(y);
if (b == 0) return INT2FIX(1);
if (b == 1) return x;
a = FIX2LONG(x);
+ if (a == 0) {
+ if (b > 0) return INT2FIX(0);
+ return rb_float_new(1.0 / zero);
+ }
+ if (a == 1) return INT2FIX(1);
+ if (a == -1) {
+ if (b % 2 == 0)
+ return INT2FIX(1);
+ else
+ return INT2FIX(-1);
+ }
if (b > 0) {
return rb_big_pow(rb_int2big(a), y);
}
return rb_float_new(pow((double)a, (double)b));
- } else if (TYPE(y) == T_FLOAT) {
- long a = FIX2LONG(x);
- return rb_float_new(pow((double)a, RFLOAT(y)->value));
}
- return rb_num_coerce_bin(x, y);
+ switch (TYPE(y)) {
+ case T_BIGNUM:
+ if (a == 0) return INT2FIX(0);
+ if (a == 1) return INT2FIX(1);
+ if (a == -1) {
+ if (int_even_p(y)) return INT2FIX(1);
+ else return INT2FIX(-1);
+ }
+ x = rb_int2big(FIX2LONG(x));
+ return rb_big_pow(x, y);
+ case T_FLOAT:
+ if (a == 0) {
+ return rb_float_new(RFLOAT(y)->value < 0 ? (1.0 / zero) : 0.0);
+ }
+ if (a == 1) return rb_float_new(1.0);
+ return rb_float_new(pow((double)a, RFLOAT(y)->value));
+ default:
+ return rb_num_coerce_bin(x, y);
+ }
}
/*
@@ -2370,6 +2433,16 @@ fix_rev(num)
return LONG2NUM(val);
}
+static VALUE
+fix_coerce(x)
+ VALUE x;
+{
+ while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {
+ x = rb_to_int(x);
+ }
+ return x;
+}
+
/*
* call-seq:
* fix & other => integer
@@ -2383,10 +2456,10 @@ fix_and(x, y)
{
long val;
- if (TYPE(y) == T_BIGNUM) {
+ if (!FIXNUM_P(y = fix_coerce(y))) {
return rb_big_and(y, x);
}
- val = FIX2LONG(x) & NUM2LONG(y);
+ val = FIX2LONG(x) & FIX2LONG(y);
return LONG2NUM(val);
}
@@ -2403,10 +2476,10 @@ fix_or(x, y)
{
long val;
- if (TYPE(y) == T_BIGNUM) {
+ if (!FIXNUM_P(y = fix_coerce(y))) {
return rb_big_or(y, x);
}
- val = FIX2LONG(x) | NUM2LONG(y);
+ val = FIX2LONG(x) | FIX2LONG(y);
return LONG2NUM(val);
}
@@ -2423,14 +2496,15 @@ fix_xor(x, y)
{
long val;
- if (TYPE(y) == T_BIGNUM) {
+ if (!FIXNUM_P(y = fix_coerce(y))) {
return rb_big_xor(y, x);
}
- val = FIX2LONG(x) ^ NUM2LONG(y);
+ val = FIX2LONG(x) ^ FIX2LONG(y);
return LONG2NUM(val);
}
-static VALUE fix_rshift _((VALUE, VALUE));
+static VALUE fix_lshift _((long, unsigned long));
+static VALUE fix_rshift _((long, unsigned long));
/*
* call-seq:
@@ -2440,18 +2514,28 @@ static VALUE fix_rshift _((VALUE, VALUE));
*/
static VALUE
-fix_lshift(x, y)
+rb_fix_lshift(x, y)
VALUE x, y;
{
long val, width;
val = NUM2LONG(x);
- width = NUM2LONG(y);
+ if (!FIXNUM_P(y))
+ return rb_big_lshift(rb_int2big(val), y);
+ width = FIX2LONG(y);
if (width < 0)
- return fix_rshift(x, LONG2FIX(-width));
+ return fix_rshift(val, (unsigned long)-width);
+ return fix_lshift(val, width);
+}
+
+static VALUE
+fix_lshift(val, width)
+ long val;
+ unsigned long width;
+{
if (width > (sizeof(VALUE)*CHAR_BIT-1)
|| ((unsigned long)val)>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) {
- return rb_big_lshift(rb_int2big(val), y);
+ return rb_big_lshift(rb_int2big(val), ULONG2NUM(width));
}
val = val << width;
return LONG2NUM(val);
@@ -2465,16 +2549,24 @@ fix_lshift(x, y)
*/
static VALUE
-fix_rshift(x, y)
+rb_fix_rshift(x, y)
VALUE x, y;
{
long i, val;
- i = NUM2LONG(y);
- if (i < 0)
- return fix_lshift(x, LONG2FIX(-i));
- if (i == 0) return x;
val = FIX2LONG(x);
+ if (!FIXNUM_P(y))
+ return rb_big_rshift(rb_int2big(val), y);
+ i = FIX2LONG(y);
+ if (i == 0) return x;
+ if (i < 0)
+ return fix_lshift(val, (unsigned long)-i);
+ return fix_rshift(val, i);
+}
+
+static VALUE
+fix_rshift(long val, unsigned long i)
+{
if (i >= sizeof(long)*CHAR_BIT-1) {
if (val < 0) return INT2FIX(-1);
return INT2FIX(0);
@@ -2506,7 +2598,7 @@ fix_aref(fix, idx)
long val = FIX2LONG(fix);
long i;
- if (TYPE(idx) == T_BIGNUM) {
+ if (!FIXNUM_P(idx = fix_coerce(idx))) {
idx = rb_big_norm(idx);
if (!FIXNUM_P(idx)) {
if (!RBIGNUM(idx)->sign || val >= 0)
@@ -2514,7 +2606,7 @@ fix_aref(fix, idx)
return INT2FIX(1);
}
}
- i = NUM2LONG(idx);
+ i = FIX2LONG(idx);
if (i < 0) return INT2FIX(0);
if (sizeof(VALUE)*CHAR_BIT-1 < i) {
@@ -2875,8 +2967,8 @@ Init_Numeric()
rb_define_method(rb_cFixnum, "^", fix_xor, 1);
rb_define_method(rb_cFixnum, "[]", fix_aref, 1);
- rb_define_method(rb_cFixnum, "<<", fix_lshift, 1);
- rb_define_method(rb_cFixnum, ">>", fix_rshift, 1);
+ rb_define_method(rb_cFixnum, "<<", rb_fix_lshift, 1);
+ rb_define_method(rb_cFixnum, ">>", rb_fix_rshift, 1);
rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0);
rb_define_method(rb_cFixnum, "size", fix_size, 0);
diff --git a/object.c b/object.c
index 787b860d5d..18407cc02e 100644
--- a/object.c
+++ b/object.c
@@ -812,28 +812,6 @@ nil_inspect(obj)
return rb_str_new2("nil");
}
-#ifdef NIL_PLUS
-static VALUE
-nil_plus(x, y)
- VALUE x, y;
-{
- switch (TYPE(y)) {
- case T_NIL:
- case T_FIXNUM:
- case T_FLOAT:
- case T_BIGNUM:
- case T_STRING:
- case T_ARRAY:
- return y;
- default:
- rb_raise(rb_eTypeError, "tried to add %s(%s) to nil",
- RSTRING(rb_inspect(y))->ptr,
- rb_obj_classname(y));
- }
- /* not reached */
-}
-#endif
-
static VALUE
main_to_s(obj)
VALUE obj;
diff --git a/parse.y b/parse.y
index d1466e77ca..765e5b6e78 100644
--- a/parse.y
+++ b/parse.y
@@ -406,7 +406,7 @@ stmts : none
}
| error stmt
{
- $$ = $2;
+ $$ = remove_begin($2);
}
;
@@ -436,7 +436,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
}
| stmt kIF_MOD expr_value
{
- $$ = NEW_IF(cond($3), $1, 0);
+ $$ = NEW_IF(cond($3), remove_begin($1), 0);
fixpos($$, $3);
if (cond_negative(&$$->nd_cond)) {
$$->nd_else = $$->nd_body;
@@ -445,7 +445,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
}
| stmt kUNLESS_MOD expr_value
{
- $$ = NEW_UNLESS(cond($3), $1, 0);
+ $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
fixpos($$, $3);
if (cond_negative(&$$->nd_cond)) {
$$->nd_body = $$->nd_else;
@@ -478,7 +478,8 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
}
| stmt kRESCUE_MOD stmt
{
- $$ = NEW_RESCUE($1, NEW_RESBODY(0,$3,0), 0);
+ NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
+ $$ = NEW_RESCUE(remove_begin($1), resq, 0);
}
| klBEGIN
{
@@ -2143,6 +2144,7 @@ dsym : tSYMBEG xstring_contents tSTRING_END
{
lex_state = EXPR_END;
if (!($$ = $2)) {
+ $$ = NEW_NIL();
yyerror("empty symbol literal");
}
else {
@@ -2341,6 +2343,8 @@ f_rest_arg : restarg_mark tIDENTIFIER
{
if (!is_local_id($2))
yyerror("rest argument must be local variable");
+ else if (local_id($2))
+ yyerror("duplicate rest argument name");
if (dyna_in_block()) {
rb_dvar_push($2, Qnil);
}
@@ -2520,7 +2524,9 @@ static int
yyerror(msg)
const char *msg;
{
- char *p, *pe, *buf;
+ const int max_line_margin = 30;
+ const char *p, *pe;
+ char *buf;
int len, i;
rb_compile_error("%s", msg);
@@ -2539,17 +2545,32 @@ yyerror(msg)
len = pe - p;
if (len > 4) {
+ char *p2;
+ const char *pre = "", *post = "";
+
+ if (len > max_line_margin * 2 + 10) {
+ int re_mbc_startpos _((const char *, int, int, int));
+ if ((len = lex_p - p) > max_line_margin) {
+ p = p + re_mbc_startpos(p, len, len - max_line_margin, 0);
+ pre = "...";
+ }
+ if ((len = pe - lex_p) > max_line_margin) {
+ pe = lex_p + re_mbc_startpos(lex_p, len, max_line_margin, 1);
+ post = "...";
+ }
+ len = pe - p;
+ }
buf = ALLOCA_N(char, len+2);
MEMCPY(buf, p, char, len);
buf[len] = '\0';
- rb_compile_error_append("%s", buf);
+ rb_compile_error_append("%s%s%s", pre, buf, post);
i = lex_p - p;
- p = buf; pe = p + len;
+ p2 = buf; pe = buf + len;
- while (p < pe) {
- if (*p != '\t') *p = ' ';
- p++;
+ while (p2 < pe) {
+ if (*p2 != '\t') *p2 = ' ';
+ p2++;
}
buf[i] = '^';
buf[i+1] = '\0';
@@ -2603,6 +2624,7 @@ yycompile(f, line)
ruby__end__seen = 0;
ruby_eval_tree = 0;
+ ruby_eval_tree_begin = 0;
heredoc_end = 0;
lex_strterm = 0;
ruby_current_node = 0;
@@ -2628,7 +2650,7 @@ yycompile(f, line)
rb_gc_force_recycle((VALUE)tmp);
}
if (n == 0) node = ruby_eval_tree;
- else ruby_eval_tree_begin = 0;
+ if (ruby_nerrs) ruby_eval_tree_begin = 0;
return node;
}
@@ -4354,6 +4376,7 @@ yylex()
else {
rb_compile_error("`@@%c' is not allowed as a class variable name", c);
}
+ return 0;
}
if (!is_identchar(c)) {
pushback(c);
@@ -4536,10 +4559,13 @@ newline_node(node)
{
NODE *nl = 0;
if (node) {
+ int line;
if (nd_type(node) == NODE_NEWLINE) return node;
- nl = NEW_NEWLINE(node);
- fixpos(nl, node);
- nl->nd_nth = nd_line(node);
+ line = nd_line(node);
+ node = remove_begin(node);
+ nl = NEW_NEWLINE(node);
+ nd_set_line(nl, line);
+ nl->nd_nth = line;
}
return nl;
}
@@ -5194,7 +5220,7 @@ void_stmts(node)
for (;;) {
if (!node->nd_next) return;
- void_expr(node->nd_head);
+ void_expr0(node->nd_head);
node = node->nd_next;
}
}
diff --git a/process.c b/process.c
index d964c35a42..0f45891b7a 100644
--- a/process.c
+++ b/process.c
@@ -101,6 +101,13 @@ static VALUE S_Tms;
#define BROKEN_SETREGID 1
#endif
+#ifdef BROKEN_SETREUID
+#define setreuid ruby_setreuid
+#endif
+#ifdef BROKEN_SETREGID
+#define setregid ruby_setregid
+#endif
+
#if defined(HAVE_44BSD_SETUID) || defined(__MacOS_X__)
#if !defined(USE_SETREUID) && !defined(BROKEN_SETREUID)
#define OBSOLETE_SETREUID 1
@@ -110,6 +117,9 @@ static VALUE S_Tms;
#endif
#endif
+#define preserving_errno(stmts) \
+ do {int saved_errno = errno; stmts; errno = saved_errno;} while (0)
+
/*
* call-seq:
@@ -838,23 +848,22 @@ proc_waitall()
}
static VALUE
-detach_process_watcher(pid_p)
- int *pid_p;
+detach_process_watcher(arg)
+ void *arg;
{
- int cpid, status;
+ int pid = (int)(VALUE)arg, status;
- for (;;) {
- cpid = rb_waitpid(*pid_p, &status, WNOHANG);
- if (cpid != 0) return Qnil;
+ while (rb_waitpid(pid, &status, WNOHANG) == 0) {
rb_thread_sleep(1);
}
+ return rb_last_status;
}
VALUE
rb_detach_process(pid)
int pid;
{
- return rb_thread_create(detach_process_watcher, (void*)&pid);
+ return rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
}
@@ -873,6 +882,11 @@ rb_detach_process(pid)
* terminate. <code>detach</code> only checks the status
* periodically (currently once each second).
*
+ * The waiting thread returns the exit status of the detached process
+ * when it terminates, so you can use <code>Thread#join</code> to
+ * know the result. If specified _pid_ is not a valid child process
+ * ID, the thread returns +nil+ immediately.
+ *
* In this first example, we don't reap the first child process, so
* it appears as a zombie in the process status display.
*
@@ -982,7 +996,7 @@ proc_exec_v(argv, prog)
#endif /* MSDOS or __human68k__ or __EMX__ */
before_exec();
execv(prog, argv);
- after_exec();
+ preserving_errno(after_exec());
return -1;
}
@@ -1051,7 +1065,7 @@ rb_proc_exec(str)
#else
before_exec();
execl("/bin/sh", "sh", "-c", str, (char *)NULL);
- after_exec();
+ preserving_errno(after_exec());
#endif
#endif
return -1;
@@ -1060,8 +1074,8 @@ rb_proc_exec(str)
a = argv = ALLOCA_N(char*, (s-str)/2+2);
ss = ALLOCA_N(char, s-str+1);
strcpy(ss, str);
- if (*a++ = strtok(ss, " \t")) {
- while (t = strtok(NULL, " \t")) {
+ if ((*a++ = strtok(ss, " \t")) != 0) {
+ while ((t = strtok(NULL, " \t")) != 0) {
*a++ = t;
}
*a = NULL;
@@ -1180,6 +1194,53 @@ proc_spawn(sv)
#endif
#endif
+struct rb_exec_arg {
+ int argc;
+ VALUE *argv;
+ VALUE prog;
+};
+
+static void
+proc_prepare_args(e, argc, argv, prog)
+ struct rb_exec_arg *e;
+ int argc;
+ VALUE *argv;
+ VALUE prog;
+{
+ int i;
+
+ MEMZERO(e, struct rb_exec_arg, 1);
+ if (prog) {
+ SafeStringValue(prog);
+ StringValueCStr(prog);
+ }
+ for (i = 0; i < argc; i++) {
+ SafeStringValue(argv[i]);
+ StringValueCStr(argv[i]);
+ }
+ security(RSTRING(prog ? prog : argv[0])->ptr);
+ e->prog = prog;
+ e->argc = argc;
+ e->argv = argv;
+}
+
+static VALUE
+proc_exec_args(earg)
+ VALUE earg;
+{
+ struct rb_exec_arg *e = (struct rb_exec_arg *)earg;
+ int argc = e->argc;
+ VALUE *argv = e->argv;
+ VALUE prog = e->prog;
+
+ if (argc == 1 && prog == 0) {
+ return (VALUE)rb_proc_exec(RSTRING(argv[0])->ptr);
+ }
+ else {
+ return (VALUE)proc_exec_n(argc, argv, prog);
+ }
+}
+
/*
* call-seq:
* exec(command [, arg, ...])
@@ -1212,8 +1273,10 @@ rb_f_exec(argc, argv)
{
VALUE prog = 0;
VALUE tmp;
+ struct rb_exec_arg earg;
if (argc == 0) {
+ rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
@@ -1226,15 +1289,8 @@ rb_f_exec(argc, argv)
argv[0] = RARRAY(tmp)->ptr[1];
SafeStringValue(prog);
}
- if (argc == 1 && prog == 0) {
- VALUE cmd = argv[0];
-
- SafeStringValue(cmd);
- rb_proc_exec(RSTRING(cmd)->ptr);
- }
- else {
- proc_exec_n(argc, argv, prog);
- }
+ proc_prepare_args(&earg, argc, argv, prog);
+ proc_exec_args((VALUE)&earg);
rb_sys_fail(RSTRING(argv[0])->ptr);
return Qnil; /* dummy */
}
@@ -1491,7 +1547,7 @@ rb_f_system(argc, argv)
#else
volatile VALUE prog = 0;
int pid;
- int i;
+ struct rb_exec_arg earg;
RETSIGTYPE (*chfunc)(int);
fflush(stdout);
@@ -1508,25 +1564,15 @@ rb_f_system(argc, argv)
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
+ proc_prepare_args(&earg, argc, argv, prog);
- if (prog) {
- SafeStringValue(prog);
- }
- for (i = 0; i < argc; i++) {
- SafeStringValue(argv[i]);
- }
- security(RSTRING(prog ? prog : argv[0])->ptr);
chfunc = signal(SIGCHLD, SIG_DFL);
retry:
pid = fork();
if (pid == 0) {
/* child process */
- if (argc == 1 && prog == 0) {
- rb_proc_exec(RSTRING(argv[0])->ptr);
- }
- else {
- proc_exec_n(argc, argv, prog);
- }
+ rb_thread_atfork();
+ rb_protect(proc_exec_args, (VALUE)&earg, NULL);
_exit(127);
}
if (pid < 0) {
@@ -3667,8 +3713,8 @@ Init_process()
rb_define_module_function(rb_mProcGID, "change_privilege", p_gid_change_privilege, 1);
rb_define_module_function(rb_mProcUID, "grant_privilege", p_uid_grant_privilege, 1);
rb_define_module_function(rb_mProcGID, "grant_privilege", p_gid_grant_privilege, 1);
- rb_define_alias(rb_mProcUID, "eid=", "grant_privilege");
- rb_define_alias(rb_mProcGID, "eid=", "grant_privilege");
+ rb_define_alias(rb_singleton_class(rb_mProcUID), "eid=", "grant_privilege");
+ rb_define_alias(rb_singleton_class(rb_mProcGID), "eid=", "grant_privilege");
rb_define_module_function(rb_mProcUID, "re_exchange", p_uid_exchange, 0);
rb_define_module_function(rb_mProcGID, "re_exchange", p_gid_exchange, 0);
rb_define_module_function(rb_mProcUID, "re_exchangeable?", p_uid_exchangeable, 0);
diff --git a/random.c b/random.c
index df4bcbaba7..8de3419562 100644
--- a/random.c
+++ b/random.c
@@ -310,8 +310,8 @@ random_seed()
* srand(number=0) => old_seed
*
* Seeds the pseudorandom number generator to the value of
- * <i>number</i>.<code>to_i.abs</code>. If <i>number</i> is omitted
- * or zero, seeds the generator using a combination of the time, the
+ * <i>number</i>.<code>to_i.abs</code>. If <i>number</i> is omitted,
+ * seeds the generator using a combination of the time, the
* process id, and a sequence number. (This is also the behavior if
* <code>Kernel::rand</code> is called without previously calling
* <code>srand</code>, but without the sequence.) By setting the seed
@@ -481,6 +481,7 @@ rb_f_rand(argc, argv, obj)
default:
vmax = rb_Integer(vmax);
if (TYPE(vmax) == T_BIGNUM) goto bignum;
+ /* fall through */
case T_FIXNUM:
max = FIX2LONG(vmax);
break;
diff --git a/range.c b/range.c
index 5c1b61c2e4..5c8be90c63 100644
--- a/range.c
+++ b/range.c
@@ -319,8 +319,11 @@ range_step(argc, argv, range)
if (unit == 0) rb_raise(rb_eArgError, "step can't be 0");
if (!EXCL(range)) end += 1;
- for (i=FIX2LONG(b); i<end; i+=unit) {
+ i = FIX2LONG(b);
+ while (i < end) {
rb_yield(LONG2NUM(i));
+ if (i + unit < i) break;
+ i += unit;
}
}
else {
diff --git a/regex.c b/regex.c
index ae0694b764..e721097e32 100644
--- a/regex.c
+++ b/regex.c
@@ -3109,6 +3109,28 @@ re_compile_fastmap(bufp)
/* adjust startpos value to the position between characters. */
int
+re_mbc_startpos(string, size, startpos, range)
+ const char *string;
+ int size, startpos, range;
+{
+ int i = mbc_startpos(string, startpos);
+
+ if (i < startpos) {
+ if (range > 0) {
+ startpos = i + mbclen(string[i]);
+ }
+ else {
+ int len = mbclen(string[i]);
+ if (i + len <= startpos)
+ startpos = i + len;
+ else
+ startpos = i;
+ }
+ }
+ return startpos;
+}
+
+int
re_adjust_startpos(bufp, string, size, startpos, range)
struct re_pattern_buffer *bufp;
const char *string;
@@ -3121,20 +3143,7 @@ re_adjust_startpos(bufp, string, size, startpos, range)
/* Adjust startpos for mbc string */
if (current_mbctype && startpos>0 && !(bufp->options&RE_OPTIMIZE_BMATCH)) {
- int i = mbc_startpos(string, startpos);
-
- if (i < startpos) {
- if (range > 0) {
- startpos = i + mbclen(string[i]);
- }
- else {
- int len = mbclen(string[i]);
- if (i + len <= startpos)
- startpos = i + len;
- else
- startpos = i;
- }
- }
+ startpos = re_mbc_startpos(string, size, startpos, range);
}
return startpos;
}
diff --git a/ruby.c b/ruby.c
index 9aa062a0f2..9777695175 100644
--- a/ruby.c
+++ b/ruby.c
@@ -15,6 +15,9 @@
#if defined _WIN32 || defined __CYGWIN__
#include <windows.h>
#endif
+#if defined __CYGWIN__
+#include <sys/cygwin.h>
+#endif
#ifdef _WIN32_WCE
#include <winsock.h>
#include "wince.h"
@@ -109,127 +112,141 @@ NULL
extern VALUE rb_load_path;
-#define STATIC_FILE_LENGTH 255
+#ifndef CharNext /* defined as CharNext[AW] on Windows. */
+#define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))
+#endif
+
+#if defined DOSISH || defined __CYGWIN__
+static inline void
+translate_char(char *p, int from, int to)
+{
+ while (*p) {
+ if ((unsigned char)*p == from)
+ *p = to;
+ p = CharNext(p);
+ }
+}
+#endif
#if defined _WIN32 || defined __CYGWIN__ || defined __DJGPP__
-static char *
-rubylib_mangle(s, l)
- char *s;
- unsigned int l;
+static VALUE
+rubylib_mangled_path(const char *s, unsigned int l)
{
static char *newp, *oldp;
static int newl, oldl, notfound;
- static char newsub[STATIC_FILE_LENGTH+1];
+ char *ptr;
+ VALUE ret;
if (!newp && !notfound) {
newp = getenv("RUBYLIB_PREFIX");
if (newp) {
- char *s;
-
- oldp = newp;
+ oldp = newp = strdup(newp);
while (*newp && !ISSPACE(*newp) && *newp != ';') {
- newp++; oldl++; /* Skip digits. */
+ newp = CharNext(newp); /* Skip digits. */
}
+ oldl = newp - oldp;
while (*newp && (ISSPACE(*newp) || *newp == ';')) {
- newp++; /* Skip whitespace. */
+ newp = CharNext(newp); /* Skip whitespace. */
}
newl = strlen(newp);
- if (newl == 0 || oldl == 0 || newl > STATIC_FILE_LENGTH) {
+ if (newl == 0 || oldl == 0) {
rb_fatal("malformed RUBYLIB_PREFIX");
}
- strcpy(newsub, newp);
- s = newsub;
- while (*s) {
- if (*s == '\\') *s = '/';
- s++;
- }
+ translate_char(newp, '\\', '/');
}
else {
notfound = 1;
}
}
- if (l == 0) {
- l = strlen(s);
- }
if (!newp || l < oldl || strncasecmp(oldp, s, oldl) != 0) {
- static char ret[STATIC_FILE_LENGTH+1];
- strncpy(ret, s, l);
- ret[l] = 0;
- return ret;
+ return rb_str_new(s, l);
}
- if (l + newl - oldl > STATIC_FILE_LENGTH || newl > STATIC_FILE_LENGTH) {
- rb_fatal("malformed RUBYLIB_PREFIX");
- }
- strcpy(newsub + newl, s + oldl);
- newsub[l + newl - oldl] = 0;
- return newsub;
+ ret = rb_str_new(0, l + newl - oldl);
+ ptr = RSTRING(ret)->ptr;
+ memcpy(ptr, newp, newl);
+ memcpy(ptr + newl, s + oldl, l - oldl);
+ ptr[l + newl - oldl] = 0;
+ return ret;
+}
+
+static VALUE
+rubylib_mangled_path2(const char *s)
+{
+ return rubylib_mangled_path(s, strlen(s));
}
-#define rubylib_mangled_path(s, l) rb_str_new2(rubylib_mangle((s), (l)))
-#define rubylib_mangled_path2(s) rb_str_new2(rubylib_mangle((s), 0))
#else
-#define rubylib_mangled_path(s, l) rb_str_new((s), (l))
-#define rubylib_mangled_path2(s) rb_str_new2(s)
+#define rubylib_mangled_path rb_str_new
+#define rubylib_mangled_path2 rb_str_new2
#endif
-void
-ruby_incpush(path)
+static void push_include _((const char *path));
+
+static void
+push_include(path)
const char *path;
{
const char sep = PATH_SEP_CHAR;
+ const char *p, *s;
- if (path == 0) return;
-#if defined(__CYGWIN__)
- {
- char rubylib[FILENAME_MAX];
- conv_to_posix_path(path, rubylib, FILENAME_MAX);
- path = rubylib;
+ p = path;
+ while (*p) {
+ while (*p == sep)
+ p++;
+ if (!*p) break;
+ for (s = p; *s && *s != sep; s = CharNext(s));
+ rb_ary_push(rb_load_path, rubylib_mangled_path(p, s - p));
+ p = s;
}
-#endif
- if (strchr(path, sep)) {
- const char *p, *s;
- VALUE ary = rb_ary_new();
-
- p = path;
- while (*p) {
- while (*p == sep) p++;
- if ((s = strchr(p, sep)) != 0) {
- rb_ary_push(ary, rubylib_mangled_path(p, (int)(s-p)));
- p = s + 1;
+}
+
+#ifdef __CYGWIN__
+static void
+push_include_cygwin(const char *path)
+{
+ const char *p, *s;
+ char rubylib[FILENAME_MAX];
+ VALUE buf = 0;
+
+ p = path;
+ while (*p) {
+ unsigned int len;
+ while (*p == ';')
+ p++;
+ if (!*p) break;
+ for (s = p; *s && *s != ';'; s = CharNext(s));
+ len = s - p;
+ if (*s) {
+ if (!buf) {
+ buf = rb_str_new(p, len);
+ p = RSTRING(buf)->ptr;
}
else {
- rb_ary_push(ary, rubylib_mangled_path2(p));
- break;
+ rb_str_resize(buf, len);
+ p = strncpy(RSTRING(buf)->ptr, p, len);
}
}
- rb_ary_concat(rb_load_path, ary);
- }
- else {
- rb_ary_push(rb_load_path, rubylib_mangled_path2(path));
+ if (cygwin_conv_to_posix_path(p, rubylib) == 0)
+ p = rubylib;
+ push_include(p);
+ if (!*s) break;
+ p = s + 1;
}
}
-#if defined DOSISH || defined __CYGWIN__
-#define LOAD_RELATIVE 1
+#define push_include push_include_cygwin
#endif
-#if defined DOSISH || defined __CYGWIN__
-static inline void translate_char _((char *, int, int));
-
-static inline void
-translate_char(p, from, to)
- char *p;
- int from, to;
+void
+ruby_incpush(path)
+ const char *path;
{
- while (*p) {
- if ((unsigned char)*p == from)
- *p = to;
-#ifdef CharNext /* defined as CharNext[AW] on Windows. */
- p = CharNext(p);
-#else
- p += mblen(p, MB_CUR_MAX);
-#endif
- }
+ if (path == 0)
+ return;
+ push_include(path);
}
+
+#if defined DOSISH || defined __CYGWIN__
+#define LOAD_RELATIVE 1
#endif
void
@@ -260,13 +277,19 @@ ruby_init_loadpath()
#endif
libpath[FILENAME_MAX] = '\0';
-#if defined DOSISH || defined __CYGWIN__
+#if defined DOSISH
translate_char(libpath, '\\', '/');
+#elif defined __CYGWIN__
+ {
+ char rubylib[FILENAME_MAX];
+ cygwin_conv_to_posix_path(libpath, rubylib);
+ strncpy(libpath, rubylib, sizeof(libpath));
+ }
#endif
p = strrchr(libpath, '/');
if (p) {
*p = 0;
- if (p-libpath > 3 && !strcasecmp(p-4, "/bin")) {
+ if (p - libpath > 3 && !strcasecmp(p - 4, "/bin")) {
p -= 4;
*p = 0;
}
@@ -282,30 +305,31 @@ ruby_init_loadpath()
#else
#define RUBY_RELATIVE(path) (path)
#endif
+#define incpush(path) rb_ary_push(rb_load_path, rubylib_mangled_path2(path))
if (rb_safe_level() == 0) {
ruby_incpush(getenv("RUBYLIB"));
}
#ifdef RUBY_SEARCH_PATH
- ruby_incpush(RUBY_RELATIVE(RUBY_SEARCH_PATH));
+ incpush(RUBY_RELATIVE(RUBY_SEARCH_PATH));
#endif
- ruby_incpush(RUBY_RELATIVE(RUBY_SITE_LIB2));
+ incpush(RUBY_RELATIVE(RUBY_SITE_LIB2));
#ifdef RUBY_SITE_THIN_ARCHLIB
- ruby_incpush(RUBY_RELATIVE(RUBY_SITE_THIN_ARCHLIB));
+ incpush(RUBY_RELATIVE(RUBY_SITE_THIN_ARCHLIB));
#endif
- ruby_incpush(RUBY_RELATIVE(RUBY_SITE_ARCHLIB));
- ruby_incpush(RUBY_RELATIVE(RUBY_SITE_LIB));
+ incpush(RUBY_RELATIVE(RUBY_SITE_ARCHLIB));
+ incpush(RUBY_RELATIVE(RUBY_SITE_LIB));
- ruby_incpush(RUBY_RELATIVE(RUBY_LIB));
+ incpush(RUBY_RELATIVE(RUBY_LIB));
#ifdef RUBY_THIN_ARCHLIB
- ruby_incpush(RUBY_RELATIVE(RUBY_THIN_ARCHLIB));
+ incpush(RUBY_RELATIVE(RUBY_THIN_ARCHLIB));
#endif
- ruby_incpush(RUBY_RELATIVE(RUBY_ARCHLIB));
+ incpush(RUBY_RELATIVE(RUBY_ARCHLIB));
if (rb_safe_level() == 0) {
- ruby_incpush(".");
+ incpush(".");
}
}
@@ -751,7 +775,7 @@ proc_options(argc, argv)
}
}
if (!*s) break;
- if (!strchr("IdvwrK", *s))
+ if (!strchr("IdvwWrK", *s))
rb_raise(rb_eRuntimeError, "illegal switch in RUBYOPT: -%c", *s);
s = moreswitches(s);
}
diff --git a/sample/test.rb b/sample/test.rb
index e7f2d251b7..741e96ee9d 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -1697,7 +1697,10 @@ else
end
def valid_syntax?(code, fname)
- eval("BEGIN {return true}\n#{code}", nil, fname, 0)
+ code = code.sub(/\A(?:\s*\#.*$)*(\n)?/n) {
+ "#$&#{"\n" if $1 && !$2}BEGIN{return true}\n"
+ }
+ eval(code, nil, fname, 0)
rescue Exception
puts $!.message
false
diff --git a/signal.c b/signal.c
index 82400e7add..530bcc1164 100644
--- a/signal.c
+++ b/signal.c
@@ -21,6 +21,12 @@
#undef SIGBUS
#endif
+#if defined HAVE_SIGPROCMASK || defined HAVE_SIGSETMASK
+#define USE_TRAP_MASK 1
+#else
+#define USE_TRAP_MASK 0
+#endif
+
#ifndef NSIG
# ifdef DJGPP
# define NSIG SIGMAX
@@ -570,7 +576,7 @@ rb_trap_exec()
}
struct trap_arg {
-#ifndef _WIN32
+#if USE_TRAP_MASK
# ifdef HAVE_SIGPROCMASK
sigset_t mask;
# else
@@ -716,7 +722,7 @@ trap(arg)
trap_list[sig].cmd = command;
trap_list[sig].safe = ruby_safe_level;
/* enable at least specified signal. */
-#ifndef _WIN32
+#if USE_TRAP_MASK
#ifdef HAVE_SIGPROCMASK
sigdelset(&arg->mask, sig);
#else
@@ -726,7 +732,7 @@ trap(arg)
return oldcmd;
}
-#ifndef _WIN32
+#if USE_TRAP_MASK
static VALUE
trap_ensure(arg)
struct trap_arg *arg;
@@ -745,7 +751,7 @@ trap_ensure(arg)
void
rb_trap_restore_mask()
{
-#ifndef _WIN32
+#if USE_TRAP_MASK
# ifdef HAVE_SIGPROCMASK
sigprocmask(SIG_SETMASK, &trap_last_mask, NULL);
# else
@@ -805,7 +811,7 @@ sig_trap(argc, argv)
if (OBJ_TAINTED(arg.cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
}
-#ifndef _WIN32
+#if USE_TRAP_MASK
/* disable interrupt */
# ifdef HAVE_SIGPROCMASK
sigfillset(&arg.mask);
@@ -888,7 +894,7 @@ init_sigchld(sig)
int sig;
{
sighandler_t oldfunc;
-#ifndef _WIN32
+#if USE_TRAP_MASK
# ifdef HAVE_SIGPROCMASK
sigset_t mask;
# else
@@ -896,7 +902,7 @@ init_sigchld(sig)
# endif
#endif
-#ifndef _WIN32
+#if USE_TRAP_MASK
/* disable interrupt */
# ifdef HAVE_SIGPROCMASK
sigfillset(&mask);
@@ -913,7 +919,7 @@ init_sigchld(sig)
trap_list[sig].cmd = 0;
}
-#ifndef _WIN32
+#if USE_TRAP_MASK
#ifdef HAVE_SIGPROCMASK
sigdelset(&mask, sig);
sigprocmask(SIG_SETMASK, &mask, NULL);
diff --git a/sprintf.c b/sprintf.c
index 45d4d7a063..be6d274512 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -82,6 +82,7 @@ sign_bits(base, p)
#define FSPACE 16
#define FWIDTH 32
#define FPREC 64
+#define FPREC0 128
#define CHECK(l) do {\
while (blen + (l) >= bsiz) {\
@@ -110,9 +111,7 @@ sign_bits(base, p)
#define GETNTHARG(nth) \
((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth])
-#define GETASTER(val) do { \
- t = p++; \
- n = 0; \
+#define GETNUM(n, val) \
for (; p < end && ISDIGIT(*p); p++) { \
int next_n = 10 * n + (*p - '0'); \
if (next_n / 10 != n) {\
@@ -122,7 +121,12 @@ sign_bits(base, p)
} \
if (p >= end) { \
rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
- } \
+ }
+
+#define GETASTER(val) do { \
+ t = p++; \
+ n = 0; \
+ GETNUM(n, val); \
if (*p == '$') { \
tmp = GETPOSARG(n); \
} \
@@ -257,6 +261,21 @@ rb_f_sprintf(argc, argv)
VALUE tmp;
VALUE str;
+#define CHECK_FOR_WIDTH(f) \
+ if ((f) & FWIDTH) { \
+ rb_raise(rb_eArgError, "width given twice"); \
+ } \
+ if ((f) & FPREC0) { \
+ rb_raise(rb_eArgError, "width after precision"); \
+ }
+#define CHECK_FOR_FLAGS(f) \
+ if ((f) & FWIDTH) { \
+ rb_raise(rb_eArgError, "flag after width"); \
+ } \
+ if ((f) & FPREC0) { \
+ rb_raise(rb_eArgError, "flag after precision"); \
+ }
+
fmt = GETNTHARG(0);
if (OBJ_TAINTED(fmt)) tainted = 1;
StringValue(fmt);
@@ -292,26 +311,31 @@ rb_f_sprintf(argc, argv)
break;
case ' ':
+ CHECK_FOR_FLAGS(flags);
flags |= FSPACE;
p++;
goto retry;
case '#':
+ CHECK_FOR_FLAGS(flags);
flags |= FSHARP;
p++;
goto retry;
case '+':
+ CHECK_FOR_FLAGS(flags);
flags |= FPLUS;
p++;
goto retry;
case '-':
+ CHECK_FOR_FLAGS(flags);
flags |= FMINUS;
p++;
goto retry;
case '0':
+ CHECK_FOR_FLAGS(flags);
flags |= FZERO;
p++;
goto retry;
@@ -319,16 +343,7 @@ rb_f_sprintf(argc, argv)
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = 0;
- for (; p < end && ISDIGIT(*p); p++) {
- int next_n = 10 * n + (*p - '0');
- if (next_n / 10 != n) {
- rb_raise(rb_eArgError, "width too big");
- }
- n = 10 * n + (*p - '0');
- }
- if (p >= end) {
- rb_raise(rb_eArgError, "malformed format string - %%[0-9]");
- }
+ GETNUM(n, width);
if (*p == '$') {
if (nextvalue != Qundef) {
rb_raise(rb_eArgError, "value given twice - %d$", n);
@@ -337,15 +352,13 @@ rb_f_sprintf(argc, argv)
p++;
goto retry;
}
+ CHECK_FOR_WIDTH(flags);
width = n;
flags |= FWIDTH;
goto retry;
case '*':
- if (flags & FWIDTH) {
- rb_raise(rb_eArgError, "width given twice");
- }
-
+ CHECK_FOR_WIDTH(flags);
flags |= FWIDTH;
GETASTER(width);
if (width < 0) {
@@ -356,10 +369,10 @@ rb_f_sprintf(argc, argv)
goto retry;
case '.':
- if (flags & FPREC) {
+ if (flags & FPREC0) {
rb_raise(rb_eArgError, "precision given twice");
}
- flags |= FPREC;
+ flags |= FPREC|FPREC0;
prec = 0;
p++;
@@ -372,17 +385,12 @@ rb_f_sprintf(argc, argv)
goto retry;
}
- for (; p < end && ISDIGIT(*p); p++) {
- prec = 10 * prec + (*p - '0');
- }
- if (p >= end) {
- rb_raise(rb_eArgError, "malformed format string - %%.[0-9]");
- }
+ GETNUM(prec, precision);
goto retry;
case '\n':
- p--;
case '\0':
+ p--;
case '%':
if (flags != FNONE) {
rb_raise(rb_eArgError, "illegal format character - %%");
@@ -471,7 +479,7 @@ rb_f_sprintf(argc, argv)
{
volatile VALUE val = GETARG();
char fbuf[32], nbuf[64], *s, *t;
- char *prefix = 0;
+ const char *prefix = 0;
int sign = 0;
char sc = 0;
long v = 0;
@@ -548,6 +556,7 @@ rb_f_sprintf(argc, argv)
default:
base = 10; break;
}
+
if (!bignum) {
if (base == 2) {
val = rb_int2big(v);
@@ -693,7 +702,7 @@ rb_f_sprintf(argc, argv)
else {
char c;
- if (bignum && !RBIGNUM(val)->sign)
+ if (!sign && bignum && !RBIGNUM(val)->sign)
c = sign_bits(base, p);
else
c = '0';
diff --git a/string.c b/string.c
index 58fa0362fc..f5de52c152 100644
--- a/string.c
+++ b/string.c
@@ -1644,7 +1644,7 @@ rb_str_splice(str, beg, len, val)
}
beg += RSTRING(str)->len;
}
- if (RSTRING(str)->len < beg + len) {
+ if (RSTRING(str)->len < len || RSTRING(str)->len < beg + len) {
len = RSTRING(str)->len - beg;
}
diff --git a/struct.c b/struct.c
index 45797c80a0..0dd5aba0a0 100644
--- a/struct.c
+++ b/struct.c
@@ -252,7 +252,7 @@ rb_struct_define(name, va_alist)
ary = rb_ary_new();
va_init_list(ar, name);
- while (mem = va_arg(ar, char*)) {
+ while ((mem = va_arg(ar, char*)) != 0) {
ID slot = rb_intern(mem);
rb_ary_push(ary, ID2SYM(slot));
}
@@ -557,8 +557,9 @@ rb_struct_init_copy(copy, s)
if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
- RSTRUCT(copy)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
- RSTRUCT(copy)->len = RSTRUCT(s)->len;
+ if (RSTRUCT(copy)->len != RSTRUCT(s)->len) {
+ rb_raise(rb_eTypeError, "struct size mismatch");
+ }
MEMCPY(RSTRUCT(copy)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(copy)->len);
return copy;
diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb
index d663e0446d..553d3078fe 100644
--- a/test/rinda/test_rinda.rb
+++ b/test/rinda/test_rinda.rb
@@ -240,6 +240,20 @@ module TupleSpaceTestModule
end
end
+ def test_ruby_talk_264062
+ th = Thread.new { @ts.take([:empty], 1) }
+ sleep 2
+ assert_raises(Rinda::RequestExpiredError) do
+ th.value
+ end
+
+ th = Thread.new { @ts.read([:empty], 1) }
+ sleep 2
+ assert_raises(Rinda::RequestExpiredError) do
+ th.value
+ end
+ end
+
def test_core_01
5.times do |n|
@ts.write([:req, 2])
diff --git a/test/ruby/test_beginendblock.rb b/test/ruby/test_beginendblock.rb
index b56b596a65..f8c9c846bd 100644
--- a/test/ruby/test_beginendblock.rb
+++ b/test/ruby/test_beginendblock.rb
@@ -54,4 +54,16 @@ EOW
assert_equal(expected, File.read(erroutpath))
# expecting Tempfile to unlink launcher and errout file.
end
+
+ def test_begin_and_eval
+ $test_begin_and_eval = :ok
+ begin
+ eval("BEGIN{$test_begin_and_eval = :ng}\n_/a:a")
+ rescue SyntaxError
+ x1 = x2 = $test_begin_and_eval
+ eval("x2 = $test_begin_and_eval")
+ end
+ assert_equal(:ok, x1)
+ assert_equal(:ok, x2)
+ end
end
diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb
index c238337db5..e070a9c866 100644
--- a/test/ruby/test_bignum.rb
+++ b/test/ruby/test_bignum.rb
@@ -84,4 +84,12 @@ class TestBignum < Test::Unit::TestCase
shift_test(-4518325415524767873)
shift_test(-0xfffffffffffffffff)
end
+
+ def test_too_big_to_s
+ if (big = 2**31-1).is_a?(Fixnum)
+ return
+ end
+ e = assert_raise(RangeError) {(1 << big).to_s}
+ assert_match(/too big to convert/, e.message)
+ end
end
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 5bec012bf8..38d72f701b 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -1,6 +1,7 @@
require 'test/unit'
class TestHash < Test::Unit::TestCase
+
def test_hash
x = {1=>2, 2=>4, 3=>6}
y = {1, 2, 2, 4, 3, 6}
@@ -71,4 +72,567 @@ class TestHash < Test::Unit::TestCase
assert_equal(44, x[22])
assert_equal(0, $z)
end
+
+ # From rubicon
+
+ def setup
+ @cls = Hash
+ @h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', true => 'true', nil => 'nil',
+ 'nil' => nil
+ ]
+ end
+
+ def test_s_AREF
+ h = @cls["a" => 100, "b" => 200]
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+
+ h = @cls.[]("a" => 100, "b" => 200)
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+ end
+
+ def test_s_new
+ h = @cls.new
+ assert_instance_of(@cls, h)
+ assert_nil(h.default)
+ assert_nil(h['spurious'])
+
+ h = @cls.new('default')
+ assert_instance_of(@cls, h)
+ assert_equal('default', h.default)
+ assert_equal('default', h['spurious'])
+
+ end
+
+ def test_AREF # '[]'
+ t = Time.now
+ h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', t => 'time', nil => 'nil',
+ 'nil' => nil
+ ]
+
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h1 = h.dup
+ h1.default = :default
+
+ assert_equal('one', h1[1])
+ assert_equal('two', h1[2])
+ assert_equal('three', h1[3])
+ assert_equal('self', h1[self])
+ assert_equal('time', h1[t])
+ assert_equal('nil', h1[nil])
+ assert_equal(nil, h1['nil'])
+ assert_equal(:default, h1['koala'])
+
+
+ end
+
+ def test_ASET # '[]='
+ t = Time.now
+ h = @cls.new
+ h[1] = 'one'
+ h[2] = 'two'
+ h[3] = 'three'
+ h[self] = 'self'
+ h[t] = 'time'
+ h[nil] = 'nil'
+ h['nil'] = nil
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h[1] = 1
+ h[nil] = 99
+ h['nil'] = nil
+ z = [1,2]
+ h[z] = 256
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ assert_equal(256, h[z])
+ end
+
+ def test_EQUAL # '=='
+ h1 = @cls[ "a" => 1, "c" => 2 ]
+ h2 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h3 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h4 = @cls[ ]
+ assert(h1 == h1)
+ assert(h2 == h2)
+ assert(h3 == h3)
+ assert(h4 == h4)
+ assert(!(h1 == h2))
+ assert(h2 == h3)
+ assert(!(h3 == h4))
+ end
+
+ def test_clear
+ assert(@h.size > 0)
+ @h.clear
+ assert_equal(0, @h.size)
+ assert_nil(@h[1])
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.clone
+ a.taint if taint
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ def test_default
+ assert_nil(@h.default)
+ h = @cls.new(:xyzzy)
+ assert_equal(:xyzzy, h.default)
+ end
+
+ def test_default=
+ assert_nil(@h.default)
+ @h.default = :xyzzy
+ assert_equal(:xyzzy, @h.default)
+ end
+
+ def test_delete
+ h1 = @cls[ 1 => 'one', 2 => 'two', true => 'true' ]
+ h2 = @cls[ 1 => 'one', 2 => 'two' ]
+ h3 = @cls[ 2 => 'two' ]
+
+ assert_equal('true', h1.delete(true))
+ assert_equal(h2, h1)
+
+ assert_equal('one', h1.delete(1))
+ assert_equal(h3, h1)
+
+ assert_equal('two', h1.delete(2))
+ assert_equal(@cls[], h1)
+
+ assert_nil(h1.delete(99))
+ assert_equal(@cls[], h1)
+
+ assert_equal('default 99', h1.delete(99) {|i| "default #{i}" })
+ end
+
+ def test_delete_if
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.delete_if { false })
+ assert_equal(@cls[], h.delete_if { true })
+
+ h = base.dup
+ assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.delete_if {|k,v| v })
+ assert_equal(h3, h)
+
+ h = base.dup
+ n = 0
+ h.delete_if {|*a|
+ n += 1
+ assert_equal(2, a.size)
+ assert_equal(base[a[0]], a[1])
+ h.shift
+ true
+ }
+ assert_equal(base.size, n)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.dup
+ a.taint if taint
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(false, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ def test_each
+ count = 0
+ @cls[].each { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_key
+ count = 0
+ @cls[].each_key { |k| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_key do |k|
+ h.delete(k)
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_pair
+ count = 0
+ @cls[].each_pair { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_pair do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_value
+ res = []
+ @cls[].each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ @h.each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ expected = []
+ @h.each { |k, v| expected << v }
+
+ assert_equal([], expected - res)
+ assert_equal([], res - expected)
+ end
+
+ def test_empty?
+ assert(@cls[].empty?)
+ assert(!@h.empty?)
+ end
+
+ def test_fetch
+ assert_raise(IndexError) { @cls[].fetch(1) }
+ assert_raise(IndexError) { @h.fetch('gumby') }
+ assert_equal('gumbygumby', @h.fetch('gumby') {|k| k * 2 })
+ assert_equal('pokey', @h.fetch('gumby', 'pokey'))
+
+ assert_equal('one', @h.fetch(1))
+ assert_equal(nil, @h.fetch('nil'))
+ assert_equal('nil', @h.fetch(nil))
+ end
+
+ def test_key?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_value?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?('one'))
+ assert(@h.value?(nil))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_include?
+ assert(!@cls[].include?(1))
+ assert(!@cls[].include?(nil))
+ assert(@h.include?(nil))
+ assert(@h.include?(1))
+ assert(!@h.include?('gumby'))
+ end
+
+ def test_values_at
+ res = @h.values_at('dog', 'cat', 'horse')
+ assert(res.length == 3)
+ assert_equal([nil, nil, nil], res)
+
+ res = @h.values_at
+ assert(res.length == 0)
+
+ res = @h.values_at(3, 2, 1, nil)
+ assert_equal 4, res.length
+ assert_equal %w( three two one nil ), res
+
+ res = @h.values_at(3, 99, 1, nil)
+ assert_equal 4, res.length
+ assert_equal ['three', nil, 'one', 'nil'], res
+ end
+
+
+ def test_invert
+ h = @h.invert
+ assert_equal(1, h['one'])
+ assert_equal(true, h['true'])
+ assert_equal(nil, h['nil'])
+
+ h.each do |k, v|
+ assert(@h.key?(v)) # not true in general, but works here
+ end
+
+ h = @cls[ 'a' => 1, 'b' => 2, 'c' => 1].invert
+ assert_equal(2, h.length)
+ assert(h[1] == 'a' || h[1] == 'c')
+ assert_equal('b', h[2])
+ end
+
+ def test_key?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_keys
+ assert_equal([], @cls[].keys)
+
+ keys = @h.keys
+ expected = []
+ @h.each { |k, v| expected << k }
+ assert_equal([], keys - expected)
+ assert_equal([], expected - keys)
+ end
+
+ def test_length
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_member?
+ assert(!@cls[].member?(1))
+ assert(!@cls[].member?(nil))
+ assert(@h.member?(nil))
+ assert(@h.member?(1))
+ assert(!@h.member?('gumby'))
+ end
+
+ def test_rehash
+ a = [ "a", "b" ]
+ c = [ "c", "d" ]
+ h = @cls[ a => 100, c => 300 ]
+ assert_equal(100, h[a])
+ a[0] = "z"
+ assert_nil(h[a])
+ h.rehash
+ assert_equal(100, h[a])
+ end
+
+ def test_reject
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.reject { false })
+ assert_equal(@cls[], h.reject { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject {|k,v| k.instance_of?(String) })
+
+ assert_equal(h2, h.reject {|k,v| v.instance_of?(String) })
+
+ assert_equal(h3, h.reject {|k,v| v })
+ assert_equal(base, h)
+ end
+
+ def test_reject!
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(nil, h.reject! { false })
+ assert_equal(@cls[], h.reject! { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject! {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.reject! {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.reject! {|k,v| v })
+ assert_equal(h3, h)
+ end
+
+ def test_replace
+ h = @cls[ 1 => 2, 3 => 4 ]
+ h1 = h.replace(@cls[ 9 => 8, 7 => 6 ])
+ assert_equal(h, h1)
+ assert_equal(8, h[9])
+ assert_equal(6, h[7])
+ assert_nil(h[1])
+ assert_nil(h[2])
+ end
+
+ def test_shift
+ h = @h.dup
+
+ @h.length.times {
+ k, v = h.shift
+ assert(@h.key?(k))
+ assert_equal(@h[k], v)
+ }
+
+ assert_equal(0, h.length)
+ end
+
+ def test_size
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_sort
+ h = @cls[].sort
+ assert_equal([], h)
+
+ h = @cls[ 1 => 1, 2 => 1 ].sort
+ assert_equal([[1,1], [2,1]], h)
+
+ h = @cls[ 'cat' => 'feline', 'ass' => 'asinine', 'bee' => 'beeline' ]
+ h1 = h.sort
+ assert_equal([ %w(ass asinine), %w(bee beeline), %w(cat feline)], h1)
+ end
+
+ def test_store
+ t = Time.now
+ h = @cls.new
+ h.store(1, 'one')
+ h.store(2, 'two')
+ h.store(3, 'three')
+ h.store(self, 'self')
+ h.store(t, 'time')
+ h.store(nil, 'nil')
+ h.store('nil', nil)
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h.store(1, 1)
+ h.store(nil, 99)
+ h.store('nil', nil)
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ end
+
+ def test_to_a
+ assert_equal([], @cls[].to_a)
+ assert_equal([[1,2]], @cls[ 1=>2 ].to_a)
+ a = @cls[ 1=>2, 3=>4, 5=>6 ].to_a
+ assert_equal([1,2], a.delete([1,2]))
+ assert_equal([3,4], a.delete([3,4]))
+ assert_equal([5,6], a.delete([5,6]))
+ assert_equal(0, a.length)
+ end
+
+ def test_to_hash
+ h = @h.to_hash
+ assert_equal(@h, h)
+ end
+
+ def test_to_s
+ h = @cls[ 1 => 2, "cat" => "dog", 1.5 => :fred ]
+ assert_equal(h.to_a.join, h.to_s)
+ $, = ":"
+ assert_equal(h.to_a.join, h.to_s)
+ h = @cls[]
+ assert_equal(h.to_a.join, h.to_s)
+ $, = nil
+ end
+
+ def test_update
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ ha = @cls[ 1 => 2, 2 => 'two', 3 => 4, 4 => 'four' ]
+ hb = @cls[ 1 => 2, 2 => 3, 3 => 4, 4 => 'four' ]
+
+ assert_equal(ha, h1.update(h2))
+ assert_equal(ha, h1)
+
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ assert_equal(hb, h2.update(h1))
+ assert_equal(hb, h2)
+ end
+
+ def test_value?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?(nil))
+ assert(@h.value?('one'))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_values
+ assert_equal([], @cls[].values)
+
+ vals = @h.values
+ expected = []
+ @h.each { |k, v| expected << v }
+ assert_equal([], vals - expected)
+ assert_equal([], expected - vals)
+ end
+
end
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index 9c9fd9470b..11f3583076 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -45,4 +45,24 @@ class TestMarshal < Test::Unit::TestCase
assert_equal(a, b)
}
end
+
+ class C
+ def initialize(str)
+ @str = str
+ end
+ def _dump(limit)
+ @str
+ end
+ def self._load(s)
+ new(s)
+ end
+ end
+
+ def test_too_long_string
+ (data = Marshal.dump(C.new("a")))[-2, 1] = "\003\377\377\377"
+ e = assert_raise(ArgumentError, "[ruby-dev:32054]") {
+ Marshal.load(data)
+ }
+ assert_equal("marshal data too short", e.message)
+ end
end
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index c30705cb15..ef28098dce 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -11,8 +11,13 @@ class TestMethod < Test::Unit::TestCase
class Base
def foo() :base end
+ def bar() :bar end
+ end
+ module SuperBar
+ def bar() super end
end
class Derived < Base
+ include SuperBar
def foo() :derived end
end
@@ -39,4 +44,10 @@ class TestMethod < Test::Unit::TestCase
um.bind(Base.new)
end
end
+
+ def test_method_super
+ assert_nothing_raised do
+ assert_equal(:bar, Derived.new.method(:bar).call)
+ end
+ end
end
diff --git a/test/ruby/test_system.rb b/test/ruby/test_system.rb
index f3a71598f7..3513577ec5 100644
--- a/test/ruby/test_system.rb
+++ b/test/ruby/test_system.rb
@@ -4,7 +4,10 @@ require 'envutil'
class TestSystem < Test::Unit::TestCase
def valid_syntax?(code, fname)
- eval("BEGIN {return true}\n#{code}", nil, fname, 0)
+ code = code.sub(/\A(?:\s*\#.*$)*(\n)?/n) {
+ "#$&#{"\n" if $1 && !$2}BEGIN{return true}\n"
+ }
+ eval(code, nil, fname, 0)
end
def test_system
diff --git a/test/webrick/.htaccess b/test/webrick/.htaccess
new file mode 100644
index 0000000000..69d4659b9f
--- /dev/null
+++ b/test/webrick/.htaccess
@@ -0,0 +1 @@
+this file should not be published.
diff --git a/test/webrick/test_cgi.rb b/test/webrick/test_cgi.rb
index 7e3f4ee5f0..b39fe2661c 100644
--- a/test/webrick/test_cgi.rb
+++ b/test/webrick/test_cgi.rb
@@ -1,20 +1,13 @@
require "webrick"
require File.join(File.dirname(__FILE__), "utils.rb")
require "test/unit"
-begin
- loadpath = $:.dup
- $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
- require 'envutil'
-ensure
- $:.replace(loadpath)
-end
class TestWEBrickCGI < Test::Unit::TestCase
def test_cgi
accepted = started = stopped = 0
requested0 = requested1 = 0
config = {
- :CGIInterpreter => EnvUtil.rubybin,
+ :CGIInterpreter => TestWEBrick::RubyBin,
:DocumentRoot => File.dirname(__FILE__),
:DirectoryIndex => ["webrick.cgi"],
}
diff --git a/test/webrick/test_filehandler.rb b/test/webrick/test_filehandler.rb
index 703fde4d9a..2c7d97fa70 100644
--- a/test/webrick/test_filehandler.rb
+++ b/test/webrick/test_filehandler.rb
@@ -1,6 +1,7 @@
require "test/unit"
require "webrick"
require "stringio"
+require File.join(File.dirname(__FILE__), "utils.rb")
class WEBrick::TestFileHandler < Test::Unit::TestCase
def default_file_handler(filename)
@@ -8,6 +9,10 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase
klass.new(WEBrick::Config::HTTP, filename)
end
+ def windows?
+ File.directory?("\\")
+ end
+
def get_res_body(res)
return res.body.read rescue res.body
end
@@ -62,4 +67,134 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase
res = make_range_response(filename, "bytes=0-0, -2")
assert_match(%r{^multipart/byteranges}, res["content-type"])
end
+
+ def test_filehandler
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("200", res.code)
+ assert_equal("text/html", res.content_type)
+ assert_match(/HREF="#{this_file}"/, res.body)
+ }
+ req = Net::HTTP::Get.new("/#{this_file}")
+ http.request(req){|res|
+ assert_equal("200", res.code)
+ assert_equal("text/plain", res.content_type)
+ assert_equal(File.read(__FILE__), res.body)
+ }
+ end
+ end
+
+ def test_non_disclosure_name
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+ doc_root_opts = server[:DocumentRootOptions]
+ doc_root_opts[:NondisclosureName] = %w(.ht* *~ test_*)
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("200", res.code)
+ assert_equal("text/html", res.content_type)
+ assert_no_match(/HREF="#{File.basename(__FILE__)}"/, res.body)
+ }
+ req = Net::HTTP::Get.new("/#{this_file}")
+ http.request(req){|res|
+ assert_equal("404", res.code)
+ }
+ doc_root_opts[:NondisclosureName] = %w(.ht* *~ TEST_*)
+ http.request(req){|res|
+ assert_equal("404", res.code)
+ }
+ end
+ end
+
+ def test_directory_traversal
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/../../")
+ http.request(req){|res| assert_equal("400", res.code) }
+ req = Net::HTTP::Get.new("/..%5c../#{File.basename(__FILE__)}")
+ http.request(req){|res| assert_equal(windows? ? "200" : "404", res.code) }
+ req = Net::HTTP::Get.new("/..%5c..%5cruby.c")
+ http.request(req){|res| assert_equal("404", res.code) }
+ end
+ end
+
+ def test_unwise_in_path
+ if windows?
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/..%5c..")
+ http.request(req){|res| assert_equal("301", res.code) }
+ end
+ end
+ end
+
+ def test_short_filename
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webric~1.cgi/test")
+ http.request(req) do |res|
+ if windows?
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ else
+ assert_equal("404", res.code)
+ end
+ end
+
+ req = Net::HTTP::Get.new("/.htaccess")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ req = Net::HTTP::Get.new("/htacce~1")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ req = Net::HTTP::Get.new("/HTACCE~1")
+ http.request(req) {|res| assert_equal("404", res.code) }
+ end
+ end
+
+ def test_script_disclosure
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webrick.cgi/test")
+ http.request(req) do |res|
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ end
+
+ response_assertion = Proc.new do |res|
+ if windows?
+ assert_equal("200", res.code)
+ assert_equal("/test", res.body)
+ else
+ assert_equal("404", res.code)
+ end
+ end
+ req = Net::HTTP::Get.new("/webrick.cgi%20/test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi./test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi::$DATA/test")
+ http.request(req, &response_assertion)
+ end
+ end
end
diff --git a/test/webrick/utils.rb b/test/webrick/utils.rb
index f1e6e4b027..5db94e6cd5 100644
--- a/test/webrick/utils.rb
+++ b/test/webrick/utils.rb
@@ -1,3 +1,10 @@
+begin
+ loadpath = $:.dup
+ $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
+ require 'envutil'
+ensure
+ $:.replace(loadpath)
+end
require "webrick"
begin
require "webrick/https"
@@ -12,6 +19,11 @@ module TestWEBrick
return self
end
+ RubyBin = "\"#{EnvUtil.rubybin}\""
+ RubyBin << " \"-I#{File.expand_path("../..", File.dirname(__FILE__))}/lib\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\""
+
module_function
def start_server(klass, config={}, &block)
diff --git a/test/webrick/webrick_long_filename.cgi b/test/webrick/webrick_long_filename.cgi
new file mode 100755
index 0000000000..73ba729407
--- /dev/null
+++ b/test/webrick/webrick_long_filename.cgi
@@ -0,0 +1,36 @@
+#!ruby -d
+require "webrick/cgi"
+
+class TestApp < WEBrick::CGI
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ if (p = req.path_info) && p.length > 0
+ res.body = p
+ elsif (q = req.query).size > 0
+ res.body = q.keys.sort.collect{|key|
+ q[key].list.sort.collect{|v|
+ "#{key}=#{v}"
+ }.join(", ")
+ }.join(", ")
+ elsif %r{/$} =~ req.request_uri.to_s
+ res.body = ""
+ res.body << req.request_uri.to_s << "\n"
+ res.body << req.script_name
+ elsif !req.cookies.empty?
+ res.body = req.cookies.inject(""){|result, cookie|
+ result << "%s=%s\n" % [cookie.name, cookie.value]
+ }
+ res.cookies << WEBrick::Cookie.new("Customer", "WILE_E_COYOTE")
+ res.cookies << WEBrick::Cookie.new("Shipping", "FedEx")
+ else
+ res.body = req.script_name
+ end
+ end
+
+ def do_POST(req, res)
+ do_GET(req, res)
+ end
+end
+
+cgi = TestApp.new
+cgi.start
diff --git a/time.c b/time.c
index 8350a3a150..b8da8633a8 100644
--- a/time.c
+++ b/time.c
@@ -349,7 +349,7 @@ time_arg(argc, argv, tm, usec)
tm->tm_mon = -1;
for (i=0; i<12; i++) {
if (RSTRING(s)->len == 3 &&
- strcasecmp(months[i], RSTRING(v[1])->ptr) == 0) {
+ strcasecmp(months[i], RSTRING(s)->ptr) == 0) {
tm->tm_mon = i;
break;
}
@@ -1397,9 +1397,14 @@ time_succ(time)
VALUE time;
{
struct time_object *tobj;
+ int gmt;
GetTimeval(time, tobj);
- return rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
+ gmt = tobj->gmt;
+ time = rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
+ GetTimeval(time, tobj);
+ tobj->gmt = gmt;
+ return time;
}
/*
diff --git a/util.c b/util.c
index f4d0e67dd0..8c0c1b7c78 100644
--- a/util.c
+++ b/util.c
@@ -681,8 +681,8 @@ ruby_getcwd()
*
*/
-#define MDMINEXPT DBL_MIN_EXP
-#define MDMAXEXPT DBL_MAX_EXP
+#define MDMINEXPT DBL_MIN_10_EXP
+#define MDMAXEXPT DBL_MAX_10_EXP
static const
double powersOf10[] = { /* Table giving binary powers of 10. Entry */
diff --git a/variable.c b/variable.c