OLD | NEW |
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 "base/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/files/file_util.h" | 6 #include "base/files/file_util.h" |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "tools/gn/err.h" | 12 #include "tools/gn/err.h" |
13 #include "tools/gn/exec_process.h" | 13 #include "tools/gn/exec_process.h" |
14 #include "tools/gn/filesystem_utils.h" | 14 #include "tools/gn/filesystem_utils.h" |
15 #include "tools/gn/functions.h" | 15 #include "tools/gn/functions.h" |
16 #include "tools/gn/input_conversion.h" | 16 #include "tools/gn/input_conversion.h" |
17 #include "tools/gn/input_file.h" | 17 #include "tools/gn/input_file.h" |
18 #include "tools/gn/parse_tree.h" | 18 #include "tools/gn/parse_tree.h" |
19 #include "tools/gn/scheduler.h" | 19 #include "tools/gn/scheduler.h" |
20 #include "tools/gn/trace.h" | 20 #include "tools/gn/trace.h" |
21 #include "tools/gn/value.h" | 21 #include "tools/gn/value.h" |
22 | 22 |
23 namespace functions { | 23 namespace functions { |
24 | 24 |
| 25 namespace { |
| 26 |
| 27 bool CheckExecScriptPermissions(const BuildSettings* build_settings, |
| 28 const FunctionCallNode* function, |
| 29 Err* err) { |
| 30 const std::set<SourceFile>* whitelist = |
| 31 build_settings->exec_script_whitelist(); |
| 32 if (!whitelist) |
| 33 return true; // No whitelist specified, don't check. |
| 34 |
| 35 LocationRange function_range = function->GetRange(); |
| 36 if (!function_range.begin().file()) |
| 37 return true; // No file, might be some internal thing, implicitly pass. |
| 38 |
| 39 if (whitelist->find(function_range.begin().file()->name()) != |
| 40 whitelist->end()) |
| 41 return true; // Whitelisted, this is OK. |
| 42 |
| 43 // Disallowed case. |
| 44 *err = Err(function, "Disallowed exec_script call.", |
| 45 "The use of exec_script use is restricted in this build. exec_script\n" |
| 46 "is discouraged because it can slow down the GN run and is easily\n" |
| 47 "abused.\n" |
| 48 "\n" |
| 49 "Generally nontrivial work should be done as build steps rather than\n" |
| 50 "when GN is run. For example, if you need to compute a nontrivial\n" |
| 51 "preprocessor define, it will be better to have an action target\n" |
| 52 "generate a header containing the define rather than blocking the GN\n" |
| 53 "run to compute the value.\n" |
| 54 "\n" |
| 55 "The allowed callers of exec_script is maintained in the \"//.gn\" file\n" |
| 56 "if you need to modify the whitelist."); |
| 57 return false; |
| 58 } |
| 59 |
| 60 } // namespace |
| 61 |
25 const char kExecScript[] = "exec_script"; | 62 const char kExecScript[] = "exec_script"; |
26 const char kExecScript_HelpShort[] = | 63 const char kExecScript_HelpShort[] = |
27 "exec_script: Synchronously run a script and return the output."; | 64 "exec_script: Synchronously run a script and return the output."; |
28 const char kExecScript_Help[] = | 65 const char kExecScript_Help[] = |
29 "exec_script: Synchronously run a script and return the output.\n" | 66 "exec_script: Synchronously run a script and return the output.\n" |
30 "\n" | 67 "\n" |
31 " exec_script(filename,\n" | 68 " exec_script(filename,\n" |
32 " arguments = [],\n" | 69 " arguments = [],\n" |
33 " input_conversion = \"\",\n" | 70 " input_conversion = \"\",\n" |
34 " file_dependencies = [])\n" | 71 " file_dependencies = [])\n" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 if (args.size() < 1 || args.size() > 4) { | 122 if (args.size() < 1 || args.size() > 4) { |
86 *err = Err(function->function(), "Wrong number of arguments to exec_script", | 123 *err = Err(function->function(), "Wrong number of arguments to exec_script", |
87 "I expected between one and four arguments."); | 124 "I expected between one and four arguments."); |
88 return Value(); | 125 return Value(); |
89 } | 126 } |
90 | 127 |
91 const Settings* settings = scope->settings(); | 128 const Settings* settings = scope->settings(); |
92 const BuildSettings* build_settings = settings->build_settings(); | 129 const BuildSettings* build_settings = settings->build_settings(); |
93 const SourceDir& cur_dir = scope->GetSourceDir(); | 130 const SourceDir& cur_dir = scope->GetSourceDir(); |
94 | 131 |
| 132 if (!CheckExecScriptPermissions(build_settings, function, err)) |
| 133 return Value(); |
| 134 |
95 // Find the python script to run. | 135 // Find the python script to run. |
96 if (!args[0].VerifyTypeIs(Value::STRING, err)) | 136 if (!args[0].VerifyTypeIs(Value::STRING, err)) |
97 return Value(); | 137 return Value(); |
98 SourceFile script_source = | 138 SourceFile script_source = |
99 cur_dir.ResolveRelativeFile(args[0].string_value(), | 139 cur_dir.ResolveRelativeFile(args[0].string_value(), |
100 scope->settings()->build_settings()->root_path_utf8()); | 140 scope->settings()->build_settings()->root_path_utf8()); |
101 base::FilePath script_path = build_settings->GetFullPath(script_source); | 141 base::FilePath script_path = build_settings->GetFullPath(script_source); |
102 if (!build_settings->secondary_source_path().empty() && | 142 if (!build_settings->secondary_source_path().empty() && |
103 !base::PathExists(script_path)) { | 143 !base::PathExists(script_path)) { |
104 // Fall back to secondary source root when the file doesn't exist. | 144 // Fall back to secondary source root when the file doesn't exist. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 msg); | 240 msg); |
201 return Value(); | 241 return Value(); |
202 } | 242 } |
203 | 243 |
204 // Default to None value for the input conversion if unspecified. | 244 // Default to None value for the input conversion if unspecified. |
205 return ConvertInputToValue(scope->settings(), output, function, | 245 return ConvertInputToValue(scope->settings(), output, function, |
206 args.size() >= 3 ? args[2] : Value(), err); | 246 args.size() >= 3 ? args[2] : Value(), err); |
207 } | 247 } |
208 | 248 |
209 } // namespace functions | 249 } // namespace functions |
OLD | NEW |