diff options
| author | cremno <[email protected]> | 2014-08-27 12:51:10 +0200 |
|---|---|---|
| committer | cremno <[email protected]> | 2014-08-27 12:51:10 +0200 |
| commit | 89b27648dd2cc05ea60bb6c79aec4db1ef712497 (patch) | |
| tree | 7f4a15c95d03702d9e8a4c1cff6b3bea135b29e4 /src/symbol.c | |
| parent | ecda19f4024cd853d933b059ba9f082a42837096 (diff) | |
| download | mruby-89b27648dd2cc05ea60bb6c79aec4db1ef712497.tar.gz mruby-89b27648dd2cc05ea60bb6c79aec4db1ef712497.zip | |
add symbol table overflow check
Since raising an error might intern a few new strings, some symbols need
to be reserved. 8 should be sufficient.
If the real limit has been reached, mrb_bug() is called.
Diffstat (limited to 'src/symbol.c')
| -rw-r--r-- | src/symbol.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/symbol.c b/src/symbol.c index 69f9c90ee..5e40fa315 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -5,6 +5,7 @@ */ #include <ctype.h> +#include <limits.h> #include <string.h> #include "mruby.h" #include "mruby/khash.h" @@ -34,6 +35,15 @@ sym_hash_func(mrb_state *mrb, const symbol_name s) KHASH_DECLARE(n2s, symbol_name, mrb_sym, TRUE) KHASH_DEFINE (n2s, symbol_name, mrb_sym, TRUE, sym_hash_func, sym_hash_equal) /* ------------------------------------------------------ */ + +#define MRB_SYM_MAX SHRT_MAX + +static mrb_value +sym_tbl_overflow_new_str(mrb_state *mrb, const char *name, size_t len) +{ + return mrb_str_inspect(mrb, mrb_str_new(mrb, name, len)); +} + static mrb_sym sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) { @@ -53,6 +63,19 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) if (k != kh_end(h)) return kh_value(h, k); + if (mrb->symbol_table_overflow) { + if (mrb->symidx == MRB_SYM_MAX) { + mrb_bug(mrb, "symbol table overflow (symbol %S)", sym_tbl_overflow_new_str(mrb, name, len)); + } + } + else { + if (mrb->symidx >= MRB_SYM_MAX - 8) { /* raising might intern a few new strings */ + mrb->symbol_table_overflow = TRUE; + mrb_raisef(mrb, E_RUNTIME_ERROR, "symbol table overflow (symbol %S)", + sym_tbl_overflow_new_str(mrb, name, len)); + } + } + sym = ++mrb->symidx; if (lit) { sname.name = name; |
