vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 659558fcca65ed7c885dcd443a11884fd9330390
parent e2ef211acfc1c0b2e1334692307a8e78d8a0f83e
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Sat,  3 Dec 2016 13:31:59 +0100

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

Diffstat:
Msam.c | 3+--
Mvis-cmds.c | 26+++++++++++++++++++++-----
Mvis.h | 1-
3 files changed, 22 insertions(+), 8 deletions(-)

diff --git 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 @@ -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 @@ -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*);