Rewrite the getn function (again) to fix any remaining issues.

This commit is contained in:
tg 2012-12-04 01:12:11 +00:00
parent 9d2fefeac4
commit 68c4dae6ef

41
misc.c
View File

@ -30,7 +30,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.201 2012/11/30 17:34:46 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.202 2012/12/04 01:12:11 tg Exp $");
#define KSH_CHVT_FLAG #define KSH_CHVT_FLAG
#ifdef MKSH_SMALL #ifdef MKSH_SMALL
@ -469,33 +469,40 @@ parse_args(const char **argv,
int int
getn(const char *s, int *ai) getn(const char *s, int *ai)
{ {
int c; char c;
unsigned int i, j, k; unsigned int i = 0;
bool neg = false; bool neg = false;
int rv = 0;
do { do {
c = *s++; c = *s++;
} while (ksh_isspace(c)); } while (ksh_isspace(c));
if (c == '-') {
switch (c) {
case '-':
neg = true; neg = true;
/* FALLTHROUGH */
case '+':
c = *s++; c = *s++;
} else if (c == '+') break;
c = *s++; }
k = neg ? 2147483648U : 2147483647U;
j = i = 0;
do { do {
if (!ksh_isdigit(c)) if (!ksh_isdigit(c))
goto getn_out; /* not numeric */
if ((j = i * 10 + c - '0') > k) return (0);
goto getn_out; if (i > 214748364U)
i = j; /* overflow on multiplication */
return (0);
i = i * 10U + (unsigned int)(c - '0');
/* now: i <= 2147483649U */
} while ((c = *s++)); } while ((c = *s++));
rv = 1;
getn_out: if (i > (neg ? 2147483648U : 2147483647U))
*ai = i == 2147483648U ? (int)i : neg ? -(int)i : (int)i; /* overflow for signed 32-bit int */
return (rv); return (0);
*ai = neg ? -(int)i : (int)i;
return (1);
} }
/** /**