if the argument is in the (-1, 0) range, the integer part is zero and multiplying it by -1 has no effect, so the caller can't tell that the argument was negative --- builtins/read.def | 10 +++++----- examples/loadables/sleep.c | 4 ++-- externs.h | 2 +- lib/sh/uconvert.c | 7 ++++--- 4 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/builtins/read.def b/builtins/read.def index 3c38bc02..fb4f9ac7 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -208,7 +208,7 @@ read_builtin (list) int lastsig, t_errno; int mb_cur_max; unsigned int tmsec, tmusec; - long ival, uval; + long ival, uval, sign; intmax_t intval; char c; char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; @@ -302,8 +302,8 @@ read_builtin (list) break; #endif case 't': - code = uconvert (list_optarg, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) + code = uconvert (list_optarg, &sign, &ival, &uval, (char **)NULL); + if (code == 0 || sign < 0 || uval < 0) { builtin_error (_("%s: invalid timeout specification"), list_optarg); return (EXECUTION_FAILURE); @@ -403,8 +403,8 @@ read_builtin (list) /* $TMOUT, if set, is the default timeout for read. */ if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) { - code = uconvert (e, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) + code = uconvert (e, &sign, &ival, &uval, (char **)NULL); + if (code == 0 || sign < 0 || uval < 0) tmsec = tmusec = 0; else { diff --git a/examples/loadables/sleep.c b/examples/loadables/sleep.c index 204601f5..971874f0 100644 --- a/examples/loadables/sleep.c +++ b/examples/loadables/sleep.c @@ -58,7 +58,7 @@ parse_gnutimefmt (char *string, long *sp, long *up) { int c, r; char *s, *ep; - long tsec, tusec, accumsec, accumusec, t; + long tsec, tusec, accumsec, accumusec, t, sign; int mult; tsec = tusec = 0; @@ -66,7 +66,7 @@ parse_gnutimefmt (char *string, long *sp, long *up) mult = 1; for (s = string; s && *s; s++) { - r = uconvert(s, &accumsec, &accumusec, &ep); + r = uconvert(s, &sign, &accumsec, &accumusec, &ep); if (r == 0 && *ep == 0) return r; c = *ep; diff --git a/externs.h b/externs.h index 931dba9c..4030e39a 100644 --- a/externs.h +++ b/externs.h @@ -494,7 +494,7 @@ extern int sh_mktmpfd PARAMS((char *, int, char **)); extern char *sh_mktmpdir PARAMS((char *, int)); /* declarations for functions defined in lib/sh/uconvert.c */ -extern int uconvert PARAMS((char *, long *, long *, char **)); +extern int uconvert PARAMS((char *, long *, long *, long *, char **)); /* declarations for functions defined in lib/sh/ufuncs.c */ extern unsigned int falarm PARAMS((unsigned int, unsigned int)); diff --git a/lib/sh/uconvert.c b/lib/sh/uconvert.c index 457552eb..c11d16c0 100644 --- a/lib/sh/uconvert.c +++ b/lib/sh/uconvert.c @@ -39,7 +39,8 @@ #define RETURN(x) \ do { \ - if (ip) *ip = ipart * mult; \ + if (sp) *sp = mult; \ + if (ip) *ip = ipart; \ if (up) *up = upart; \ if (ep) *ep = p; \ return (x); \ @@ -57,9 +58,9 @@ static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 }; Return 1 if value converted; 0 if invalid integer for either whole or fractional parts. */ int -uconvert(s, ip, up, ep) +uconvert(s, sp, ip, up, ep) char *s; - long *ip, *up; + long *sp, *ip, *up; char **ep; { int n, mult; -- 2.34.1