| Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
|
|
|
|
|
|
[255, 255, 255, 255, 255].hash raises "can't convert Float into Integer"
|
|
Fix segfault when `eval("__FILE__")` is executed
|
|
|
|
|
|
Fix bug in mruby-test gem (fix #3094)
|
|
Add more limitations
|
|
|
|
- defined?
- alias on global variables
- Operator modification
- Kernel.binding missing
|
|
In an used build path mruby-test wasn't updating mrbtest.c in the
case that the mgem selection was changed. This lead to:
- a missing reference in case a GEM was removed
- ignoring all new GEMs added to the build configuration
This fix keeps track of the active gems and demands a rebuild of
mrbtest.c in case that the gem selection changed.
|
|
|
|
Add toolchain support for OpenWRT
|
|
Addition to mruby limitation documentation
|
|
|
|
|
|
|
|
|
|
Limitations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fix missing dependency on mruby-print to support 'puts'
|
|
|
|
Add String#rjust to mruby-string-ext
|
|
Fix a typo
|
|
su ported ->
supported
^
|
|
|
|
|
|
protect NoMethodError from calling to_hash in replace
|
|
|
|
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.
|
|
|
|
Small grammar fix
|
|
[ci skip]
|
|
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
|
|
Update license year range to 2016
|
|
|
|
Fix passing all zero string to Kernel#Integer
|
|
|