Merge commit '8a475def9e3e21f780ebcf07dd607b26ceb00ea8'

Includes a fix for a potential overflow when doing shell arithmetic division.
This commit is contained in:
Stephen Heumann 2014-11-18 21:16:35 -06:00
commit ed1fff2c7b

View File

@ -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)
return "divide by zero";
else if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
rez /= right_side_val;
else if (op == TOK_REM || op == TOK_REM_ASSIGN)
rez %= right_side_val;
else if (op == TOK_DIV || op == TOK_DIV_ASSIGN
|| op == TOK_REM || op == TOK_REM_ASSIGN) {
/*
* 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)) {