1 // Copyright (c) 2024 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gn/ohos_components_checker.h"
6
7 #include <fstream>
8 #include <functional>
9 #include <iostream>
10 #include <sys/stat.h>
11
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/values.h"
16 #include "gn/build_settings.h"
17 #include "gn/config.h"
18 #include "gn/filesystem_utils.h"
19 #include "gn/functions.h"
20 #include "gn/ohos_components.h"
21 #include "gn/parse_tree.h"
22 #include "gn/settings.h"
23 #include "gn/substitution_writer.h"
24 #include "gn/target.h"
25 #include "gn/value.h"
26
27 static const std::string SCAN_RESULT_PATH = "scan_out";
28 static const std::string WHITELIST_PATH = "component_compilation_whitelist.json";
29 static const int BASE_BINARY = 1;
30 static std::vector<std::string> all_deps_config_;
31 static std::vector<std::string> includes_over_range_;
32 static std::map<std::string, std::vector<std::string>> innerapi_public_deps_inner_;
33 static std::vector<std::string> innerapi_not_lib_;
34 static std::vector<std::string> innerapi_not_declare_;
35 static std::map<std::string, std::vector<std::string>> includes_absolute_deps_other_;
36 static std::map<std::string, std::vector<std::string>> target_absolute_deps_other_;
37 static std::map<std::string, std::vector<std::string>> import_other_;
38 static std::map<std::string, std::vector<std::string>> deps_not_lib_;
39 static std::map<std::string, std::vector<std::string>> fuzzy_match_;
40
41 OhosComponentChecker *OhosComponentChecker::instance_ = nullptr;
42
Trim(std::string & str)43 static std::string& Trim(std::string &str)
44 {
45 if (str.empty()) {
46 return str;
47 }
48 str.erase(0, str.find_first_not_of(" \t\r\n"));
49 str.erase(str.find_last_not_of(" \t\r\n") + 1);
50 return str;
51 }
52
StartWith(const std::string & str,const std::string & prefix)53 static bool StartWith(const std::string &str, const std::string &prefix)
54 {
55 return (str.rfind(prefix, 0) == 0);
56 }
57
CreateScanOutDir(const std::string & dir)58 static void CreateScanOutDir(const std::string &dir)
59 {
60 base::FilePath path(dir);
61 base::CreateDirectory(path);
62 return;
63 }
64
RemoveScanOutDir(const std::string & dir)65 static void RemoveScanOutDir(const std::string& dir)
66 {
67 if (access(dir.c_str(), F_OK) == -1) {
68 return;
69 }
70 base::FilePath path(dir);
71 base::DeleteFile(path, true);
72 return;
73 }
74
ReadBuildConfigFile(base::FilePath path,std::string & content)75 static bool ReadBuildConfigFile(base::FilePath path, std::string &content)
76 {
77 if (!base::ReadFileToString(path, &content)) {
78 return false;
79 }
80 return true;
81 }
82
LoadAllDepsConfigWhitelist(const base::Value & list)83 static void LoadAllDepsConfigWhitelist(const base::Value &list)
84 {
85 for (const base::Value &value : list.GetList()) {
86 all_deps_config_.push_back(value.GetString());
87 }
88 }
89
LoadIncludesOverRangeWhitelist(const base::Value & list)90 static void LoadIncludesOverRangeWhitelist(const base::Value &list)
91 {
92 for (const base::Value &value : list.GetList()) {
93 includes_over_range_.push_back(value.GetString());
94 }
95 }
96
LoadInnerApiPublicDepsInnerWhitelist(const base::Value & value)97 static void LoadInnerApiPublicDepsInnerWhitelist(const base::Value &value)
98 {
99 for (auto info : value.DictItems()) {
100 for (const base::Value &value_tmp : info.second.GetList()) {
101 innerapi_public_deps_inner_[info.first].push_back(value_tmp.GetString());
102 }
103 }
104 }
105
LoadInnerApiNotLibWhitelist(const base::Value & list)106 static void LoadInnerApiNotLibWhitelist(const base::Value &list)
107 {
108 for (const base::Value &value : list.GetList()) {
109 innerapi_not_lib_.push_back(value.GetString());
110 }
111 }
112
LoadInnerApiNotDeclareWhitelist(const base::Value & list)113 static void LoadInnerApiNotDeclareWhitelist(const base::Value &list)
114 {
115 for (const base::Value &value : list.GetList()) {
116 innerapi_not_declare_.push_back(value.GetString());
117 }
118 }
119
LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value & value)120 static void LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value &value)
121 {
122 for (auto info : value.DictItems()) {
123 for (const base::Value &value_tmp : info.second.GetList()) {
124 includes_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
125 }
126 }
127 }
128
LoadAbsoluteDepsOtherWhitelist(const base::Value & value)129 static void LoadAbsoluteDepsOtherWhitelist(const base::Value &value)
130 {
131 for (auto info : value.DictItems()) {
132 for (const base::Value &value_tmp : info.second.GetList()) {
133 target_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
134 }
135 }
136 }
137
LoadImportOtherWhitelist(const base::Value & value)138 static void LoadImportOtherWhitelist(const base::Value &value)
139 {
140 for (auto info : value.DictItems()) {
141 for (const base::Value &value_tmp : info.second.GetList()) {
142 import_other_[info.first].push_back(value_tmp.GetString());
143 }
144 }
145 }
146
LoadDepsNotLibWhitelist(const base::Value & value)147 static void LoadDepsNotLibWhitelist(const base::Value &value)
148 {
149 for (auto info : value.DictItems()) {
150 for (const base::Value &value_tmp : info.second.GetList()) {
151 deps_not_lib_[info.first].push_back(value_tmp.GetString());
152 }
153 }
154 }
155
LoadFuzzyMatchWhitelist(const base::Value & value)156 static void LoadFuzzyMatchWhitelist(const base::Value &value)
157 {
158 for (auto info : value.DictItems()) {
159 for (const base::Value &value_tmp : info.second.GetList()) {
160 fuzzy_match_[info.first].push_back(value_tmp.GetString());
161 }
162 }
163 }
164
165 static std::map<std::string, std::function<void(const base::Value &value)>> whitelist_map_ = {
166 { "all_dependent_configs", LoadAllDepsConfigWhitelist },
167 { "includes_over_range", LoadIncludesOverRangeWhitelist },
168 { "innerapi_not_lib", LoadInnerApiNotLibWhitelist },
169 { "innerapi_not_declare", LoadInnerApiNotDeclareWhitelist },
170 { "innerapi_public_deps_inner", LoadInnerApiPublicDepsInnerWhitelist },
171 { "includes_absolute_deps_other", LoadIncludesAbsoluteDepsOtherWhitelist },
172 { "target_absolute_deps_other", LoadAbsoluteDepsOtherWhitelist },
173 { "import_other", LoadImportOtherWhitelist },
174 { "deps_not_lib", LoadDepsNotLibWhitelist },
175 { "fuzzy_match", LoadFuzzyMatchWhitelist }
176 };
177
LoadWhitelist(const std::string & build_dir)178 static void LoadWhitelist(const std::string &build_dir)
179 {
180 std::string whitelistContent;
181 if (!ReadBuildConfigFile(base::FilePath(build_dir + "/" + WHITELIST_PATH), whitelistContent)) {
182 if (!ReadBuildConfigFile(base::FilePath("out/products_ext/" + WHITELIST_PATH), whitelistContent)) {
183 if (!ReadBuildConfigFile(base::FilePath("build/" + WHITELIST_PATH), whitelistContent)) {
184 return;
185 }
186 }
187 }
188 const base::DictionaryValue *whitelist_dict;
189 std::unique_ptr<base::Value> whitelist = base::JSONReader::ReadAndReturnError(whitelistContent,
190 base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
191 if (!whitelist) {
192 return;
193 }
194 if (!whitelist->GetAsDictionary(&whitelist_dict)) {
195 return;
196 }
197
198 for (const auto kv : whitelist_dict->DictItems()) {
199 auto iter = whitelist_map_.find(kv.first);
200 if (iter != whitelist_map_.end()) {
201 iter->second(kv.second);
202 }
203 }
204 return;
205 }
206
IsIntercept(unsigned int switchValue,int shiftLeftNum)207 static bool IsIntercept(unsigned int switchValue, int shiftLeftNum)
208 {
209 if ((switchValue & (BASE_BINARY << (shiftLeftNum - 1))) != 0) {
210 return true;
211 }
212 return false;
213 }
214
InterceptAllDepsConfig(const Target * target,const std::string & label,Err * err) const215 bool OhosComponentChecker::InterceptAllDepsConfig(const Target *target, const std::string &label, Err *err) const
216 {
217 if (!IsIntercept(ruleSwitch_, ALL_DEPS_CONFIG_BINARY)) {
218 return true;
219 }
220
221 auto result = std::find(all_deps_config_.begin(), all_deps_config_.end(), label);
222 if (result != all_deps_config_.end()) {
223 return true;
224 }
225
226 *err = Err(target->defined_from(), "all_dependent_configs not allowed.",
227 "The item " + label + " does not allow all_dependent_configs.");
228 return false;
229 }
230
InterceptIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const231 bool OhosComponentChecker::InterceptIncludesOverRange(const Target *target, const std::string &label,
232 const std::string &dir, Err *err) const
233 {
234 if (!IsIntercept(ruleSwitch_, INCLUDE_OVER_RANGE_BINARY)) {
235 return true;
236 }
237
238 auto result = std::find(includes_over_range_.begin(), includes_over_range_.end(), label);
239 if (result != includes_over_range_.end()) {
240 return true;
241 }
242 *err = Err(target->defined_from(), "Header file range is too large.",
243 "The item " + label + " header : " + dir + " range is too large.");
244 return false;
245 }
246
InterceptInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const247 bool OhosComponentChecker::InterceptInnerApiPublicDepsInner(const Target *target, const std::string &label,
248 const std::string &deps, Err *err) const
249 {
250 if (!IsIntercept(ruleSwitch_, INNERAPI_PUBLIC_DEPS_INNER_BINARY)) {
251 return true;
252 }
253
254 if (auto res = innerapi_public_deps_inner_.find(label); res != innerapi_public_deps_inner_.end()) {
255 std::string deps_str(deps);
256 auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
257 if (res_second != res->second.end()) {
258 return true;
259 }
260 }
261 *err = Err(target->defined_from(), "InnerApi not allow the use of public_deps dependent internal modules.",
262 "The item " + label + " not allow the use of public_deps dependent internal modules : " + deps);
263 return false;
264 }
265
InterceptInnerApiNotLib(const Item * item,const std::string & label,Err * err) const266 bool OhosComponentChecker::InterceptInnerApiNotLib(const Item *item, const std::string &label, Err *err) const
267 {
268 if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_LIB_BINARY)) {
269 return true;
270 }
271
272 auto result = std::find(innerapi_not_lib_.begin(), innerapi_not_lib_.end(), label);
273 if (result != innerapi_not_lib_.end()) {
274 return true;
275 }
276 *err =
277 Err(item->defined_from(), "InnerApi is not a library type.", "The item " + label + " is not a library type.");
278 return false;
279 }
280
InterceptDepsNotLib(const Item * item,const std::string & label,const std::string & deps,Err * err) const281 bool OhosComponentChecker::InterceptDepsNotLib(const Item *item, const std::string &label,
282 const std::string &deps, Err *err) const
283 {
284 if (!IsIntercept(ruleSwitch_, DEPS_NOT_LIB_BINARY)) {
285 return true;
286 }
287
288 if (auto res = fuzzy_match_.find("deps_not_lib"); res != fuzzy_match_.end()) {
289 std::string deps_str(deps);
290 for (auto res_second : res->second) {
291 if (StartWith(Trim(deps_str), res_second)) {
292 return true;
293 }
294 }
295 }
296
297 if (auto res = deps_not_lib_.find(label); res != deps_not_lib_.end()) {
298 std::string deps_str(deps);
299 auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
300 if (res_second != res->second.end()) {
301 return true;
302 }
303 }
304 *err = Err(item->defined_from(), "Depend a non-lib target.",
305 "The item " + label + " cannot depend on a non-lib target " + deps);
306 return false;
307 }
308
InterceptInnerApiNotDeclare(const Item * item,const std::string & label,Err * err) const309 bool OhosComponentChecker::InterceptInnerApiNotDeclare(const Item *item, const std::string &label, Err *err) const
310 {
311 if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_DECLARE_BINARY)) {
312 return true;
313 }
314
315 auto result = std::find(innerapi_not_declare_.begin(), innerapi_not_declare_.end(), label);
316 if (result != innerapi_not_declare_.end()) {
317 return true;
318 }
319 *err = Err(item->defined_from(), "InnerApi is not defined in bundle.json.",
320 "The item " + label + " is not defined in bundle.json.");
321 return false;
322 }
323
InterceptIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const324 bool OhosComponentChecker::InterceptIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
325 const std::string &includes, Err *err) const
326 {
327 if (!IsIntercept(ruleSwitch_, INCLUDES_ABSOLUTE_DEPS_OTHER_BINARY)) {
328 return true;
329 }
330
331 if (auto res = fuzzy_match_.find("deps_includes_absolute"); res != fuzzy_match_.end()) {
332 std::string includes_str(includes);
333 for (auto res_second : res->second) {
334 if (StartWith(Trim(includes_str), res_second)) {
335 return true;
336 }
337 }
338 }
339
340 if (auto res = includes_absolute_deps_other_.find(label); res != includes_absolute_deps_other_.end()) {
341 std::string includes_str(includes);
342 auto res_second = std::find(res->second.begin(), res->second.end(), Trim(includes_str));
343 if (res_second != res->second.end()) {
344 return true;
345 }
346 }
347 *err = Err(target->defined_from(), "Do not directly use header files of other components.",
348 "The item " + label + " do not directly use header files : " + includes + " of other components." +
349 "\n"
350 "Please use 'external_deps/public_external_deps' dependent module.");
351 return false;
352 }
353
354
InterceptTargetAbsoluteDepsOther(const Item * item,const std::string & label,const std::string & deps,Err * err) const355 bool OhosComponentChecker::InterceptTargetAbsoluteDepsOther(const Item *item, const std::string &label,
356 const std::string &deps, Err *err) const
357 {
358 if (!IsIntercept(ruleSwitch_, TARGET_ABSOLUTE_DEPS_OTHER_BINARY)) {
359 return true;
360 }
361
362 if (auto res = fuzzy_match_.find("deps_component_absolute"); res != fuzzy_match_.end()) {
363 std::string deps_str(deps);
364 for (auto res_second : res->second) {
365 if (StartWith(Trim(deps_str), res_second)) {
366 return true;
367 }
368 }
369 }
370
371 if (auto res = target_absolute_deps_other_.find(label); res != target_absolute_deps_other_.end()) {
372 std::string deps_str(deps);
373 auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
374 if (res_second != res->second.end()) {
375 return true;
376 }
377 }
378 *err = Err(item->defined_from(), "Not allow use absolute dependent other component.",
379 "The item " + label + " not allow use absolute dependent other component : " + deps +
380 "\n"
381 "Please use 'external_deps/public_external_deps'.");
382 return false;
383 }
384
InterceptInnerApiVisibilityDenied(const Item * item,const std::string & from_label,const std::string & to_label,Err * err) const385 bool OhosComponentChecker::InterceptInnerApiVisibilityDenied(const Item *item, const std::string &from_label,
386 const std::string &to_label, Err *err) const
387 {
388 if (!IsIntercept(ruleSwitch_, INNERAPI_VISIBILITY_DENIED)) {
389 return true;
390 }
391
392 *err = Err(item->defined_from(), "InnerApi visibility denied.",
393 "The item " + from_label + " cannot dependent " + to_label +
394 "\n"
395 "Please check 'visibility' field in 'bundle.json' of " +
396 to_label);
397 return false;
398 }
399
InterceptImportOther(const FunctionCallNode * function,const std::string & label,const std::string & deps,Err * err) const400 bool OhosComponentChecker::InterceptImportOther(const FunctionCallNode *function, const std::string &label,
401 const std::string &deps, Err *err) const
402 {
403 if (!IsIntercept(ruleSwitch_, IMPORT_OTHER_BINARY)) {
404 return true;
405 }
406
407 if (auto res = fuzzy_match_.find("deps_gni"); res != fuzzy_match_.end()) {
408 std::string deps_str(deps);
409 for (auto res_second : res->second) {
410 if (StartWith(Trim(deps_str), res_second)) {
411 return true;
412 }
413 }
414 }
415
416 if (auto res = import_other_.find(label); res != import_other_.end()) {
417 std::string deps_str(deps);
418 auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
419 if (res_second != res->second.end()) {
420 return true;
421 }
422 }
423 *err = Err(function->function(), "Not allow import other gni.",
424 label + " not allow import other gni : " + deps);
425 return false;
426 }
427
OhosComponentChecker(const std::string & build_dir,int checkType,unsigned int ruleSwitch)428 OhosComponentChecker::OhosComponentChecker(const std::string &build_dir, int checkType, unsigned int ruleSwitch)
429 {
430 checkType_ = checkType;
431 build_dir_ = build_dir;
432 ruleSwitch_ = ruleSwitch;
433 if (checkType_ == CheckType::INTERCEPT_IGNORE_TEST || checkType_ == CheckType::INTERCEPT_ALL) {
434 LoadWhitelist(build_dir_);
435 }
436 if (checkType_ == CheckType::SCAN_ALL || checkType_ == CheckType::INTERCEPT_ALL) {
437 ignoreTest_ = false;
438 }
439 RemoveScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
440 }
441
GenerateScanList(const std::string & path,const std::string & subsystem,const std::string & component,const std::string & label,const std::string & deps) const442 void OhosComponentChecker::GenerateScanList(const std::string &path, const std::string &subsystem,
443 const std::string &component, const std::string &label, const std::string &deps) const
444 {
445 CreateScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
446 std::ofstream file;
447 file.open(build_dir_ + "/" + SCAN_RESULT_PATH + "/" + path, std::ios::app);
448 file << subsystem << " " << component << " " << label << " " << deps << "\n";
449 file.close();
450 return;
451 }
452
CheckAllDepsConfigs(const Target * target,const std::string & label,Err * err) const453 bool OhosComponentChecker::CheckAllDepsConfigs(const Target *target, const std::string &label, Err *err) const
454 {
455 if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
456 return true;
457 }
458
459 const OhosComponent *component = target->ohos_component();
460 if (component == nullptr) {
461 return true;
462 }
463 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
464 return InterceptAllDepsConfig(target, label, err);
465 }
466 GenerateScanList("all_dependent_configs.list", component->subsystem(), component->name(), label, "");
467 return true;
468 }
469
CheckInnerApiIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const470 bool OhosComponentChecker::CheckInnerApiIncludesOverRange(const Target *target, const std::string &label,
471 const std::string &dir, Err *err) const
472 {
473 if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
474 return true;
475 }
476
477 const OhosComponent *component = target->ohos_component();
478 if (component == nullptr || (!component->isInnerApi(label) && !StartWith(label, "//third_party"))) {
479 return true;
480 }
481
482 if (dir != "." && dir != "./" && dir != "../" && dir != component->path() && dir != component->path() + "/") {
483 return true;
484 }
485
486 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
487 return InterceptIncludesOverRange(target, label, dir, err);
488 }
489 GenerateScanList("includes_over_range.list", component->subsystem(), component->name(), label, dir);
490 return true;
491 }
492
CheckInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const493 bool OhosComponentChecker::CheckInnerApiPublicDepsInner(const Target *target, const std::string &label,
494 const std::string &deps, Err *err) const
495 {
496 if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
497 return true;
498 }
499
500 const OhosComponent *component = target->ohos_component();
501 if (component == nullptr || !component->isInnerApi(label)) {
502 return true;
503 }
504
505 if (!StartWith(deps, component->path()) && StartWith(deps, "//")) {
506 return true;
507 }
508
509 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
510 return InterceptInnerApiPublicDepsInner(target, label, deps, err);
511 }
512 GenerateScanList("innerapi_public_deps_inner.list", component->subsystem(), component->name(), label, deps);
513 return true;
514 }
515
CheckInnerApiNotLib(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const516 bool OhosComponentChecker::CheckInnerApiNotLib(const Item *item, const OhosComponent *component,
517 const std::string &label, const std::string &deps, Err *err) const
518 {
519 if (checkType_ <= CheckType::NONE || item == nullptr || item->AsTarget() == nullptr ||
520 (ignoreTest_ && item->testonly()) || component == nullptr) {
521 return true;
522 }
523
524 Target::OutputType type = item->AsTarget()->output_type();
525 if (type == Target::SHARED_LIBRARY || type == Target::STATIC_LIBRARY || type == Target::RUST_LIBRARY ||
526 type == Target::EXECUTABLE || type == Target::COPY_FILES) {
527 return true;
528 }
529
530 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
531 return InterceptDepsNotLib(item, label, deps, err) && InterceptInnerApiNotLib(item, deps, err);
532 }
533
534 std::string type_str(Target::GetStringForOutputType(type));
535 GenerateScanList("innerapi_not_lib.list", component->subsystem(), component->name(), deps, type_str);
536 GenerateScanList("deps_not_lib.list", component->subsystem(), component->name(), label, deps);
537 return true;
538 }
539
CheckInnerApiNotDeclare(const Item * item,const OhosComponent * component,const std::string & label,Err * err) const540 bool OhosComponentChecker::CheckInnerApiNotDeclare(const Item *item, const OhosComponent *component,
541 const std::string &label, Err *err) const
542 {
543 if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
544 return true;
545 }
546
547 if (component->isInnerApi(label)) {
548 return true;
549 }
550 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
551 return InterceptInnerApiNotDeclare(item, label, err);
552 }
553 GenerateScanList("innerapi_not_declare.list", component->subsystem(), component->name(), label, "");
554 return true;
555 }
556
CheckIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const557 bool OhosComponentChecker::CheckIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
558 const std::string &includes, Err *err) const
559 {
560 if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
561 return true;
562 }
563
564 if (includes == "//" || !StartWith(includes, "//") || StartWith(includes, "//out/")
565 || StartWith(includes, "////out/") || StartWith(includes, "//prebuilts/")) {
566 return true;
567 }
568
569 const OhosComponent *component = target->ohos_component();
570 if (component == nullptr) {
571 return true;
572 }
573
574 if (StartWith(includes, component->path())) {
575 return true;
576 }
577
578 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
579 return InterceptIncludesAbsoluteDepsOther(target, label, includes, err);
580 }
581 GenerateScanList("includes_absolute_deps_other.list", component->subsystem(), component->name(), label, includes);
582 return true;
583 }
584
CheckInnerApiVisibilityDenied(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const585 bool OhosComponentChecker::CheckInnerApiVisibilityDenied(const Item *item, const OhosComponent *component,
586 const std::string &label, const std::string &deps, Err *err) const
587 {
588 if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
589 return true;
590 }
591
592 if (!component->isInnerApi(deps)) {
593 return true;
594 }
595 std::vector<std::string> visibility = component->getInnerApiVisibility(deps);
596 if (visibility.empty()) {
597 return true;
598 }
599
600 const OhosComponent *from_component = item->ohos_component();
601 if (from_component == nullptr) {
602 return true;
603 }
604 auto result = std::find(visibility.begin(), visibility.end(), from_component->name());
605 if (result != visibility.end()) {
606 return true;
607 }
608
609 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
610 return InterceptInnerApiVisibilityDenied(item, label, deps, err);
611 }
612 GenerateScanList("innerkit_visibility_denied.list", from_component->subsystem(), from_component->name(), label,
613 deps);
614 return true;
615 }
616
CheckTargetAbsoluteDepsOther(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,bool is_external_deps,Err * err) const617 bool OhosComponentChecker::CheckTargetAbsoluteDepsOther(const Item *item, const OhosComponent *component,
618 const std::string &label, const std::string &deps, bool is_external_deps, Err *err) const
619 {
620 if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
621 return true;
622 }
623
624 if (is_external_deps) {
625 return true;
626 }
627
628 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
629 return InterceptTargetAbsoluteDepsOther(item, label, deps, err);
630 }
631
632 const OhosComponent *from_component = item->ohos_component();
633 if (from_component == nullptr) {
634 return true;
635 }
636 GenerateScanList("target_absolute_deps_other.list",
637 from_component->subsystem(), from_component->name(), label, deps);
638 return true;
639 }
640
CheckImportOther(const FunctionCallNode * function,const BuildSettings * build_settings,const std::string & label,const std::string & deps,Err * err) const641 bool OhosComponentChecker::CheckImportOther(const FunctionCallNode *function, const BuildSettings *build_settings,
642 const std::string &label, const std::string &deps, Err *err) const
643 {
644 if (checkType_ <= CheckType::NONE || function == nullptr || build_settings == nullptr) {
645 return true;
646 }
647 const OhosComponent *component = build_settings->GetOhosComponent(label);
648 if (component == nullptr) {
649 return true;
650 }
651 if (StartWith(deps, component->path()) || StartWith(deps, "//build/") || StartWith(deps, "//out/")
652 || StartWith(deps, "//prebuilts/")) {
653 return true;
654 }
655
656 if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
657 return InterceptImportOther(function, label, deps, err);
658 }
659 GenerateScanList("import_other.list", component->subsystem(), component->name(), label, deps);
660 return true;
661 }
662