Fix a crash on invalid on `not_needed(scope)` without a 2nd argument.
While here, also fix an accepts-invalid where GN would accept
and silently ignore a third argument if the first argument was
a string or a list.
Bug: gn:38
Change-Id: I552585a9467284095ea583ee0fce01e4dad09c0c
Reviewed-on: https://gn-review.googlesource.com/c/3600
Reviewed-by: Petr Hosek <phosek@google.com>
Commit-Queue: Petr Hosek <phosek@google.com>
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
index 4c423cb..6abe758 100644
--- a/tools/gn/functions.cc
+++ b/tools/gn/functions.cc
@@ -700,6 +700,12 @@
// Extract the source scope if different from current one.
Scope* source = scope;
if (value->type() == Value::SCOPE) {
+ if (args_cur == args_vector.end()) {
+ *err = Err(
+ function, "Wrong number of arguments.",
+ "The first argument is a scope, expecting two or three arguments.");
+ return Value();
+ }
// Copy the scope value if it will be overridden.
if (value == &result_value) {
scope_value = Value(nullptr, value->scope_value()->MakeClosure());
@@ -712,6 +718,11 @@
return Value();
value = &result_value;
args_cur++;
+ } else if (args_vector.size() > 2) {
+ *err = Err(
+ function, "Wrong number of arguments.",
+ "The first argument is not a scope, expecting one or two arguments.");
+ return Value();
}
// Extract the exclusion list if defined.
diff --git a/tools/gn/functions_target_unittest.cc b/tools/gn/functions_target_unittest.cc
index 3edd77d..642b8ce 100644
--- a/tools/gn/functions_target_unittest.cc
+++ b/tools/gn/functions_target_unittest.cc
@@ -89,6 +89,37 @@
ASSERT_TRUE(err.has_error());
EXPECT_EQ("Not supported with a variable list.", err.message());
+ TestParseInput argcount_error_input(
+ "source_set(\"foo\") {\n"
+ " not_needed()\n"
+ "}\n");
+ ASSERT_FALSE(argcount_error_input.has_error());
+ err = Err();
+ argcount_error_input.parsed()->Execute(setup.scope(), &err);
+ ASSERT_TRUE(err.has_error());
+ EXPECT_EQ("Wrong number of arguments.", err.message());
+
+ TestParseInput scope_error_input(
+ "source_set(\"foo\") {\n"
+ " a = {x = 1 y = 2}\n"
+ " not_needed(a)\n"
+ "}\n");
+ ASSERT_FALSE(scope_error_input.has_error());
+ err = Err();
+ scope_error_input.parsed()->Execute(setup.scope(), &err);
+ ASSERT_TRUE(err.has_error());
+ EXPECT_EQ("Wrong number of arguments.", err.message());
+
+ TestParseInput string_error_input(
+ "source_set(\"foo\") {\n"
+ " not_needed(\"*\", {}, \"*\")\n"
+ "}\n");
+ ASSERT_FALSE(string_error_input.has_error());
+ err = Err();
+ string_error_input.parsed()->Execute(setup.scope(), &err);
+ ASSERT_TRUE(err.has_error());
+ EXPECT_EQ("Wrong number of arguments.", err.message());
+
TestParseInput template_input(
R"(# Test that not_needed() propagates through templates correctly;
# no error should arise from not using "a".