aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-12-14 14:20:56 +0000
committerRon Yorston <rmy@pobox.com>2014-12-14 14:20:56 +0000
commit6d6d18d45c145899fce3a39553771cf0af671f30 (patch)
tree1936d18cbf61b9e0989464aad0a11c52cbeff7b7 /shell
parent0c204dc07b718244c360e0b84df66ce0a012e14f (diff)
parentacb8be721768b54075a51d1859d390904a0f1f6c (diff)
downloadbusybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.tar.gz
busybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.tar.bz2
busybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.zip
Merge branch 'busybox' into merge
Conflicts: archival/libarchive/open_transformer.c libbb/lineedit.c miscutils/man.c
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c10
-rw-r--r--shell/math.c27
2 files changed, 32 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3f3e2f4bc..b95356034 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6740,7 +6740,15 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
6740 len = number(loc); 6740 len = number(loc);
6741 } 6741 }
6742 } 6742 }
6743 if (pos >= orig_len) { 6743 if (pos < 0) {
6744 /* ${VAR:$((-n)):l} starts n chars from the end */
6745 pos = orig_len + pos;
6746 }
6747 if ((unsigned)pos >= orig_len) {
6748 /* apart from obvious ${VAR:999999:l},
6749 * covers ${VAR:$((-9999999)):l} - result is ""
6750 * (bash-compat)
6751 */
6744 pos = 0; 6752 pos = 0;
6745 len = 0; 6753 len = 0;
6746 } 6754 }
diff --git a/shell/math.c b/shell/math.c
index 3da151137..006221b6a 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -415,10 +415,29 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
415 } 415 }
416 else if (right_side_val == 0) 416 else if (right_side_val == 0)
417 return "divide by zero"; 417 return "divide by zero";
418 else if (op == TOK_DIV || op == TOK_DIV_ASSIGN) 418 else if (op == TOK_DIV || op == TOK_DIV_ASSIGN
419 rez /= right_side_val; 419 || op == TOK_REM || op == TOK_REM_ASSIGN) {
420 else if (op == TOK_REM || op == TOK_REM_ASSIGN) 420 /*
421 rez %= right_side_val; 421 * bash 4.2.45 x86 64bit: SEGV on 'echo $((2**63 / -1))'
422 *
423 * MAX_NEGATIVE_INT / -1 = MAX_POSITIVE_INT+1
424 * and thus is not representable.
425 * Some CPUs segfault trying such op.
426 * Others overflow MAX_POSITIVE_INT+1 to
427 * MAX_NEGATIVE_INT (0x7fff+1 = 0x8000).
428 * Make sure to at least not SEGV here:
429 */
430 if (right_side_val == -1
431 && rez << 1 == 0 /* MAX_NEGATIVE_INT or 0 */
432 ) {
433 right_side_val = 1;
434 }
435 if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
436 rez /= right_side_val;
437 else {
438 rez %= right_side_val;
439 }
440 }
422 } 441 }
423 442
424 if (is_assign_op(op)) { 443 if (is_assign_op(op)) {