ash,hush: do not segfault on $((2**63 / -1))
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
08a5dab181
commit
8a475def9e
27
shell/math.c
27
shell/math.c
@ -415,10 +415,29 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
|
|||||||
}
|
}
|
||||||
else if (right_side_val == 0)
|
else if (right_side_val == 0)
|
||||||
return "divide by zero";
|
return "divide by zero";
|
||||||
else if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
|
else if (op == TOK_DIV || op == TOK_DIV_ASSIGN
|
||||||
rez /= right_side_val;
|
|| op == TOK_REM || op == TOK_REM_ASSIGN) {
|
||||||
else if (op == TOK_REM || op == TOK_REM_ASSIGN)
|
/*
|
||||||
rez %= right_side_val;
|
* bash 4.2.45 x86 64bit: SEGV on 'echo $((2**63 / -1))'
|
||||||
|
*
|
||||||
|
* MAX_NEGATIVE_INT / -1 = MAX_POSITIVE_INT+1
|
||||||
|
* and thus is not representable.
|
||||||
|
* Some CPUs segfault trying such op.
|
||||||
|
* Others overfolw MAX_POSITIVE_INT+1 to
|
||||||
|
* MAX_NEGATIVE_INT (0x7fff+1 = 0x8000).
|
||||||
|
* Make sure to at least not SEGV here:
|
||||||
|
*/
|
||||||
|
if (right_side_val == -1
|
||||||
|
&& rez << 1 == 0 /* MAX_NEGATIVE_INT or 0 */
|
||||||
|
) {
|
||||||
|
right_side_val = 1;
|
||||||
|
}
|
||||||
|
if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
|
||||||
|
rez /= right_side_val;
|
||||||
|
else {
|
||||||
|
rez %= right_side_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_assign_op(op)) {
|
if (is_assign_op(op)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user