diff options
author | Ron Yorston <rmy@pobox.com> | 2014-12-14 14:20:56 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-12-14 14:20:56 +0000 |
commit | 6d6d18d45c145899fce3a39553771cf0af671f30 (patch) | |
tree | 1936d18cbf61b9e0989464aad0a11c52cbeff7b7 /shell | |
parent | 0c204dc07b718244c360e0b84df66ce0a012e14f (diff) | |
parent | acb8be721768b54075a51d1859d390904a0f1f6c (diff) | |
download | busybox-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.c | 10 | ||||
-rw-r--r-- | shell/math.c | 27 |
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)) { |