printf: accept negative numbers for %x; sh: overflowed numbers are 0
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0f952c249e
commit
71016baf55
@ -78,6 +78,14 @@ static int multiconvert(const char *arg, void *result, converter convert)
|
|||||||
static void FAST_FUNC conv_strtoull(const char *arg, void *result)
|
static void FAST_FUNC conv_strtoull(const char *arg, void *result)
|
||||||
{
|
{
|
||||||
*(unsigned long long*)result = bb_strtoull(arg, NULL, 0);
|
*(unsigned long long*)result = bb_strtoull(arg, NULL, 0);
|
||||||
|
/* both coreutils 6.10 and bash 3.2:
|
||||||
|
* $ printf '%x\n' -2
|
||||||
|
* fffffffffffffffe
|
||||||
|
* Mimic that:
|
||||||
|
*/
|
||||||
|
if (errno) {
|
||||||
|
*(unsigned long long*)result = bb_strtoll(arg, NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void FAST_FUNC conv_strtoll(const char *arg, void *result)
|
static void FAST_FUNC conv_strtoll(const char *arg, void *result)
|
||||||
{
|
{
|
||||||
|
@ -562,7 +562,11 @@ arith(const char *expr, int *perrcode, a_e_h_t *math_hooks)
|
|||||||
}
|
}
|
||||||
if (isdigit(arithval)) {
|
if (isdigit(arithval)) {
|
||||||
numstackptr->var = NULL;
|
numstackptr->var = NULL;
|
||||||
|
errno = 0;
|
||||||
|
/* call strtoul[l]: */
|
||||||
numstackptr->val = strto_arith_t(expr, (char **) &expr, 0);
|
numstackptr->val = strto_arith_t(expr, (char **) &expr, 0);
|
||||||
|
if (errno)
|
||||||
|
numstackptr->val = 0; /* bash compat */
|
||||||
goto num;
|
goto num;
|
||||||
}
|
}
|
||||||
for (p = op_tokens; ; p++) {
|
for (p = op_tokens; ; p++) {
|
||||||
@ -592,7 +596,7 @@ arith(const char *expr, int *perrcode, a_e_h_t *math_hooks)
|
|||||||
lasttok = TOK_NUM;
|
lasttok = TOK_NUM;
|
||||||
|
|
||||||
/* Plus and minus are binary (not unary) _only_ if the last
|
/* Plus and minus are binary (not unary) _only_ if the last
|
||||||
* token was as number, or a right paren (which pretends to be
|
* token was a number, or a right paren (which pretends to be
|
||||||
* a number, since it evaluates to one). Think about it.
|
* a number, since it evaluates to one). Think about it.
|
||||||
* It makes sense. */
|
* It makes sense. */
|
||||||
if (lasttok != TOK_NUM) {
|
if (lasttok != TOK_NUM) {
|
||||||
@ -611,7 +615,7 @@ arith(const char *expr, int *perrcode, a_e_h_t *math_hooks)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We don't want a unary operator to cause recursive descent on the
|
/* We don't want an unary operator to cause recursive descent on the
|
||||||
* stack, because there can be many in a row and it could cause an
|
* stack, because there can be many in a row and it could cause an
|
||||||
* operator to be evaluated before its argument is pushed onto the
|
* operator to be evaluated before its argument is pushed onto the
|
||||||
* integer stack. */
|
* integer stack. */
|
||||||
|
@ -80,11 +80,11 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
|
|||||||
#if ENABLE_SH_MATH_SUPPORT_64
|
#if ENABLE_SH_MATH_SUPPORT_64
|
||||||
typedef long long arith_t;
|
typedef long long arith_t;
|
||||||
#define arith_t_fmt "%lld"
|
#define arith_t_fmt "%lld"
|
||||||
#define strto_arith_t strtoll
|
#define strto_arith_t strtoull
|
||||||
#else
|
#else
|
||||||
typedef long arith_t;
|
typedef long arith_t;
|
||||||
#define arith_t_fmt "%ld"
|
#define arith_t_fmt "%ld"
|
||||||
#define strto_arith_t strtol
|
#define strto_arith_t strtoul
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef const char *(*arith_var_lookup_t)(const char *name);
|
typedef const char *(*arith_var_lookup_t)(const char *name);
|
||||||
|
Loading…
Reference in New Issue
Block a user