mirror of
https://git.busybox.net/busybox.git
synced 2024-11-23 13:43:28 +08:00
shell/math: do not accept $((36#@))
function old new delta parse_with_base 170 174 +4 arith_apply 996 991 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-5) Total: -1 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
38f769ab4e
commit
045924ed7d
38
shell/math.c
38
shell/math.c
@ -128,7 +128,8 @@ typedef unsigned char operator;
|
|||||||
* Consider * and /
|
* Consider * and /
|
||||||
*/
|
*/
|
||||||
#define tok_decl(prec,id) (((id)<<5) | (prec))
|
#define tok_decl(prec,id) (((id)<<5) | (prec))
|
||||||
#define PREC(op) ((op) & 0x1F)
|
#define ID_SHIFT 5
|
||||||
|
#define PREC(op) ((op) & 0x1f)
|
||||||
|
|
||||||
#define PREC_LPAREN 0
|
#define PREC_LPAREN 0
|
||||||
#define TOK_LPAREN tok_decl(0,0)
|
#define TOK_LPAREN tok_decl(0,0)
|
||||||
@ -146,14 +147,16 @@ typedef unsigned char operator;
|
|||||||
#define TOK_AND_ASSIGN tok_decl(2,1)
|
#define TOK_AND_ASSIGN tok_decl(2,1)
|
||||||
#define TOK_OR_ASSIGN tok_decl(2,2)
|
#define TOK_OR_ASSIGN tok_decl(2,2)
|
||||||
#define TOK_XOR_ASSIGN tok_decl(2,3)
|
#define TOK_XOR_ASSIGN tok_decl(2,3)
|
||||||
#define TOK_PLUS_ASSIGN tok_decl(2,4)
|
#define TOK_ADD_ASSIGN tok_decl(2,4)
|
||||||
#define TOK_MINUS_ASSIGN tok_decl(2,5)
|
#define TOK_SUB_ASSIGN tok_decl(2,5)
|
||||||
#define TOK_LSHIFT_ASSIGN tok_decl(2,6)
|
#define TOK_LSHIFT_ASSIGN tok_decl(2,6)
|
||||||
#define TOK_RSHIFT_ASSIGN tok_decl(2,7)
|
#define TOK_RSHIFT_ASSIGN tok_decl(2,7)
|
||||||
|
|
||||||
#define PREC_ASSIGN2 3
|
#define PREC_ASSIGN2 3
|
||||||
#define TOK_MUL_ASSIGN tok_decl(3,0)
|
#define TOK_MUL_ASSIGN tok_decl(3,0)
|
||||||
#define TOK_DIV_ASSIGN tok_decl(3,1)
|
/* "/" and "/=" ops have the same id bits */
|
||||||
|
#define DIV_ID1 1
|
||||||
|
#define TOK_DIV_ASSIGN tok_decl(3,DIV_ID1)
|
||||||
#define TOK_REM_ASSIGN tok_decl(3,2)
|
#define TOK_REM_ASSIGN tok_decl(3,2)
|
||||||
|
|
||||||
#define fix_assignment_prec(prec) do { prec -= (prec == 3); } while (0)
|
#define fix_assignment_prec(prec) do { prec -= (prec == 3); } while (0)
|
||||||
@ -198,7 +201,7 @@ typedef unsigned char operator;
|
|||||||
#define TOK_SUB tok_decl(13,1)
|
#define TOK_SUB tok_decl(13,1)
|
||||||
|
|
||||||
#define TOK_MUL tok_decl(14,0)
|
#define TOK_MUL tok_decl(14,0)
|
||||||
#define TOK_DIV tok_decl(14,1)
|
#define TOK_DIV tok_decl(14,DIV_ID1)
|
||||||
#define TOK_REM tok_decl(14,2)
|
#define TOK_REM tok_decl(14,2)
|
||||||
|
|
||||||
/* Exponent is right associative */
|
/* Exponent is right associative */
|
||||||
@ -408,9 +411,9 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
|
|||||||
rez = (rez <= right_side_val);
|
rez = (rez <= right_side_val);
|
||||||
else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
|
else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
|
||||||
rez *= right_side_val;
|
rez *= right_side_val;
|
||||||
else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN)
|
else if (op == TOK_ADD || op == TOK_ADD_ASSIGN)
|
||||||
rez += right_side_val;
|
rez += right_side_val;
|
||||||
else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN)
|
else if (op == TOK_SUB || op == TOK_SUB_ASSIGN)
|
||||||
rez -= right_side_val;
|
rez -= right_side_val;
|
||||||
else if (op == TOK_ASSIGN || op == TOK_COMMA)
|
else if (op == TOK_ASSIGN || op == TOK_COMMA)
|
||||||
rez = right_side_val;
|
rez = right_side_val;
|
||||||
@ -439,11 +442,11 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
|
|||||||
* Make sure to at least not SEGV here:
|
* Make sure to at least not SEGV here:
|
||||||
*/
|
*/
|
||||||
if (right_side_val == -1
|
if (right_side_val == -1
|
||||||
&& rez << 1 == 0 /* MAX_NEGATIVE_INT or 0 */
|
&& (rez << 1) == 0 /* MAX_NEGATIVE_INT or 0 */
|
||||||
) {
|
) {
|
||||||
right_side_val = 1;
|
right_side_val = 1;
|
||||||
}
|
}
|
||||||
if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
|
if (op & (DIV_ID1 << ID_SHIFT)) /* DIV or DIV_ASSIGN? */
|
||||||
rez /= right_side_val;
|
rez /= right_side_val;
|
||||||
else
|
else
|
||||||
rez %= right_side_val;
|
rez %= right_side_val;
|
||||||
@ -505,8 +508,8 @@ static const char op_tokens[] ALIGN1 = {
|
|||||||
'*','=', 0, TOK_MUL_ASSIGN,
|
'*','=', 0, TOK_MUL_ASSIGN,
|
||||||
'/','=', 0, TOK_DIV_ASSIGN,
|
'/','=', 0, TOK_DIV_ASSIGN,
|
||||||
'%','=', 0, TOK_REM_ASSIGN,
|
'%','=', 0, TOK_REM_ASSIGN,
|
||||||
'+','=', 0, TOK_PLUS_ASSIGN,
|
'+','=', 0, TOK_ADD_ASSIGN,
|
||||||
'-','=', 0, TOK_MINUS_ASSIGN,
|
'-','=', 0, TOK_SUB_ASSIGN,
|
||||||
'-','-', 0, TOK_POST_DEC,
|
'-','-', 0, TOK_POST_DEC,
|
||||||
'^','=', 0, TOK_XOR_ASSIGN,
|
'^','=', 0, TOK_XOR_ASSIGN,
|
||||||
'+','+', 0, TOK_POST_INC,
|
'+','+', 0, TOK_POST_INC,
|
||||||
@ -542,12 +545,15 @@ static arith_t parse_with_base(const char *nptr, char **endptr, unsigned base)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned digit = (unsigned)*nptr - '0';
|
unsigned digit = (unsigned)*nptr - '0';
|
||||||
if (digit >= 10 /* not 0..9 */
|
if (digit >= 10 /* not 0..9 */
|
||||||
&& digit <= 'z' - '0' /* needed to reject e.g. $((64#~)) */
|
&& digit <= 'z' - '0' /* reject e.g. $((64#~)) */
|
||||||
) {
|
) {
|
||||||
/* in bases up to 36, case does not matter for a-z */
|
/* current char is one of :;<=>?@A..Z[\]^_`a..z */
|
||||||
|
|
||||||
|
/* in bases up to 36, case does not matter for a-z,
|
||||||
|
* map A..Z and a..z to 10..35: */
|
||||||
digit = (unsigned)(*nptr | 0x20) - ('a' - 10);
|
digit = (unsigned)(*nptr | 0x20) - ('a' - 10);
|
||||||
if (base > 36 && *nptr <= '_') {
|
if (base > 36 && *nptr <= '_') {
|
||||||
/* otherwise, A-Z,@,_ are 36-61,62,63 */
|
/* base > 36: A-Z,@,_ are 36-61,62,63 */
|
||||||
if (*nptr == '_')
|
if (*nptr == '_')
|
||||||
digit = 63;
|
digit = 63;
|
||||||
else if (*nptr == '@')
|
else if (*nptr == '@')
|
||||||
@ -558,8 +564,8 @@ static arith_t parse_with_base(const char *nptr, char **endptr, unsigned base)
|
|||||||
break; /* error: one of [\]^ */
|
break; /* error: one of [\]^ */
|
||||||
}
|
}
|
||||||
//bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit);
|
//bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit);
|
||||||
//if (digit < 10) - example where we need this?
|
if (digit < 10) /* reject e.g. $((36#@)) */
|
||||||
// break;
|
break;
|
||||||
}
|
}
|
||||||
if (digit >= base)
|
if (digit >= base)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user