aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2024-07-09 03:04:26 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2024-07-09 03:04:26 +0200
commit49340d93edc778b193cb40b59cf94dbe38650013 (patch)
tree779fc3ab4c2965c335cf9d339942e7e56787da27
parentfb08d43d44d1fea1f741fafb9aa7e1958a5f69aa (diff)
downloadbusybox-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.c20
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
925static void fmt_num(const char *format, double n) 926static 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
944static xhash *iamarray(var *a) 946static 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 }