From 5b181f782a1558380afe24331d2f1b3b82b6f8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sat, 3 Dec 2016 13:31:59 +0100 Subject: vis: improve :set option number parsing Only accept numbers in range [0, INT_MAX]. Reject trailing garbage, where before something like `:set cc 50NaN` worked it will now cause an error. Close #418 --- sam.c | 3 +-- vis-cmds.c | 26 +++++++++++++++++++++----- vis.h | 1 - 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/sam.c b/sam.c index 2c4fcb6..337f8a4 100644 --- a/sam.c +++ b/sam.c @@ -269,7 +269,6 @@ typedef struct { OPTION_TYPE_STRING, OPTION_TYPE_BOOL, OPTION_TYPE_NUMBER, - OPTION_TYPE_UNSIGNED, } type; enum { OPTION_FLAG_NONE = 0, @@ -370,7 +369,7 @@ static const OptionDef options[] = { }, [OPTION_HORIZON] = { { "horizon" }, - OPTION_TYPE_UNSIGNED, OPTION_FLAG_WINDOW, + OPTION_TYPE_NUMBER, OPTION_FLAG_WINDOW, "Number of bytes to consider for syntax highlighting", }, }; diff --git a/vis-cmds.c b/vis-cmds.c index 18169f5..bc42268 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -115,13 +115,29 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor } break; case OPTION_TYPE_NUMBER: - case OPTION_TYPE_UNSIGNED: if (!argv[2]) { vis_info_show(vis, "Expecting number"); return false; } - /* TODO: error checking? long type */ - arg.u = strtoul(argv[2], NULL, 10); + char *ep; + errno = 0; + long lval = strtol(argv[2], &ep, 10); + if (argv[2][0] == '\0' || *ep != '\0') { + vis_info_show(vis, "Invalid number"); + return false; + } + + if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) || + (lval > INT_MAX || lval < INT_MIN)) { + vis_info_show(vis, "Number overflow"); + return false; + } + + if (lval < 0) { + vis_info_show(vis, "Expecting positive number"); + return false; + } + arg.i = lval; break; default: return false; @@ -230,7 +246,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor view_colorcolumn_set(win->view, arg.i); break; case OPTION_HORIZON: - win->horizon = arg.u; + win->horizon = arg.i; break; } @@ -631,7 +647,7 @@ static bool cmd_help(Vis *vis, Win *win, Command *cmd, const char *argv[], Curso opt->names[1] ? "|" : "", opt->names[1] ? opt->names[1] : "", opt->type == OPTION_TYPE_BOOL ? " on|off" : "", - opt->type == OPTION_TYPE_NUMBER || opt->type == OPTION_TYPE_UNSIGNED ? " nn" : ""); + opt->type == OPTION_TYPE_NUMBER ? " nn" : ""); text_appendf(txt, " %-30s %s\n", names, opt->help ? opt->help : ""); } diff --git a/vis.h b/vis.h index 1cf9725..4f1fd29 100644 --- a/vis.h +++ b/vis.h @@ -45,7 +45,6 @@ typedef struct { typedef union { /* various types of arguments passed to key action functions */ bool b; int i; - size_t u; const char *s; const void *v; void (*w)(View*); -- cgit v1.2.3