diff options
| author | cremno <[email protected]> | 2014-07-11 12:59:15 +0200 |
|---|---|---|
| committer | cremno <[email protected]> | 2014-07-11 13:03:13 +0200 |
| commit | 9d597f4d9f421d7d1b8b3b6788e2c9add1f3b4e6 (patch) | |
| tree | c667e767893c52ee84a1e6fe75cf100aacf6c174 | |
| parent | ec45dbe16a418f58414f039f1a3b734cd14f63b8 (diff) | |
| download | mruby-9d597f4d9f421d7d1b8b3b6788e2c9add1f3b4e6.tar.gz mruby-9d597f4d9f421d7d1b8b3b6788e2c9add1f3b4e6.zip | |
allocate `history_path` dynamically
`PATH_MAX` doesn't have to be defined and if it is, then its value is
usually incorrect (possible buffer overflow).
Use `malloc` and `snprintf` instead to prevent this.
https://www.gnu.org/software/hurd/community/gsoc/project_ideas/maxpath.html
| -rw-r--r-- | mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index f96508d55..2d239d240 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -29,18 +29,48 @@ #define MIRB_USING_HISTORY() #endif -#ifdef ENABLE_READLINE -#include <limits.h> -static const char *history_file_name = ".mirb_history"; -char history_path[PATH_MAX]; -#endif - #include "mruby.h" #include "mruby/array.h" #include "mruby/proc.h" #include "mruby/compile.h" #include "mruby/string.h" +#ifdef ENABLE_READLINE + +static const char history_file_name[] = ".mirb_history"; + +static char * +get_history_path(void) +{ + char *path = NULL; + const char *home = getenv("HOME"); + +#ifdef _WIN32 + if (home != NULL) { + home = getenv("USERPROFILE"); + } +#endif + + if (home != NULL) { + int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); + if (len >= 0) { + size_t size = len + 1; + path = (char *)malloc(size); + if (path != NULL) { + int n = snprintf(path, size, "%s/%s", home, history_file_name); + if (n != len) { + free(path); + path = NULL; + } + } + } + } + + return path; +} + +#endif + static void p(mrb_state *mrb, mrb_value obj, int prompt) { @@ -283,7 +313,7 @@ main(int argc, char **argv) int last_char; int char_index; #else - char *home = NULL; + char *history_path; #endif mrbc_context *cxt; struct mrb_parser_state *parser; @@ -295,6 +325,17 @@ main(int argc, char **argv) int ai; unsigned int stack_keep = 0; +#ifdef ENABLE_READLINE + history_path = get_history_path(); + if (history_path == NULL) { + fputs("failed to get history path\n", stderr); + return EXIT_FAILURE; + } + + MIRB_USING_HISTORY(); + MIRB_READ_HISTORY(history_path); +#endif + /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { @@ -320,22 +361,6 @@ main(int argc, char **argv) ai = mrb_gc_arena_save(mrb); -#ifdef ENABLE_READLINE - MIRB_USING_HISTORY(); - home = getenv("HOME"); -#ifdef _WIN32 - if (!home) - home = getenv("USERPROFILE"); -#endif - if (home) { - strcpy(history_path, home); - strcat(history_path, "/"); - strcat(history_path, history_file_name); - MIRB_READ_HISTORY(history_path); - } -#endif - - while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); @@ -441,6 +466,7 @@ main(int argc, char **argv) #ifdef ENABLE_READLINE MIRB_WRITE_HISTORY(history_path); + free(history_path); #endif return 0; |
