diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2024-07-09 03:04:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-07-09 03:04:26 +0200 |
commit | 49340d93edc778b193cb40b59cf94dbe38650013 (patch) | |
tree | 779fc3ab4c2965c335cf9d339942e7e56787da27 | |
parent | fb08d43d44d1fea1f741fafb9aa7e1958a5f69aa (diff) | |
download | busybox-w32-49340d93edc778b193cb40b59cf94dbe38650013.tar.gz busybox-w32-49340d93edc778b193cb40b59cf94dbe38650013.tar.bz2 busybox-w32-49340d93edc778b193cb40b59cf94dbe38650013.zip |
awk: do not infinitely recurse getvar_s() if CONVFMT is set to a numeric value
function old new delta
fmt_num 247 257 +10
evaluate 3385 3379 -6
getvar_s 111 102 -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 10/-15) Total: -5 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/editors/awk.c b/editors/awk.c index ff6d6350b..8bc214b69 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -532,6 +532,7 @@ static const char vValues[] ALIGN1 = | |||
532 | "%.6g\0" "%.6g\0" " \0" " \0" | 532 | "%.6g\0" "%.6g\0" " \0" " \0" |
533 | "\n\0" "\n\0" "\0" "\0" | 533 | "\n\0" "\n\0" "\0" "\0" |
534 | "\034\0" "\0" "\377"; | 534 | "\034\0" "\0" "\377"; |
535 | #define str_percent_dot_6g vValues | ||
535 | 536 | ||
536 | /* hash size may grow to these values */ | 537 | /* hash size may grow to these values */ |
537 | #define FIRST_PRIME 61 | 538 | #define FIRST_PRIME 61 |
@@ -922,7 +923,7 @@ static double my_strtod_or_hexoct(char **pp) | |||
922 | 923 | ||
923 | /* -------- working with variables (set/get/copy/etc) -------- */ | 924 | /* -------- working with variables (set/get/copy/etc) -------- */ |
924 | 925 | ||
925 | static void fmt_num(const char *format, double n) | 926 | static const char *fmt_num(const char *format, double n) |
926 | { | 927 | { |
927 | if (n == (long long)n) { | 928 | if (n == (long long)n) { |
928 | snprintf(g_buf, MAXVARFMT, "%lld", (long long)n); | 929 | snprintf(g_buf, MAXVARFMT, "%lld", (long long)n); |
@@ -939,6 +940,7 @@ static void fmt_num(const char *format, double n) | |||
939 | syntax_error(EMSG_INV_FMT); | 940 | syntax_error(EMSG_INV_FMT); |
940 | } | 941 | } |
941 | } | 942 | } |
943 | return g_buf; | ||
942 | } | 944 | } |
943 | 945 | ||
944 | static xhash *iamarray(var *a) | 946 | static xhash *iamarray(var *a) |
@@ -1025,8 +1027,15 @@ static const char *getvar_s(var *v) | |||
1025 | { | 1027 | { |
1026 | /* if v is numeric and has no cached string, convert it to string */ | 1028 | /* if v is numeric and has no cached string, convert it to string */ |
1027 | if ((v->type & (VF_NUMBER | VF_CACHED)) == VF_NUMBER) { | 1029 | if ((v->type & (VF_NUMBER | VF_CACHED)) == VF_NUMBER) { |
1028 | fmt_num(getvar_s(intvar[CONVFMT]), v->number); | 1030 | const char *convfmt = str_percent_dot_6g; /* "%.6g" */ |
1029 | v->string = xstrdup(g_buf); | 1031 | /* Get CONVFMT, unless we already recursed on it: |
1032 | * someone might try to cause stack overflow by setting | ||
1033 | * CONVFMT=9 (a numeric, not string, value) | ||
1034 | */ | ||
1035 | if (v != intvar[CONVFMT]) | ||
1036 | convfmt = getvar_s(intvar[CONVFMT]); | ||
1037 | /* Convert the value */ | ||
1038 | v->string = xstrdup(fmt_num(convfmt, v->number)); | ||
1030 | v->type |= VF_CACHED; | 1039 | v->type |= VF_CACHED; |
1031 | } | 1040 | } |
1032 | return (v->string == NULL) ? "" : v->string; | 1041 | return (v->string == NULL) ? "" : v->string; |
@@ -3097,9 +3106,8 @@ static var *evaluate(node *op, var *res) | |||
3097 | for (;;) { | 3106 | for (;;) { |
3098 | var *v = evaluate(nextarg(&op1), TMPVAR0); | 3107 | var *v = evaluate(nextarg(&op1), TMPVAR0); |
3099 | if (v->type & VF_NUMBER) { | 3108 | if (v->type & VF_NUMBER) { |
3100 | fmt_num(getvar_s(intvar[OFMT]), | 3109 | fputs(fmt_num(getvar_s(intvar[OFMT]), getvar_i(v)), |
3101 | getvar_i(v)); | 3110 | F); |
3102 | fputs(g_buf, F); | ||
3103 | } else { | 3111 | } else { |
3104 | fputs(getvar_s(v), F); | 3112 | fputs(getvar_s(v), F); |
3105 | } | 3113 | } |