aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2018-05-28 05:21:55 -0400
committerMasahiro Yamada <yamada.masahiro@socionext.com>2018-05-28 14:31:19 -0400
commit915f64901eb3f1e4e126f58c0d2f82f5ec1d1223 (patch)
treeff55db36fc7f90bcc51af0070bc65ac947737c4d
parenta702a6176e2fea9ae366a7345247eb886e4cc730 (diff)
kconfig: error out if a recursive variable references itself
When using a recursively expanded variable, it is a common mistake to make circular reference. For example, Make terminates the following code: X = $(X) Y := $(X) Let's detect the circular expansion in Kconfig, too. On the other hand, a function that recurses itself is a commonly-used programming technique. So, Make does not check recursion in the reference with 'call'. For example, the following code continues running eternally: X = $(call X) Y := $(X) Kconfig allows circular expansion if one or more arguments are given, but terminates when the same function is recursively invoked 1000 times, assuming it is a programming mistake. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
-rw-r--r--scripts/kconfig/preprocess.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index 0574039238c6..65da87fce907 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -229,6 +229,7 @@ struct variable {
229 char *name; 229 char *name;
230 char *value; 230 char *value;
231 enum variable_flavor flavor; 231 enum variable_flavor flavor;
232 int exp_count;
232 struct list_head node; 233 struct list_head node;
233}; 234};
234 235
@@ -253,11 +254,22 @@ static char *variable_expand(const char *name, int argc, char *argv[])
253 if (!v) 254 if (!v)
254 return NULL; 255 return NULL;
255 256
257 if (argc == 0 && v->exp_count)
258 pperror("Recursive variable '%s' references itself (eventually)",
259 name);
260
261 if (v->exp_count > 1000)
262 pperror("Too deep recursive expansion");
263
264 v->exp_count++;
265
256 if (v->flavor == VAR_RECURSIVE) 266 if (v->flavor == VAR_RECURSIVE)
257 res = expand_string_with_args(v->value, argc, argv); 267 res = expand_string_with_args(v->value, argc, argv);
258 else 268 else
259 res = xstrdup(v->value); 269 res = xstrdup(v->value);
260 270
271 v->exp_count--;
272
261 return res; 273 return res;
262} 274}
263 275
@@ -284,6 +296,7 @@ void variable_add(const char *name, const char *value,
284 296
285 v = xmalloc(sizeof(*v)); 297 v = xmalloc(sizeof(*v));
286 v->name = xstrdup(name); 298 v->name = xstrdup(name);
299 v->exp_count = 0;
287 list_add_tail(&v->node, &variable_list); 300 list_add_tail(&v->node, &variable_list);
288 } 301 }
289 302