diff options
| author | take_cheeze <[email protected]> | 2013-08-26 22:15:11 +0900 |
|---|---|---|
| committer | take_cheeze <[email protected]> | 2013-09-02 00:48:05 +0900 |
| commit | d19d9bb047a8b63c79442d5713be9205cf74c60c (patch) | |
| tree | ec1fc64bfaf10904a42b99a5f1466b04934e45ff | |
| parent | 596cd3f6e7416d44f31331c316ee77be06ce6ea4 (diff) | |
| download | mruby-d19d9bb047a8b63c79442d5713be9205cf74c60c.tar.gz mruby-d19d9bb047a8b63c79442d5713be9205cf74c60c.zip | |
fix crash in 2nd call to vsnprintf
| -rw-r--r-- | src/backtrace.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index 77906e843..6092aaf86 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -32,7 +32,7 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ... { va_list ap; mrb_value ary, str; - int len, ai; + int ai; if (level > 0) { return; @@ -40,12 +40,17 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ... ai = mrb_gc_arena_save(mrb); ary = mrb_obj_value((struct RArray*)stream); + va_start(ap, format); - len = vsnprintf(NULL, 0, format, ap); - str = mrb_str_new(mrb, 0, len); - vsnprintf(RSTRING_PTR(str), len, format, ap); - mrb_ary_push(mrb, ary, str); + str = mrb_str_new(mrb, 0, vsnprintf(NULL, 0, format, ap) + 1); va_end(ap); + + va_start(ap, format); + vsnprintf(RSTRING_PTR(str), RSTRING_LEN(str), format, ap); + va_end(ap); + + mrb_str_resize(mrb, str, RSTRING_LEN(str) - 1); + mrb_ary_push(mrb, ary, str); mrb_gc_arena_restore(mrb, ai); } |
