Commit Graph

3115 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 62b06ab4d4 [cppcheck] mrb_str_rindex() remove unnecessary len update by chars2bytes() 2016-02-05 21:54:07 +09:00
Yukihiro "Matz" Matsumoto af4dd3d579 [cppcheck] remove duplicated break 2016-02-05 21:48:44 +09:00
Yukihiro "Matz" Matsumoto 3c73c315f4 Hash: check flags before accessing ifnone; ref #980 2016-02-05 10:08:28 +09:00
Yukihiro "Matz" Matsumoto 25e4ec3f37 cache UTF8 status for utf8_strlen(); ref #980 2016-02-04 23:33:16 +09:00
Yukihiro "Matz" Matsumoto 5e514c910f cache mrb_regexp_p(); ref #980 2016-02-04 23:22:01 +09:00
Kouhei Sutou c77123d20a Fix SEGV by stack extension in mrb_get_args()
mrb_get_args() keeps pointer of the current stack. But address of the
current stack maybe changed by method call.

'i' format character calls #to_i when the argument isn't integer but
has #to_i.

Here is a code that may call #to_i in mrb_get_args():

    case 'i':
      // ...
            default:
              *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
              break;
     // ...

Here is a code #to_i is called:

    class X
      def initialize(i)
        @i = i
      end

      def to_i
        @i
      end
    end

    [][X.new(0), 0] # X#to_i is called

So, mrb_get_args() shouldn't keep pointer and use it. mrb_get_args()
should always refer mrb->ci->stack to use valid address of the current
stack.
2016-01-22 00:20:00 +09:00
Kouhei Sutou 1d84b3205a Fix SEGV on re-raising NoMemoryError
Think about the following Ruby script:

segv.rb:

    begin
      lambda do
        lambda do
          "x" * 1000 # NoMemoryError
        end.call
      end.call
    rescue
      raise
    end

If memory can't allocate after `"x" * 1000`, mruby crashes.

Because L_RAISE: block in mrb_vm_exec() calls mrb_env_unshare() via
cipop() and mrb_env_unshare() uses allocated memory without NULL check:

L_RAISE: block:

    L_RAISE:
      // ...
      while (ci[0].ridx == ci[-1].ridx) {
        cipop(mrb);
        // ...
      }

cipop():

    static void
    cipop(mrb_state *mrb)
    {
      struct mrb_context *c = mrb->c;

      if (c->ci->env) {
        mrb_env_unshare(mrb, c->ci->env);
      }

      c->ci--;
    }

mrb_env_unshare():

    MRB_API void
    mrb_env_unshare(mrb_state *mrb, struct REnv *e)
    {
      size_t len = (size_t)MRB_ENV_STACK_LEN(e);
      // p is NULL in this case
      mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);

      MRB_ENV_UNSHARE_STACK(e);
      if (len > 0) {
        stack_copy(p, e->stack, len); // p is NULL but used. It causes SEGV.
      }
      e->stack = p;
      mrb_write_barrier(mrb, (struct RBasic *)e);
    }

To solve the SEGV, this change always raises NoMemoryError even when
realloc() is failed after the first NoMemoryError in
mrb_realloc(). mrb_unv_unshare() doesn't need to check NULL with this
change.

But it causes infinite loop in the following while:

    L_RAISE:
      // ...
      while (ci[0].ridx == ci[-1].ridx) {
        cipop(mrb);
        // ...
      }

Because cipop() never pops ci.

This change includes cipop() change. The change pops ci even when
mrb_unv_unshare() is failed by NoMemoryError.

This case can be reproduced by the following program:

    #include <stdlib.h>
    #include <mruby.h>
    #include <mruby/compile.h>

    static void *
    allocf(mrb_state *mrb, void *ptr, size_t size, void *ud)
    {
      static mrb_bool always_fail = FALSE;

      if (size == 1001) {
        always_fail = TRUE;
      }
      if (always_fail) {
        return NULL;
      }

      if (size == 0) {
        free(ptr);
        return NULL;
      } else {
        return realloc(ptr, size);
      }
    }

    int
    main(int argc, char **argv)
    {
      mrb_state *mrb;
      mrbc_context *c;
      FILE *file;

      mrb = mrb_open_allocf(allocf, NULL);
      c = mrbc_context_new(mrb);
      file = fopen(argv[1], "r");
      mrb_load_file_cxt(mrb, file, c);
      fclose(file);
      mrbc_context_free(mrb, c);
      mrb_close(mrb);

      return EXIT_SUCCESS;
    }

Try the following command lines:

    % cc -I include -L build/host/lib -O0 -g3 -o no-memory no-memory.c -lmruby -lm
    % ./no-memory segv.rb
2016-01-19 16:37:42 +09:00
Syohei YOSHIDA 787685a0b9 Fix all zero string case 2016-01-14 11:07:07 +09:00
Yukihiro "Matz" Matsumoto 8143285956 Merge pull request #3080 from kou/fix-class-variable-in-module
Fix class variable reference in module
2016-01-11 10:00:34 +09:00
Kouhei Sutou ad492eb9f3 Fix class variable reference in module
Fix #3079
2016-01-11 00:34:15 +09:00
Simon Génier 146a9eeb38 Fix segfault on mrb_exc_backtrace.
The code to iterate over backtrace locations was changed in #3065, but
unfortunately output_backtrace was not correctly updated to forward the
callback.
2016-01-07 11:24:16 -05:00
Yukihiro "Matz" Matsumoto f3cce24035 replace mrb_toplevel_run() by mrb_top_run() 2016-01-07 22:48:22 +09:00
Yukihiro "Matz" Matsumoto f7afe1d82a change mrb_run related API names; compatibility macros provided 2016-01-07 22:36:29 +09:00
Yukihiro "Matz" Matsumoto 725b3ca5a7 move KHASH_DECLARE(ht..) to mruby/hash.h; close #3073 2016-01-07 12:46:38 +09:00
Syohei YOSHIDA 931cc0359a printf precision parameter must be 'int' type
There is a problem when MRB_INT64 is enabled.
2016-01-07 11:06:20 +09:00
ksss af21b365d2 symname_p support !~ 2016-01-06 11:59:09 +09:00
Yukihiro "Matz" Matsumoto 9145aed85e bytes2chars() conversion to fail if target byte offset is not on the character boundary; ref #3067
that means String#index matches first byte of a multi-byte character. this behavior is different
from CRuby, but a compromise for mruby which does not have encoding stuffs.
2016-01-05 18:05:25 +09:00
Yukihiro "Matz" Matsumoto aec825a64c stack_extend before eval_under() 2016-01-04 10:22:38 +09:00
Yukihiro "Matz" Matsumoto aa1f668b80 instance_eval should pass the receiver as a block parameter; close #3029 2016-01-02 22:01:00 +09:00
Yukihiro "Matz" Matsumoto bd462c5edc mruby-fiber: fiber_switch() to use nesting VM when it's called from C API or mrb_funcall(); close #3056 2016-01-02 13:48:45 +09:00
Yukihiro "Matz" Matsumoto 31b8469bff Merge pull request #3067 from ksss/use-memchr
Use memchr for performance
2015-12-31 21:20:51 +09:00
ksss 6c1b6ef7a5 Use memchr for performance
```ruby
s = "b"
str = ("a" * 100 + s)

t = Time.now
str.index(s)
puts Time.now - t
```

before => 0.000788
after  => 0.000508

---

```ruby
s = "b"
str = ("a" * 100 * 1024 * 1024 + s)

t = Time.now
str.index(s)
puts Time.now - t
```

before => 0.225474
after  => 0.008658
2015-12-31 17:52:22 +09:00
Yukihiro "Matz" Matsumoto 3531fe179c GC must scan env from fibers even when it's not yet copied to heap; fix #3063 2015-12-31 00:11:37 +09:00
Kouhei Sutou a561bdb25f Support backtrace after method calls
GitHub: fix #2902, #2917

The current implementation traverses stack to retrieve backtrace. But
stack will be changed when some operations are occurred. It means that
backtrace may be broken after some operations.

This change (1) saves the minimum information to retrieve backtrace when
exception is raised and (2) restores backtrace from the minimum
information when backtrace is needed. It reduces overhead for creating
backtrace Ruby objects.

The space for the minimum information is reused by multiple
exceptions. So memory allocation isn't occurred for each exception.
2015-12-29 20:36:12 +09:00
Kouhei Sutou 1eeeecb08a Fix indent 2015-12-29 14:20:10 +09:00
Yasuhiro Matsumoto 7cc33af2dc fix build on VS2012 2015-12-22 17:46:20 +09:00
Kei Sawada d69b5c3fc7 Add case statement of MRB_TT_SCLASS in mrb_obj_is_kind_of() 2015-12-16 15:54:03 +09:00
Yukihiro "Matz" Matsumoto f54a98ff15 mrb_str_len_to_inum(): fixed a bug with MRB_INT_MIN conversion; fix #3048 2015-12-16 14:49:43 +09:00
Yukihiro "Matz" Matsumoto d18c55fca7 mrb_str_len_to_inum(): fixed a bug with underscores in digits; fix #3049 2015-12-16 14:49:08 +09:00
Yukihiro "Matz" Matsumoto 2a234a93d7 mrb_str_len_to_inum(): string may not be NUL terminated; ref #3043 2015-12-14 10:59:56 +09:00
Yukihiro "Matz" Matsumoto 19c744e14d mrb_str_len_to_inum(): fixed a bug with separating _ in the digits; ref #3043 2015-12-14 10:59:56 +09:00
Yukihiro "Matz" Matsumoto 26a25e1666 mrb_str_len_to_inum: should not raise "string contains null byte" error on "0x"; fix #3043 2015-12-12 16:33:48 +09:00
Yukihiro "Matz" Matsumoto ad333cd191 mrb_str_len_to_inum: converting may not be terminated by NUL; fix #3044 2015-12-12 16:33:48 +09:00
Yukihiro "Matz" Matsumoto 9a21aa2d3c preserve original string for error message 2015-12-01 21:42:07 +09:00
Yukihiro "Matz" Matsumoto ca417dac26 mrb_str_len_to_inum(): inspect string in error message 2015-12-01 21:41:53 +09:00
Yukihiro "Matz" Matsumoto 36fabe104b new API function mrb_string_value_len() 2015-12-01 16:18:01 +09:00
Yukihiro "Matz" Matsumoto 0701236dac mrb_str_to_inum(): should treat null byte in strings properly; fix #3040 2015-12-01 16:11:47 +09:00
Yukihiro "Matz" Matsumoto d3a56a6949 mrb_cstr_to_inum(): should ignore trailing white spaces even when badcheck set 2015-12-01 11:14:22 +09:00
Yukihiro "Matz" Matsumoto dbb8cf637e mrb_str_to_inum(): should raise error when string contains null byte 2015-12-01 11:13:32 +09:00
Yukihiro "Matz" Matsumoto 9f2fca6ebe mrb_str_to_inum(): no need to call mrb_string_value_cstr() here; ref 05411ee 2015-12-01 10:54:00 +09:00
Yukihiro "Matz" Matsumoto 05411ee15e mrb_string_value_cstr() should not raise error for frozen strings
cf. http://qiita.com/tsahara@github/items/b2a442af95ac893e10a1 (Japanese).
2015-12-01 10:45:43 +09:00
Yukihiro "Matz" Matsumoto 5c405dea3d include changed from by quotes ("") to by brackets (<>); close #3032 2015-11-27 17:48:23 +09:00
Yukihiro "Matz" Matsumoto 996417cabf integer range check was moved to mrb_flo_to_fixnum(); ref #3025 2015-11-19 22:49:50 +09:00
murase_syuka ef95dcd390 Bugfix nagative-number lshift() bit overflow 2015-11-18 21:37:17 +09:00
murase_syuka a4d5588101 Bugfix lshift() bit overflow; close #3023 2015-11-18 01:00:46 +09:00
cremno e2e23c66d2 add RUBY_ENGINE_VERSION
RUBY_ENGINE_VERSION is equivalent to MRUBY_VERSION. It would be a
standard way to get the interpreter version (without a case expression).

It's also already defined by CRuby 2.3, JRuby 9000, Opal, and Rubinius.
2015-11-17 00:13:31 +01:00
Yukihiro "Matz" Matsumoto 4440566b95 DISABLE_STDIO/ENABLE_DEBUG macros to rename; close #3014
changes:
 * rename DISABLE_STDIO -> MRB_DISABLE_STDIO
 * rename ENABLE_DEBUG -> MRB_ENABLE_DEBUG_HOOK
 * no more opposite macro definitions (e.g. ENABLE_STDIO, DISABLE_DEBUG).
 * rewrite above macro references throughout the code.
 * update documents
2015-11-17 07:30:34 +09:00
murase_syuka cd1a566002 fix comment 2015-11-16 22:27:42 +09:00
Yukihiro "Matz" Matsumoto d6e1762346 Merge pull request #3004 from cremno/remove-return
remove return
2015-11-08 21:36:54 +09:00
Yukihiro "Matz" Matsumoto d3b323cf2f PR #2521 did not work for singleton classes for non-class objects; fix #3003 2015-11-07 15:51:00 +09:00