Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: tools/gn/setup.cc

Issue 988563002: Add an whitelist for calling GN's exec_script. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/setup.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/setup.h" 5 #include "tools/gn/setup.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <sstream> 10 #include <sstream>
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 "\n" 61 "\n"
62 " check_targets [optional]\n" 62 " check_targets [optional]\n"
63 " A list of labels and label patterns that should be checked when\n" 63 " A list of labels and label patterns that should be checked when\n"
64 " running \"gn check\" or \"gn gen --check\". If unspecified, all\n" 64 " running \"gn check\" or \"gn gen --check\". If unspecified, all\n"
65 " targets will be checked. If it is the empty list, no targets will\n" 65 " targets will be checked. If it is the empty list, no targets will\n"
66 " be checked.\n" 66 " be checked.\n"
67 "\n" 67 "\n"
68 " The format of this list is identical to that of \"visibility\"\n" 68 " The format of this list is identical to that of \"visibility\"\n"
69 " so see \"gn help visibility\" for examples.\n" 69 " so see \"gn help visibility\" for examples.\n"
70 "\n" 70 "\n"
71 " exec_script_whitelist [optional]\n"
72 " A list of .gn/.gni files (not labels) that have permission to call\n"
73 " the exec_script function. If this list is defined, calls to\n"
74 " exec_script will be checked against this list and GN will fail if\n"
75 " the current file isn't in the list.\n"
76 "\n"
77 " This is to allow the use of exec_script to be restricted since\n"
78 " is easy to use inappropriately. Wildcards are not supported.\n"
79 " Files in the secondary_source tree (if defined) should be\n"
80 " referenced by ignoring the secondary tree and naming them as if\n"
81 " they are in the main tree.\n"
82 "\n"
83 " If unspecified, the ability to call exec_script is unrestricted.\n"
84 "\n"
85 " Example:\n"
86 " exec_script_whitelist = [\n"
87 " \"//base/BUILD.gn\",\n"
88 " \"//build/my_config.gni\",\n"
89 " ]\n"
90 "\n"
71 " root [optional]\n" 91 " root [optional]\n"
72 " Label of the root build target. The GN build will start by loading\n" 92 " Label of the root build target. The GN build will start by loading\n"
73 " the build file containing this target name. This defaults to\n" 93 " the build file containing this target name. This defaults to\n"
74 " \"//:\" which will cause the file //BUILD.gn to be loaded.\n" 94 " \"//:\" which will cause the file //BUILD.gn to be loaded.\n"
75 "\n" 95 "\n"
76 " secondary_source [optional]\n" 96 " secondary_source [optional]\n"
77 " Label of an alternate directory tree to find input files. When\n" 97 " Label of an alternate directory tree to find input files. When\n"
78 " searching for a BUILD.gn file (or the build config file discussed\n" 98 " searching for a BUILD.gn file (or the build config file discussed\n"
79 " above), the file will first be looked for in the source root.\n" 99 " above), the file will first be looked for in the source root.\n"
80 " If it's not found, the secondary source root will be checked\n" 100 " If it's not found, the secondary source root will be checked\n"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 main_loop->PostTask(FROM_HERE, base::Bind(&Builder::ItemDefined, builder, 143 main_loop->PostTask(FROM_HERE, base::Bind(&Builder::ItemDefined, builder,
124 base::Passed(&item))); 144 base::Passed(&item)));
125 } 145 }
126 146
127 void DecrementWorkCount() { 147 void DecrementWorkCount() {
128 g_scheduler->DecrementWorkCount(); 148 g_scheduler->DecrementWorkCount();
129 } 149 }
130 150
131 } // namespace 151 } // namespace
132 152
133 // CommonSetup ----------------------------------------------------------------- 153 const char Setup::kBuildArgFileName[] = "args.gn";
134 154
135 const char CommonSetup::kBuildArgFileName[] = "args.gn"; 155 Setup::Setup()
136
137 CommonSetup::CommonSetup()
138 : build_settings_(), 156 : build_settings_(),
139 loader_(new LoaderImpl(&build_settings_)), 157 loader_(new LoaderImpl(&build_settings_)),
140 builder_(new Builder(loader_.get())), 158 builder_(new Builder(loader_.get())),
141 root_build_file_("//BUILD.gn"), 159 root_build_file_("//BUILD.gn"),
142 check_for_bad_items_(true), 160 check_for_bad_items_(true),
143 check_for_unused_overrides_(true), 161 check_for_unused_overrides_(true),
144 check_public_headers_(false) { 162 check_public_headers_(false),
145 loader_->set_complete_callback(base::Bind(&DecrementWorkCount));
146 }
147
148 CommonSetup::CommonSetup(const CommonSetup& other)
149 : build_settings_(other.build_settings_),
150 loader_(new LoaderImpl(&build_settings_)),
151 builder_(new Builder(loader_.get())),
152 root_build_file_(other.root_build_file_),
153 check_for_bad_items_(other.check_for_bad_items_),
154 check_for_unused_overrides_(other.check_for_unused_overrides_),
155 check_public_headers_(other.check_public_headers_) {
156 loader_->set_complete_callback(base::Bind(&DecrementWorkCount));
157 }
158
159 CommonSetup::~CommonSetup() {
160 }
161
162 void CommonSetup::RunPreMessageLoop() {
163 // Load the root build file.
164 loader_->Load(root_build_file_, LocationRange(), Label());
165
166 // Will be decremented with the loader is drained.
167 g_scheduler->IncrementWorkCount();
168 }
169
170 bool CommonSetup::RunPostMessageLoop() {
171 Err err;
172 if (check_for_bad_items_) {
173 if (!builder_->CheckForBadItems(&err)) {
174 err.PrintToStdout();
175 return false;
176 }
177 }
178
179 if (check_for_unused_overrides_) {
180 if (!build_settings_.build_args().VerifyAllOverridesUsed(&err)) {
181 // TODO(brettw) implement a system of warnings. Until we have a better
182 // system, print the error but don't return failure.
183 err.PrintToStdout();
184 return true;
185 }
186 }
187
188 if (check_public_headers_) {
189 std::vector<const Target*> all_targets = builder_->GetAllResolvedTargets();
190 std::vector<const Target*> to_check;
191 if (check_patterns()) {
192 commands::FilterTargetsByPatterns(all_targets, *check_patterns(),
193 &to_check);
194 } else {
195 to_check = all_targets;
196 }
197
198 if (!commands::CheckPublicHeaders(&build_settings_, all_targets,
199 to_check, false)) {
200 return false;
201 }
202 }
203
204 // Write out tracing and timing if requested.
205 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
206 if (cmdline->HasSwitch(switches::kTime))
207 PrintLongHelp(SummarizeTraces());
208 if (cmdline->HasSwitch(switches::kTracelog))
209 SaveTraces(cmdline->GetSwitchValuePath(switches::kTracelog));
210
211 return true;
212 }
213
214 // Setup -----------------------------------------------------------------------
215
216 Setup::Setup()
217 : CommonSetup(),
218 empty_settings_(&empty_build_settings_, std::string()), 163 empty_settings_(&empty_build_settings_, std::string()),
219 dotfile_scope_(&empty_settings_), 164 dotfile_scope_(&empty_settings_),
220 fill_arguments_(true) { 165 fill_arguments_(true) {
221 empty_settings_.set_toolchain_label(Label()); 166 empty_settings_.set_toolchain_label(Label());
222 build_settings_.set_item_defined_callback( 167 build_settings_.set_item_defined_callback(
223 base::Bind(&ItemDefinedCallback, scheduler_.main_loop(), builder_)); 168 base::Bind(&ItemDefinedCallback, scheduler_.main_loop(), builder_));
224 169
170 loader_->set_complete_callback(base::Bind(&DecrementWorkCount));
225 // The scheduler's main loop wasn't created when the Loader was created, so 171 // The scheduler's main loop wasn't created when the Loader was created, so
226 // we need to set it now. 172 // we need to set it now.
227 loader_->set_main_loop(scheduler_.main_loop()); 173 loader_->set_main_loop(scheduler_.main_loop());
228 } 174 }
229 175
230 Setup::~Setup() { 176 Setup::~Setup() {
231 } 177 }
232 178
233 bool Setup::DoSetup(const std::string& build_dir, bool force_create) { 179 bool Setup::DoSetup(const std::string& build_dir, bool force_create) {
234 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); 180 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 return true; 213 return true;
268 } 214 }
269 215
270 bool Setup::Run() { 216 bool Setup::Run() {
271 RunPreMessageLoop(); 217 RunPreMessageLoop();
272 if (!scheduler_.Run()) 218 if (!scheduler_.Run())
273 return false; 219 return false;
274 return RunPostMessageLoop(); 220 return RunPostMessageLoop();
275 } 221 }
276 222
277 Scheduler* Setup::GetScheduler() {
278 return &scheduler_;
279 }
280
281 SourceFile Setup::GetBuildArgFile() const { 223 SourceFile Setup::GetBuildArgFile() const {
282 return SourceFile(build_settings_.build_dir().value() + kBuildArgFileName); 224 return SourceFile(build_settings_.build_dir().value() + kBuildArgFileName);
283 } 225 }
284 226
227 void Setup::RunPreMessageLoop() {
228 // Load the root build file.
229 loader_->Load(root_build_file_, LocationRange(), Label());
230
231 // Will be decremented with the loader is drained.
232 g_scheduler->IncrementWorkCount();
233 }
234
235 bool Setup::RunPostMessageLoop() {
236 Err err;
237 if (check_for_bad_items_) {
238 if (!builder_->CheckForBadItems(&err)) {
239 err.PrintToStdout();
240 return false;
241 }
242 }
243
244 if (check_for_unused_overrides_) {
245 if (!build_settings_.build_args().VerifyAllOverridesUsed(&err)) {
246 // TODO(brettw) implement a system of warnings. Until we have a better
247 // system, print the error but don't return failure.
248 err.PrintToStdout();
249 return true;
250 }
251 }
252
253 if (check_public_headers_) {
254 std::vector<const Target*> all_targets = builder_->GetAllResolvedTargets();
255 std::vector<const Target*> to_check;
256 if (check_patterns()) {
257 commands::FilterTargetsByPatterns(all_targets, *check_patterns(),
258 &to_check);
259 } else {
260 to_check = all_targets;
261 }
262
263 if (!commands::CheckPublicHeaders(&build_settings_, all_targets,
264 to_check, false)) {
265 return false;
266 }
267 }
268
269 // Write out tracing and timing if requested.
270 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
271 if (cmdline->HasSwitch(switches::kTime))
272 PrintLongHelp(SummarizeTraces());
273 if (cmdline->HasSwitch(switches::kTracelog))
274 SaveTraces(cmdline->GetSwitchValuePath(switches::kTracelog));
275
276 return true;
277 }
278
285 bool Setup::FillArguments(const base::CommandLine& cmdline) { 279 bool Setup::FillArguments(const base::CommandLine& cmdline) {
286 // Use the args on the command line if specified, and save them. Do this even 280 // Use the args on the command line if specified, and save them. Do this even
287 // if the list is empty (this means clear any defaults). 281 // if the list is empty (this means clear any defaults).
288 if (cmdline.HasSwitch(switches::kArgs)) { 282 if (cmdline.HasSwitch(switches::kArgs)) {
289 if (!FillArgsFromCommandLine(cmdline.GetSwitchValueASCII(switches::kArgs))) 283 if (!FillArgsFromCommandLine(cmdline.GetSwitchValueASCII(switches::kArgs)))
290 return false; 284 return false;
291 SaveArgsToFile(); 285 SaveArgsToFile();
292 return true; 286 return true;
293 } 287 }
294 288
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 if (err.has_error()) { 531 if (err.has_error()) {
538 err.PrintToStdout(); 532 err.PrintToStdout();
539 return false; 533 return false;
540 } 534 }
541 535
542 return true; 536 return true;
543 } 537 }
544 538
545 bool Setup::FillOtherConfig(const base::CommandLine& cmdline) { 539 bool Setup::FillOtherConfig(const base::CommandLine& cmdline) {
546 Err err; 540 Err err;
541 SourceDir current_dir("//");
547 542
548 // Secondary source path, read from the config file if present. 543 // Secondary source path, read from the config file if present.
549 // Read from the config file if present. 544 // Read from the config file if present.
550 const Value* secondary_value = 545 const Value* secondary_value =
551 dotfile_scope_.GetValue("secondary_source", true); 546 dotfile_scope_.GetValue("secondary_source", true);
552 if (secondary_value) { 547 if (secondary_value) {
553 if (!secondary_value->VerifyTypeIs(Value::STRING, &err)) { 548 if (!secondary_value->VerifyTypeIs(Value::STRING, &err)) {
554 err.PrintToStdout(); 549 err.PrintToStdout();
555 return false; 550 return false;
556 } 551 }
557 build_settings_.SetSecondarySourcePath( 552 build_settings_.SetSecondarySourcePath(
558 SourceDir(secondary_value->string_value())); 553 SourceDir(secondary_value->string_value()));
559 } 554 }
560 555
561 // Root build file. 556 // Root build file.
562 const Value* root_value = dotfile_scope_.GetValue("root", true); 557 const Value* root_value = dotfile_scope_.GetValue("root", true);
563 if (root_value) { 558 if (root_value) {
564 if (!root_value->VerifyTypeIs(Value::STRING, &err)) { 559 if (!root_value->VerifyTypeIs(Value::STRING, &err)) {
565 err.PrintToStdout(); 560 err.PrintToStdout();
566 return false; 561 return false;
567 } 562 }
568 563
569 Label root_target_label = 564 Label root_target_label =
570 Label::Resolve(SourceDir("//"), Label(), *root_value, &err); 565 Label::Resolve(current_dir, Label(), *root_value, &err);
571 if (err.has_error()) { 566 if (err.has_error()) {
572 err.PrintToStdout(); 567 err.PrintToStdout();
573 return false; 568 return false;
574 } 569 }
575 570
576 root_build_file_ = Loader::BuildFileForLabel(root_target_label); 571 root_build_file_ = Loader::BuildFileForLabel(root_target_label);
577 } 572 }
578 573
579 // Build config file. 574 // Build config file.
580 const Value* build_config_value = 575 const Value* build_config_value =
581 dotfile_scope_.GetValue("buildconfig", true); 576 dotfile_scope_.GetValue("buildconfig", true);
582 if (!build_config_value) { 577 if (!build_config_value) {
583 Err(Location(), "No build config file.", 578 Err(Location(), "No build config file.",
584 "Your .gn file (\"" + FilePathToUTF8(dotfile_name_) + "\")\n" 579 "Your .gn file (\"" + FilePathToUTF8(dotfile_name_) + "\")\n"
585 "didn't specify a \"buildconfig\" value.").PrintToStdout(); 580 "didn't specify a \"buildconfig\" value.").PrintToStdout();
586 return false; 581 return false;
587 } else if (!build_config_value->VerifyTypeIs(Value::STRING, &err)) { 582 } else if (!build_config_value->VerifyTypeIs(Value::STRING, &err)) {
588 err.PrintToStdout(); 583 err.PrintToStdout();
589 return false; 584 return false;
590 } 585 }
591 build_settings_.set_build_config_file( 586 build_settings_.set_build_config_file(
592 SourceFile(build_config_value->string_value())); 587 SourceFile(build_config_value->string_value()));
593 588
594 // Targets to check. 589 // Targets to check.
595 const Value* check_targets_value = 590 const Value* check_targets_value =
596 dotfile_scope_.GetValue("check_targets", true); 591 dotfile_scope_.GetValue("check_targets", true);
597 if (check_targets_value) { 592 if (check_targets_value) {
598 check_patterns_.reset(new std::vector<LabelPattern>);
599
600 // Fill the list of targets to check. 593 // Fill the list of targets to check.
601 if (!check_targets_value->VerifyTypeIs(Value::LIST, &err)) { 594 if (!check_targets_value->VerifyTypeIs(Value::LIST, &err)) {
602 err.PrintToStdout(); 595 err.PrintToStdout();
603 return false; 596 return false;
604 } 597 }
605 SourceDir current_dir("//"); 598
599 check_patterns_.reset(new std::vector<LabelPattern>);
606 for (const auto& item : check_targets_value->list_value()) { 600 for (const auto& item : check_targets_value->list_value()) {
607 check_patterns_->push_back( 601 check_patterns_->push_back(
608 LabelPattern::GetPattern(current_dir, item, &err)); 602 LabelPattern::GetPattern(current_dir, item, &err));
609 if (err.has_error()) { 603 if (err.has_error()) {
610 err.PrintToStdout(); 604 err.PrintToStdout();
611 return false; 605 return false;
612 } 606 }
613 } 607 }
614 } 608 }
615 609
610 // Fill exec_script_whitelist.
611 const Value* exec_script_whitelist_value =
612 dotfile_scope_.GetValue("exec_script_whitelist", true);
613 if (exec_script_whitelist_value) {
614 // Fill the list of targets to check.
615 if (!exec_script_whitelist_value->VerifyTypeIs(Value::LIST, &err)) {
616 err.PrintToStdout();
617 return false;
618 }
619 scoped_ptr<std::set<SourceFile>> whitelist(new std::set<SourceFile>);
620 for (const auto& item : exec_script_whitelist_value->list_value()) {
621 if (!item.VerifyTypeIs(Value::STRING, &err)) {
622 err.PrintToStdout();
623 return false;
624 }
625 whitelist->insert(current_dir.ResolveRelativeFile(item.string_value()));
626 }
627 build_settings_.set_exec_script_whitelist(whitelist.Pass());
628 }
629
616 return true; 630 return true;
617 } 631 }
618
619 // DependentSetup --------------------------------------------------------------
620
621 DependentSetup::DependentSetup(Setup* derive_from)
622 : CommonSetup(*derive_from),
623 scheduler_(derive_from->GetScheduler()) {
624 build_settings_.set_item_defined_callback(
625 base::Bind(&ItemDefinedCallback, scheduler_->main_loop(), builder_));
626 }
627
628 DependentSetup::DependentSetup(DependentSetup* derive_from)
629 : CommonSetup(*derive_from),
630 scheduler_(derive_from->GetScheduler()) {
631 build_settings_.set_item_defined_callback(
632 base::Bind(&ItemDefinedCallback, scheduler_->main_loop(), builder_));
633 }
634
635 DependentSetup::~DependentSetup() {
636 }
637
638 Scheduler* DependentSetup::GetScheduler() {
639 return scheduler_;
640 }
641
642 void DependentSetup::RunPreMessageLoop() {
643 CommonSetup::RunPreMessageLoop();
644 }
645
646 bool DependentSetup::RunPostMessageLoop() {
647 return CommonSetup::RunPostMessageLoop();
648 }
649
OLDNEW
« no previous file with comments | « tools/gn/setup.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698