From 9d597f4d9f421d7d1b8b3b6788e2c9add1f3b4e6 Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 11 Jul 2014 12:59:15 +0200 Subject: 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 --- mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 72 ++++++++++++++++++++++---------- 1 file 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 -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; -- cgit v1.2.3 From 82a335643eabb40f96f73603a41ca244223a3281 Mon Sep 17 00:00:00 2001 From: cremno Date: Sat, 12 Jul 2014 11:50:51 +0200 Subject: call `mrb_malloc_simple` instead of `malloc` --- mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 36 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 2d239d240..40fc5cc93 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -40,7 +40,7 @@ static const char history_file_name[] = ".mirb_history"; static char * -get_history_path(void) +get_history_path(mrb_state *mrb) { char *path = NULL; const char *home = getenv("HOME"); @@ -55,11 +55,11 @@ get_history_path(void) int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); if (len >= 0) { size_t size = len + 1; - path = (char *)malloc(size); + path = (char *)mrb_malloc_simple(mrb, size); if (path != NULL) { int n = snprintf(path, size, "%s/%s", home, history_file_name); if (n != len) { - free(path); + mrb_free(mrb, path); path = NULL; } } @@ -325,17 +325,6 @@ 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) { @@ -351,6 +340,18 @@ main(int argc, char **argv) return n; } +#ifdef ENABLE_READLINE + history_path = get_history_path(mrb); + if (history_path == NULL) { + fputs("failed to get history path\n", stderr); + mrb_close(mrb); + return EXIT_FAILURE; + } + + MIRB_USING_HISTORY(); + MIRB_READ_HISTORY(history_path); +#endif + print_hint(); cxt = mrbc_context_new(mrb); @@ -461,13 +462,14 @@ main(int argc, char **argv) mrb_parser_free(parser); cxt->lineno++; } - mrbc_context_free(mrb, cxt); - mrb_close(mrb); #ifdef ENABLE_READLINE MIRB_WRITE_HISTORY(history_path); - free(history_path); + mrb_free(mrb, history_path); #endif + mrbc_context_free(mrb, cxt); + mrb_close(mrb); + return 0; } -- cgit v1.2.3