An error occurred fetching the project authors.
  1. 14 Jul, 2016 1 commit
  2. 10 May, 2016 1 commit
  3. 09 May, 2016 1 commit
  4. 27 Apr, 2016 1 commit
  5. 11 Apr, 2016 1 commit
  6. 24 Mar, 2016 1 commit
    • Kouhei Sutou's avatar
      Add missing regs update · c69cba2a
      Kouhei Sutou authored
      mrb_vm_define_class() may realloc() mrb->c->stack because it calls
      mrb_funcall() for inherited hook. If mrb->c->stack is realloc()-ed, regs
      refers orphan address.
      c69cba2a
  7. 19 Jan, 2016 1 commit
    • Kouhei Sutou's avatar
      Fix SEGV on re-raising NoMemoryError · 1d84b320
      Kouhei Sutou authored
      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
      1d84b320
  8. 07 Jan, 2016 1 commit
  9. 04 Jan, 2016 1 commit
  10. 02 Jan, 2016 2 commits
  11. 30 Dec, 2015 1 commit
  12. 29 Dec, 2015 1 commit
    • Kouhei Sutou's avatar
      Support backtrace after method calls · a561bdb2
      Kouhei Sutou authored
      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.
      a561bdb2
  13. 27 Nov, 2015 1 commit
  14. 16 Nov, 2015 1 commit
  15. 07 Nov, 2015 1 commit
  16. 26 Oct, 2015 1 commit
  17. 19 Oct, 2015 1 commit
  18. 02 Sep, 2015 1 commit
  19. 10 Aug, 2015 1 commit
  20. 30 Jul, 2015 2 commits
  21. 13 Jul, 2015 1 commit
  22. 07 Jul, 2015 1 commit
  23. 31 May, 2015 1 commit
  24. 25 May, 2015 1 commit
  25. 15 May, 2015 1 commit
    • cremno's avatar
      remove mrb_define_method_vm() function · 2106d4d4
      cremno authored
      It isn't needed as it's very similar to mrb_define_method_raw() and also
      there's only one place where mrb_proc_ptr() actually has to be called.
      
      Inspired by @furunkel's method cache patch (#2764).
      2106d4d4
  26. 26 Apr, 2015 2 commits
  27. 21 Mar, 2015 1 commit
  28. 05 Mar, 2015 1 commit
  29. 28 Feb, 2015 1 commit
  30. 27 Feb, 2015 1 commit
  31. 26 Feb, 2015 1 commit
  32. 24 Feb, 2015 1 commit
    • Kouhei Sutou's avatar
      Fix a crash bug on raising after realloc · 3fefe52f
      Kouhei Sutou authored
      The following program reproduces this problem:
      
          #include <mruby.h>
      
          static mrb_value
          recursive(mrb_state *mrb, mrb_value self)
          {
            mrb_int n;
      
            mrb_get_args(mrb, "i", &n);
      
            if (n == 0) {
              mrb_raise(mrb, E_RUNTIME_ERROR, "XXX");
            } else {
              mrb_funcall(mrb, self, "recursive", 1, mrb_fixnum_value(n - 1));
            }
      
            return self;
          }
      
          int
          main(void)
          {
            mrb_state *mrb;
      
            mrb = mrb_open();
      
            mrb_define_method(mrb, mrb->kernel_module, "recursive", recursive,
                              MRB_ARGS_REQ(1));
            mrb_funcall(mrb, mrb_top_self(mrb), "recursive", 1, mrb_fixnum_value(30));
      
            mrb_close(mrb);
          }
      
      Recursive method call isn't required. It's just for expanding call info
      stack.
      
      If mrb_realloc() is called in cipush(), cibase address is changed. So,
      we shouldn't compare ci before mrb_realloc() and cibase after
      mrb_realloc(). It accesses unknown address and causes crash.
      3fefe52f
  33. 23 Feb, 2015 1 commit
    • Go Saito's avatar
      fix pointer dereference after realloc · 42d23084
      Go Saito authored
      In src/vm.c: mrb_funcall_with_block
      stack_extend may realloc mrb->c->stbase, if argv points on mruby's stack,
      then it points invalid address after stack_extend.
      
      e.g. src/class.c: mrb_instance_new
      
      This code:
      
      ```ruby
      class A
        def initialize(a0,a1,a2,a3,a4)
          a0.is_a? Array
        end
      end
      
      def f(a0,a1,a2,a3,a4)
        A.new(a0,a1,a2,a3,a4)
        f(a0,a1,a2,a3,a4)
      end
      
      f(0,1,2,3,4)
      ```
      
      is expected to get exception
      ```
      stack level too deep. (limit=(0x40000 - 128)) (SystemStackError)
      ```
      
      but get segfault.
      Signed-off-by: default avatarGo Saito <gos@iij.ad.jp>
      42d23084
  34. 05 Feb, 2015 1 commit
    • Kouhei Sutou's avatar
      Fix ensure with yield context on break and return · 8cb40fcd
      Kouhei Sutou authored
      How to reproduce:
      
          class A
            def x
              yield
            ensure
              y
            end
      
            def y
            end
          end
      
          # Work
          A.new.x do
          end
      
          # Not work
          # trace:
          # 	[2] /tmp/a.rb:5:in A.x
          # 	[0] /tmp/a.rb:15
          # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError)
          A.new.x do
            break
          end
      
          # trace:
          # 	[2] /tmp/a.rb:5:in A.call
          # 	[0] /tmp/a.rb:19
          # /tmp/a.rb:5: undefined method 'y' for main (NoMethodError)
          lambda do
            A.new.x do
              return
            end
          end.call
      
      `self` in ensure is broken when yield and break/return are used.
      8cb40fcd
  35. 26 Jan, 2015 1 commit
  36. 28 Nov, 2014 1 commit
  37. 19 Nov, 2014 1 commit
    • sdottaka's avatar
      Fix an error when calling a method implemented in C by super() with arguments.... · 820f6d14
      sdottaka authored
      Fix an error when calling a method implemented in C by super() with arguments. This fix makes the following code workable:
      
      Expected:
      
      class MRBTime < Time; def self.new; super(2012, 4, 21); end; end
      MRBTime.new # => Sat Apr 21 00:00:00 2012
      
      Actual:
      
      class MRBTime < Time; def self.new; super(2012, 4, 21); end; end
      MRBTime.new # => can't convert nil into Integer (TypeError)
      820f6d14