diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 18:28:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 18:28:12 +0200 |
commit | 47d9133896f0de6b17393309193051e4bd52015e (patch) | |
tree | 48a8fc733695e253aca3bdc3acd452ddf01611ea | |
parent | 786ca197ad1305607efaccb067c19931d9e765b1 (diff) | |
download | busybox-w32-47d9133896f0de6b17393309193051e4bd52015e.tar.gz busybox-w32-47d9133896f0de6b17393309193051e4bd52015e.tar.bz2 busybox-w32-47d9133896f0de6b17393309193051e4bd52015e.zip |
awk: enforce simple builtins' argument number
function old new delta
evaluate 3215 3303 +88
.rodata 104036 104107 +71
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 159/0) Total: 159 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/editors/awk.c b/editors/awk.c index fb841687e..1925e0771 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -464,11 +464,11 @@ static const uint32_t tokeninfo[] ALIGN4 = { | |||
464 | // OC_B's are builtins with enforced minimum number of arguments (two upper bits). | 464 | // OC_B's are builtins with enforced minimum number of arguments (two upper bits). |
465 | // Highest byte bit pattern: nn s3s2s1 v3v2v1 | 465 | // Highest byte bit pattern: nn s3s2s1 v3v2v1 |
466 | // nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var | 466 | // nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var |
467 | // OC_FBLTIN's are builtins with one optional argument, | 467 | // OC_FBLTIN's are builtins with zero or one argument. |
468 | // TODO: enforce exactly one arg for: system, close, cos, sin, exp, int, log, sqrt | 468 | // |Rx| enforces that arg is present for: system, close, cos, sin, exp, int, log, sqrt. |
469 | // zero args for: rand systime | 469 | // Check for no args is present in builtins' code (not in this table): rand, systime. |
470 | // Do have one optional arg: fflush, srand, length | 470 | // Have one _optional_ arg: fflush, srand, length |
471 | #define OC_B OC_BUILTIN | 471 | #define OC_B OC_BUILTIN |
472 | #define A1 P(0x40) /*one arg*/ | 472 | #define A1 P(0x40) /*one arg*/ |
473 | #define A2 P(0x80) /*two args*/ | 473 | #define A2 P(0x80) /*two args*/ |
474 | #define A3 P(0xc0) /*three args*/ | 474 | #define A3 P(0xc0) /*three args*/ |
@@ -480,15 +480,15 @@ static const uint32_t tokeninfo[] ALIGN4 = { | |||
480 | #define _ss_vv P(0x1b) | 480 | #define _ss_vv P(0x1b) |
481 | #define _s_vv_ P(0x16) | 481 | #define _s_vv_ P(0x16) |
482 | #define ss_vv_ P(0x36) | 482 | #define ss_vv_ P(0x36) |
483 | OC_B|B_an|_vv|A2, OC_B|B_co|__v|A1, OC_B|B_ls|_vv|A2, OC_B|B_or|_vv|A2, // and compl lshift or | 483 | OC_B|B_an|_vv|A2, OC_B|B_co|__v|A1, OC_B|B_ls|_vv|A2, OC_B|B_or|_vv|A2, // and compl lshift or |
484 | OC_B|B_rs|_vv|A2, OC_B|B_xo|_vv|A2, // rshift xor | 484 | OC_B|B_rs|_vv|A2, OC_B|B_xo|_vv|A2, // rshift xor |
485 | OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|_vv|A2, // close system fflush atan2 | 485 | OC_FBLTIN|Sx|Rx|F_cl,OC_FBLTIN|Sx|Rx|F_sy,OC_FBLTIN|Sx|F_ff, OC_B|B_a2|_vv|A2, // close system fflush atan2 |
486 | OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, // cos exp int log | 486 | OC_FBLTIN|Nx|Rx|F_co,OC_FBLTIN|Nx|Rx|F_ex,OC_FBLTIN|Nx|Rx|F_in,OC_FBLTIN|Nx|Rx|F_lg,// cos exp int log |
487 | OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, // rand sin sqrt srand | 487 | OC_FBLTIN|F_rn, OC_FBLTIN|Nx|Rx|F_si,OC_FBLTIN|Nx|Rx|F_sq,OC_FBLTIN|Nx|F_sr, // rand sin sqrt srand |
488 | OC_B|B_ge|_s_vv_|A3, OC_B|B_gs|ss_vv_|A2, OC_B|B_ix|_ss_vv|A2, // gensub gsub index /*length was here*/ | 488 | OC_B|B_ge|_s_vv_|A3, OC_B|B_gs|ss_vv_|A2, OC_B|B_ix|_ss_vv|A2, // gensub gsub index /*length was here*/ |
489 | OC_B|B_ma|__s__v|A2, OC_B|B_sp|__s_vv|A2, OC_SPRINTF, OC_B|B_su|ss_vv_|A2, // match split sprintf sub | 489 | OC_B|B_ma|__s__v|A2, OC_B|B_sp|__s_vv|A2, OC_SPRINTF, OC_B|B_su|ss_vv_|A2, // match split sprintf sub |
490 | OC_B|B_ss|__svvv|A2, OC_FBLTIN|F_ti, OC_B|B_ti|__s_vv, OC_B|B_mt|__s_vv, // substr systime strftime mktime | 490 | OC_B|B_ss|__svvv|A2, OC_FBLTIN|F_ti, OC_B|B_ti|__s_vv, OC_B|B_mt|__s_vv, // substr systime strftime mktime |
491 | OC_B|B_lo|__s__v|A1, OC_B|B_up|__s__v|A1, // tolower toupper | 491 | OC_B|B_lo|__s__v|A1, OC_B|B_up|__s__v|A1, // tolower toupper |
492 | OC_FBLTIN|Sx|F_le, // length | 492 | OC_FBLTIN|Sx|F_le, // length |
493 | OC_GETLINE|SV, // getline | 493 | OC_GETLINE|SV, // getline |
494 | 0, 0, // func function | 494 | 0, 0, // func function |
@@ -2773,8 +2773,11 @@ static var *evaluate(node *op, var *res) | |||
2773 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); | 2773 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); |
2774 | 2774 | ||
2775 | /* execute inevitable things */ | 2775 | /* execute inevitable things */ |
2776 | if (opinfo & OF_RES1) | 2776 | if (opinfo & OF_RES1) { |
2777 | if ((opinfo & OF_REQUIRED) && !op1) | ||
2778 | syntax_error(EMSG_TOO_FEW_ARGS); | ||
2777 | L.v = evaluate(op1, TMPVAR0); | 2779 | L.v = evaluate(op1, TMPVAR0); |
2780 | } | ||
2778 | if (opinfo & OF_STR1) { | 2781 | if (opinfo & OF_STR1) { |
2779 | L.s = getvar_s(L.v); | 2782 | L.s = getvar_s(L.v); |
2780 | debug_printf_eval("L.s:'%s'\n", L.s); | 2783 | debug_printf_eval("L.s:'%s'\n", L.s); |
@@ -3101,12 +3104,18 @@ static var *evaluate(node *op, var *res) | |||
3101 | double R_d = R_d; /* for compiler */ | 3104 | double R_d = R_d; /* for compiler */ |
3102 | debug_printf_eval("FBLTIN\n"); | 3105 | debug_printf_eval("FBLTIN\n"); |
3103 | 3106 | ||
3107 | if (op1 && (op1->info & OPCLSMASK) == OC_COMMA) | ||
3108 | /* Simple builtins take one arg maximum */ | ||
3109 | syntax_error("Too many arguments"); | ||
3110 | |||
3104 | switch (opn) { | 3111 | switch (opn) { |
3105 | case F_in: | 3112 | case F_in: |
3106 | R_d = (long long)L_d; | 3113 | R_d = (long long)L_d; |
3107 | break; | 3114 | break; |
3108 | 3115 | ||
3109 | case F_rn: | 3116 | case F_rn: /*rand*/ |
3117 | if (op1) | ||
3118 | syntax_error("Too many arguments"); | ||
3110 | R_d = (double)rand() / (double)RAND_MAX; | 3119 | R_d = (double)rand() / (double)RAND_MAX; |
3111 | break; | 3120 | break; |
3112 | 3121 | ||
@@ -3149,7 +3158,9 @@ static var *evaluate(node *op, var *res) | |||
3149 | srand(seed); | 3158 | srand(seed); |
3150 | break; | 3159 | break; |
3151 | 3160 | ||
3152 | case F_ti: | 3161 | case F_ti: /*systime*/ |
3162 | if (op1) | ||
3163 | syntax_error("Too many arguments"); | ||
3153 | R_d = time(NULL); | 3164 | R_d = time(NULL); |
3154 | break; | 3165 | break; |
3155 | 3166 | ||