commit 5043282
shrub
·
2026-04-28 10:36:16 +0000 UTC
parent ce959b5
functions/foreach: fix temp var restore and interned name ownership issue
1 files changed,
+9,
-8
+9,
-8
1@@ -1175,7 +1175,8 @@ fnforeach(struct EvalCtx *ctx, const char *args)
2 {
3 char **raw;
4 char *name_raw, *name, *list, *out;
5- char *saved_name, *saved_val;
6+ char *saved_val;
7+ const char *iname;
8 struct Var *saved;
9 size_t argc, i, j, len, cap;
10 int saved_simple;
11@@ -1193,17 +1194,16 @@ fnforeach(struct EvalCtx *ctx, const char *args)
12 name = trimspacesdup(name_raw);
13 free(name_raw);
14 list = expandstr(ctx, raw[1]);
15+ iname = intern(name);
16
17 saved = findvar(ctx->env, name);
18 had_saved = saved != 0;
19 if (had_saved) {
20- saved_name = xstrdup(saved->name);
21 saved_val = xstrdup(saved->val);
22 saved_simple = saved->simple;
23 saved_origin = saved->origin;
24 saved_exported = saved->exported;
25 } else {
26- saved_name = 0;
27 saved_val = 0;
28 saved_simple = 0;
29 saved_origin = ORIGIN_FILE;
30@@ -1248,14 +1248,16 @@ fnforeach(struct EvalCtx *ctx, const char *args)
31 }
32
33 if (had_saved) {
34- envsetvar(ctx->env, saved_name, saved_val, saved_simple, saved_origin, saved_exported);
35- free(saved_name);
36+ free(saved->val);
37+ saved->val = saved_val;
38+ saved->simple = saved_simple;
39+ saved->origin = saved_origin;
40+ saved->exported = saved_exported;
41 } else {
42 size_t k;
43
44 for (k = 0; k < ctx->env->n; k++) {
45- if (strcmp(ctx->env->v[k].name, name) == 0) {
46- free(ctx->env->v[k].name);
47+ if (ctx->env->v[k].name == iname) {
48 free(ctx->env->v[k].val);
49 memmove(&ctx->env->v[k], &ctx->env->v[k + 1],
50 (ctx->env->n - k - 1) * sizeof(ctx->env->v[0]));
51@@ -1265,7 +1267,6 @@ fnforeach(struct EvalCtx *ctx, const char *args)
52 }
53 }
54
55- free(saved_val);
56 free(list);
57 free(name);
58 freeargsraw(raw, argc);