You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

coding_guild_cpp_en.md 28 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. <!-- TOC -->
  2. - [Note](#note)
  3. - [Scope](#scope)
  4. - [Code Style](#1-code-style)
  5. - [Naming](#11-naming)
  6. - [Format](#12-format)
  7. - [Comment](#13-comment)
  8. - [General Coding](#2-general-coding)
  9. - [Code Design](#21-code-design)
  10. - [Header File and Preprocessing](#22-header-file-and-preprocessing)
  11. - [Data Type](#23-data-type)
  12. - [Constant](#24-constant)
  13. - [Variable](#25-variable)
  14. - [Expression](#26-expression)
  15. - [Conversion](#27-conversion)
  16. - [Control Statement](#28-control-statement)
  17. - [Declaration and Initialization](#29-declaration-and-initialization)
  18. - [Pointer and Array](#210-pointer-and-array)
  19. - [String](#211-string)
  20. - [Assert](#212-assert)
  21. - [Class and Object](#213-class-and-object)
  22. - [Function Design](#214-function-design)
  23. - [Function Usage](#215-function-usage)
  24. - [Memory](#216-memory)
  25. - [File](#217-file)
  26. - [Secure Function](#218-secure-function)
  27. <!-- /TOC -->
  28. ## Note
  29. This document is developed based on [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html), Huawei C++ Coding Style Guide, Huawei secure coding standards, and industry consensus. To participate in the MindSpore community, please comply with this style guide, and then the Google C++ Style Guide.
  30. If you disagree with the rules, you are advised to submit an issue and provide reasons. The issue can take effect after being reviewed, accepted, and modified by the MindSpore community operation team.
  31. ## Scope
  32. MindSpore open source community
  33. ------------------
  34. ### <a name="csf">1. Code Style</a>
  35. #### <a name="nm">1.1 Naming</a>
  36. ##### Rule 1.1.1 File Naming
  37. C++ files are named in the format of lowercase letters + underscores (_). The file name extension is `.cc`. The header file name extension is `.h`. The unit test file name ends with `_test.cc`.
  38. > a_b_c.h
  39. > a_b_c.cc
  40. > a_b_c_test.cc
  41. ##### Rule 1.1.2 Use lowercase letters and underscores (_) to name local variables and parameters
  42. ```cpp
  43. void FooBar(int func_param) {
  44. int local_var;
  45. }
  46. ```
  47. ##### Rule 1.1.3 Use lowercase letters and underscores (_) to name member variables, with an underscore (_) as the suffix
  48. ```cpp
  49. class FooBar {
  50. public:
  51. int mamber_var_;
  52. };
  53. ```
  54. ##### Rule 1.1.4 Use uppercase letters and underscores (_) in macro names
  55. ```cpp
  56. #define MS_LOG(...)
  57. ```
  58. ##### Rule 1.1.5 Name constants and enumerations in the CamelCase style starting with letterr "k."
  59. ```cpp
  60. const int kDaysInAWeek = 7;
  61. enum UrlTableErrors {
  62. kOk = 0,
  63. kErrorOutOfMemory,
  64. kErrorMalformedInput,
  65. };
  66. ```
  67. ##### Rule 1.1.6 Naming of function
  68. 1. Class member variable accessor:naming of accessor should comply with naming rule of variables and parameters, such as:
  69. ```c++
  70. int count() {return this->count_;}
  71. ```
  72. 2. Class member variable modifier:naming of modifier should be started with `set_` and followed by variables or parameters name, such as:
  73. ```c++
  74. void set_count(int count) {this->count_ = count;}
  75. ```
  76. 3. Other class member functions/common functions: named based on the large hump rules, such as:
  77. ```c++
  78. void FindPattern(...);
  79. ```
  80. #### <a name="fmt">1.2 Format</a>
  81. ##### Recommendation 1.2.1 Each line contains a maximum of 120 characters
  82. If a line contains more than 120 characters, start a new line properly.
  83. ##### Rule 1.2.2 Use spaces to indent, two at a time
  84. ##### Rule 1.2.3 When declaring a pointer or referencing variables or parameters, follow variable names with `&` and `*` and place a space on the other side
  85. ```cpp
  86. char *c;
  87. const std::string &str;
  88. ```
  89. ##### Rule 1.2.4 Use braces to include an if statement
  90. ```cpp
  91. // Even if the if branch code is within one line, braces are required.
  92. if (cond) {
  93. single line code;
  94. }
  95. ```
  96. ##### Rule 1.2.5 Use braces for loop statements such as for and while statements, even if the loop body is empty or there is only one loop statement
  97. ##### Rule 1.2.6 Keep a consistent line break style for expressions and ensure that operators are placed at the end of a line
  98. ```cpp
  99. int a = a_very_long_expression +
  100. a_very_very_long_expression +
  101. a_very_very_very_long_expression;
  102. ```
  103. ##### Rule 1.2.7 Each variable definition or assignment statement occupies one line
  104. ```cpp
  105. a = 1;
  106. b = 2;
  107. c = 3;
  108. ```
  109. #### <a name="nts">1.3 Comment</a>
  110. ##### Rule 1.3.1 File header comments contain copyright statements
  111. All .h and .cc files must contain the following copyright statements:
  112. ```cpp
  113. /**
  114. * Copyright 2019 Huawei Technologies Co., Ltd
  115. *
  116. * Licensed under the Apache License, Version 2.0 (the "License");
  117. * you may not use this file except in compliance with the License.
  118. * You may obtain a copy of the License at
  119. *
  120. * http://www.apache.org/licenses/LICENSE-2.0
  121. *
  122. * Unless required by applicable law or agreed to in writing, software
  123. * distributed under the License is distributed on an "AS IS" BASIS,
  124. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  125. * See the License for the specific language governing permissions and
  126. * limitations under the License.
  127. */
  128. ```
  129. > Notes:
  130. > Files created in 2020 should contain `Copyright 2020 Huawei Technologies Co., Ltd`.
  131. > Files created in 2019 and modified in 2020 should contain `Copyright 2019-2020 Huawei Technologies Co., Ltd`.
  132. ##### Rule 1.3.2 A comment is placed above or to the right of the code. There must be a space between the comment character and the comment content, and at least one space between the code and its comment on the right. Use `//`, not `/**/`
  133. ```cpp
  134. // this is multi-
  135. // line comment
  136. int foo; // this single-line comment
  137. ```
  138. ##### Rule 1.3.3 Do not use comments such as TODO, TBD, and FIXME in code. You are advised to submit an issue for tracking
  139. ##### Recommendation 1.3.4 Function header comments with no content are forbidden
  140. Not all functions require header comments. You are advised to use the name of the function as its comment and write header comments if there is the need. For the information that cannot be expressed by the function prototype but is expected to be known by readers, function header comments are required.
  141. Do not write useless or redundant function headers. The function header comments are optional, including but not limited to function description, return values, performance constraints, usage, memory conventions, algorithm implementation, and reentrant requirements.
  142. ### <a name="cc">2. General Coding</a>
  143. #### <a name="cdes">2.1 Code Design</a>
  144. ##### Rule 2.1.1 Check the validity of all external data, including but not limited to function input parameters, external input named lines, files, environment variables, and user data
  145. ##### Rule 2.1.2 When transferring function execution results, preferentially use return values and avoid output parameters
  146. ```cpp
  147. FooBar *Func(const std::string &in);
  148. ```
  149. ##### Rule 2.1.3 Delete invalid, redundant, or never-executed code
  150. Although most modern compilers in many cases can alert you to invalid or never executed code, responding alarms should be identified and cleared.
  151. Identify and delete invalid statements or expressions from the code.
  152. ##### Rule 2.1.4 Follow additional specifications to the C++ exception mechanism
  153. ###### Rule 2.1.4.1 Specify the types of exceptions to be captured. Do not capture all exceptions
  154. ```cpp
  155. // Incorrect
  156. try {
  157. // do something;
  158. } catch (...) {
  159. // do something;
  160. }
  161. // Correct
  162. try {
  163. // do something;
  164. } catch (const std::bad_alloc &e) {
  165. // do something;
  166. }
  167. ```
  168. #### <a name="inc">2.2 Header File and Preprocessing</a>
  169. ##### Rule 2.2.1 Use the new standard C++ header file
  170. ```cpp
  171. // Correct
  172. #include <cstdlib>
  173. // Incorrect
  174. #include <stdlib.h>
  175. ```
  176. ##### Rule 2.2.2 Header file cyclic dependency is forbidden
  177. An example of cyclic dependency (also known as circular dependency) is: a.h contains b.h, b.h contains c.h, and c.h contains a.h. If any of these header files is modified, all code containing a.h, b.h, and c.h needs to be recompiled.
  178. The cyclic dependency of header files reflects an obviously unreasonable architecture design, which can be avoided through optimization.
  179. ##### Rule 2.2.3 Do not include unnecessary header files
  180. ##### Rule 2.2.4 It is prohibited to reference external function interfaces and variables in extern declaration mode
  181. ##### Rule 2.2.5 Do not include header files in extern "C"
  182. ##### Rule 2.2.6 Do not use "using" to import namespace in a header file or before #include statements
  183. #### <a name="dtype">2.3 Data Type</a>
  184. ##### Recommendation 2.3.1 Do not abuse typedef or #define to alias basic types
  185. ##### Rule 2.3.2 Use “using” instead of typedef to define the alias of a type to avoid shot-bomb modification caused by type changes
  186. ```cpp
  187. // Correct
  188. using FooBarPtr = std::shared_ptr<FooBar>;
  189. // Incorrect
  190. typedef std::shared_ptr<FooBar> FooBarPtr;
  191. ```
  192. #### <a name="cons">2.4 Constant</a>
  193. ##### Rule 2.4.1 Do not use macros to replace constants
  194. ##### Rule 2.4.2 Do not use magic numbers or character strings
  195. ##### Recommendation 2.4.3 Ensure that a constant has only one responsibility
  196. #### <a name="var">2.5 Variable</a>
  197. ##### Recommendation 2.5.1 Use namespaces to manage global constants. If the global constants are closely tied to a class, you can use static member constants to manage them
  198. ```cpp
  199. namespace foo {
  200. int kGlobalVar;
  201. class Bar {
  202. private:
  203. static int static_member_var_;
  204. };
  205. }
  206. ```
  207. ##### Rule 2.5.2 Do not use global variables. Use the singleton pattern cautiously to avoid abuse
  208. ##### Rule 2.5.3 A variable cannot be referenced again if it is contained in an increment or decrement operation in an expression
  209. ##### Rule 2.5.4 After the resource is released, immediately assign a new value to the pointer variable that points to a resource handle or descriptor, or set the value to NULL
  210. ##### Rule 2.5.5 Do not use uninitialized variables
  211. #### <a name="exp">2.6 Expression</a>
  212. ##### Recommendation 2.6.1 When comparing expressions, follow the principle that the left side tends to change and the right side tends to remain unchanged
  213. ```cpp
  214. // Correct
  215. if (ret != SUCCESS) {
  216. ...
  217. }
  218. // Incorrect
  219. if (SUCCESS != ret) {
  220. ...
  221. }
  222. ```
  223. ##### Rule 2.6.2 Use parentheses to specify the operator precedence to avoid rookie errors
  224. ```cpp
  225. // Correct
  226. if (cond1 || (cond2 && cond3)) {
  227. ...
  228. }
  229. // Incorrect
  230. if (cond1 || cond2 && cond3) {
  231. ...
  232. }
  233. ```
  234. #### <a name="exc">2.7 Conversion</a>
  235. ##### Rule 2.7.1 Use the type casting provided by the C++ instead of the C style. Do not use const_cast and reinterpret_cast
  236. #### <a name="ctrl">2.8 Control Statement</a>
  237. ##### Rule 2.8.1 A switch statement must have a default branch
  238. #### <a name="init">2.9 Declaration and Initialization</a>
  239. ##### Rule 2.9.1 Do not use `memcpy_s` or `memset_s` to initialize non-POD objects
  240. #### <a name="ptr">2.10 Pointer and Array</a>
  241. ##### Rule 2.10.1 Do not use the pointer returned by c_str () of std::string
  242. ```cpp
  243. // Incorrect
  244. const char * a = std::to_string(12345).c_str();
  245. ```
  246. ##### Rule 2.10.2 Prefer `unique_ptr` to `shared_ptr`
  247. ##### Rule 2.10.3 Create `shared_ptr` by using `std::make_shared` instead of `new`
  248. ```cpp
  249. // Correct
  250. std::shared_ptr<FooBar> foo = std::make_shared<FooBar>();
  251. // Incorrect
  252. std::shared_ptr<FooBar> foo(new FooBar());
  253. ```
  254. ##### Rule 2.10.4 Use a smart pointer to manage objects. Do not use new or delete
  255. ##### Rule 2.10.5 Do not use auto_ptr
  256. ##### Rule 2.10.6 For formal parameters of pointer and reference types, if the parameters do not need to be modified, use const
  257. ##### Rule 2.10.7 Use the array length as a function parameter when the array is a function parameter
  258. ```cpp
  259. int ParseMsg(BYTE *msg, size_t msgLen) {
  260. ...
  261. }
  262. ```
  263. #### <a name="str">2.11 String</a>
  264. ##### Rule 2.11.1 When saving a string, ensure that it has '\0' at the end
  265. #### <a name="ast">2.12 Assert</a>
  266. ##### Rule 2.12.1 Assert cannot be used to verify errors that may occur when the program is running. To handle possible running errors, use error processing code
  267. #### <a name="cls">2.13 Class and Object</a>
  268. ##### Rule 2.13.1 When a single object is released, delete is used. When an array object is released, delete [] is used
  269. ```cpp
  270. const int kSize = 5;
  271. int *number_array = new int[kSize];
  272. int *number = new int();
  273. ...
  274. delete[] number_array;
  275. number_array = nullptr;
  276. delete number;
  277. number = nullptr;
  278. ```
  279. ##### Rule 2.13.2 Do not use std::move to operate the const object
  280. ##### Rule 2.13.3 Strictly use virtual/override/final to modify virtual functions
  281. ```cpp
  282. class Base {
  283. public:
  284. virtual void Func();
  285. };
  286. class Derived : public Base {
  287. public:
  288. void Func() override;
  289. };
  290. class FinalDerived : public Derived {
  291. public:
  292. void Func() final;
  293. };
  294. ```
  295. #### <a name="fdes">2.14 Function Design</a>
  296. ##### Rule 2.14.1 Use the RAII feature to help track dynamic allocation
  297. ```cpp
  298. // Correct
  299. {
  300. std::lock_guard<std::mutex> lock(mutex_);
  301. ...
  302. }
  303. ```
  304. ##### Rule 2.14.2 Avoid capturing by reference in lambdas that will not be used locally
  305. ```cpp
  306. {
  307. int local_var = 1;
  308. auto func = [&]() { ...; std::cout << local_var << std::endl; };
  309. thread_pool.commit(func);
  310. }
  311. ```
  312. ##### Rule 2.14.3 Do not use default parameter values for virtual functions
  313. ##### Recommendation 2.14.4 Use strongly typed parameters or member variables. Do not use void*
  314. #### <a name="fuse">2.15 Function Usage</a>
  315. ##### Rule 2.15.1 The input parameter must be transferred before the output parameter
  316. ```cpp
  317. bool Func(const std::string &in, FooBar *out1, FooBar *out2);
  318. ```
  319. ##### Rule 2.15.2 Use `const T &` as the input parameter and `T *` as the output parameter for function transfer
  320. ```cpp
  321. bool Func(const std::string &in, FooBar *out1, FooBar *out2);
  322. ```
  323. ##### Rule 2.15.3 In the scenario where ownership is not involved, use T * or const T & instead of the smart pointer as the transfer parameter
  324. ```cpp
  325. // Correct
  326. bool Func(const FooBar &in);
  327. // Incorrect
  328. bool Func(std::shared_ptr<FooBar> in);
  329. ```
  330. ##### Rule 2.15.4 To transfer the ownership, you are advised to use shared_ptr + move to transfer parameters
  331. ```cpp
  332. class Foo {
  333. public:
  334. explicit Foo(shared_ptr<T> x):x_(std::move(x)){}
  335. private:
  336. shared_ptr<T> x_;
  337. };
  338. ```
  339. ##### Rule 2.15.5 Use explicit to modify single-parameter constructors and do not use explicit to modify multi-parameter constructors
  340. ```cpp
  341. explicit Foo(int x); //good :white_check_mark:
  342. explicit Foo(int x, int y=0); //good :white_check_mark:
  343. Foo(int x, int y=0); //bad :x:
  344. explicit Foo(int x, int y); //bad :x:
  345. ```
  346. ##### Rule 2.15.6 Copy constructors and copy assignment operators should be implemented or hidden together
  347. ```cpp
  348. class Foo {
  349. private:
  350. Foo(const Foo&) = default;
  351. Foo& operator=(const Foo&) = default;
  352. Foo(Foo&&) = delete;
  353. Foo& operator=(Foo&&) = delete;
  354. };
  355. ```
  356. ##### Rule 2.15.7 [Question] Do not save or delete pointer parameters
  357. ##### Rule 2.15.8 [Question] Do not use insecure functions as listed
  358. ##### Rule 2.15.9 [Question] Do not use insecure exit functions as listed
  359. ```cpp
  360. {
  361. Kill(...); // If you invoke kill to forcibly terminate other processes (such as kill -9), the resources of other processes cannot be cleared.
  362. TerminateProcess(); // If you call the erminateProcess function to forcibly terminate other processes, the resources of other processes cannot be cleared.
  363. pthread_exit(); // Do not terminate a thread. The thread functions will exit automatically and safely after the execution is complete.
  364. ExitThread(); // Do not terminate a thread. The thread functions will exit automatically and safely after the execution is complete.
  365. exit(); // Do not call any function except the main function. The program must exit safely.
  366. ExitProcess(); // Do not call any function except the main function. The program must exit safely.
  367. abort(); //Forbidden. If abort is used, the program exits immediately and resources cannot be cleared.
  368. }
  369. ```
  370. ##### Rule 2.15.10 Do not use the rand function to generate pseudo-random numbers for security purposes
  371. The rand() function in the C standard library generates pseudo-random numbers. To generate random numbers, use /dev/random.
  372. ##### Rule 2.15.11 Do not use the string class to store sensitive information
  373. The string class is a character string management class defined in C++. If sensitive information such as passwords is operated through the string class, the sensitive information can be
  374. scattered in various places of the memory and cannot be cleared.
  375. In the following code, the Foo function obtains the password, saves it to the string variable password, and then transfers it to the VerifyPassword function. In this process,
  376. two copies of the password exist in the memory.
  377. ```cpp
  378. int VerifyPassword(string password) {
  379. //...
  380. }
  381. int Foo() {
  382. string password = GetPassword();
  383. VerifyPassword(password);
  384. ...
  385. }
  386. ```
  387. Sensitive information must be stored using char or unsigned char. For example:
  388. ```cpp
  389. int VerifyPassword(const char *password) {
  390. //...
  391. }
  392. int Foo() {
  393. char password[MAX_PASSWORD] = {0};
  394. GetPassword(password, sizeof(password));
  395. VerifyPassword(password);
  396. ...
  397. }
  398. ```
  399. ##### Rule 2.15.12 Clear sensitive information in the memory immediately after use
  400. Sensitive information, such as passwords and keys, must be cleared immediately after being used to prevent attackers from obtaining the information.
  401. #### <a name="mem">2.16 Memory</a>
  402. ##### Rule 2.16.1 Check whether memory allocation is successful
  403. If the memory allocation fails, the subsequent operations may have undefined behavior risks. For example, if malloc fails to be applied for and a null pointer is returned, dereference of the null pointer is an undefined behavior.
  404. ##### Rule 2.16.2 Do not reference uninitialized memory
  405. The memory allocated by malloc and new is not initialized to 0. Ensure that the memory is initialized before being referenced.
  406. ##### Rule 2.16.3 Do not use the realloc() function
  407. The behavior of the realloc function varies with parameters. This is not a well-designed function. Although it provides some convenience in coding, it can easily cause various bugs.
  408. ##### Rule 2.16.4 Do not use the alloca() function to apply for stack memory
  409. Neither POSIX nor C99 defines the alloca() behavior. Some platforms do not support this function. Using alloca() reduces program compatibility and portability. This function requests memory in the stack frame. The requested size may exceed the stack boundary, affecting code execution.
  410. #### <a name="file">2.17 File</a>
  411. ##### Rule 2.17.1 File paths must be canonicalized before use
  412. A file path that comes from external data must be canonicalized first. If the file path is not canonicalized, attackers can construct a malicious file path to access the file without authorization.
  413. For example, an attacker can construct “../../../etc/passwd” to access any file.
  414. Use the realpath() function in Linux and the PathCanonicalize() function in Windows for file path canonicalization.
  415. [Noncompliant Code Example]
  416. The following code obtains the file name from an external system, concatenates the file name into a file path, and directly reads the file content. As a result, the attacker can read the content of any file.
  417. ```cpp
  418. char *fileName = GetMsgFromRemote();
  419. ...
  420. sprintf_s(untrustPath, sizeof(untrustPath), "/tmp/%s", fileName);
  421. char *text = ReadFileContent(untrustPath); // Bad: Did not check whether the untrustPath can be accessed before the data is read.
  422. ```
  423. [Compliant Code Example]
  424. Canonicalize the file path and then check whether the path is valid in the program.
  425. ```cpp
  426. char *fileName = GetMsgFromRemote();
  427. ...
  428. sprintf_s(untrustPath, sizeof(untrustPath), "/tmp/%s", fileName);
  429. char path[PATH_MAX] = {0};
  430. if (realpath(untrustPath, path) == NULL) {
  431. //error
  432. ...
  433. }
  434. if (!IsValidPath(path)) { // Good: Check whether the file location is correct.
  435. //error
  436. ...
  437. }
  438. char *text = ReadFileContent(untrustPath);
  439. ```
  440. Exceptions:
  441. Command line programs that run on the console, or file paths that are manually entered on the console are exempted from this rule.
  442. ##### Rule 2.17.2 Do not create temporary files in the shared directory
  443. Temporary files of a program must be exclusively used by itself. Otherwise, other users of the shared directory may obtain additional information about the program, resulting in information leakage. Therefore, do not create temporary files that should be used only by the program itself in any shared directory.
  444. For example, the /tmp directory in Linux is a shared directory that all users can access. Do not create temporary files that should be used only by the program itself in this directory.
  445. #### <a name="sf">2.18 Secure Function</a>
  446. <table>
  447. <thead>
  448. <tr>
  449. <th style="width: 100px; ">Secure Function Type</th>
  450. <th style="width: 150px; ">Description</th>
  451. <th>Remarks</th>
  452. </tr>
  453. </thead>
  454. <tr>
  455. <td rowspan="1">xxx_s</td>
  456. <td>Secure function API of Huawei Secure C library</td>
  457. <td> It can be used when the Huawei Secure C library is integrated.</td>
  458. </tr>
  459. <tr>
  460. <td rowspan="1">xxx_sp</td>
  461. <td> API of Huawei Secure C library with optimized secure function performance (macro implementation)</td>
  462. <td>
  463. If count, destMax, and strSrc are constants, the performance-optimized macro interface displays its effect. If they are variables, the performance optimization effect is not obvious. The macro interface usage policy is as follows: The _s interface is used by default. The _sp interface is restricted in performance-sensitive call sites. The restriction scenarios are as follows:
  464. a) memset_sp and memcpy_sp: destMax and count are constants.
  465. b) strcpy_sp or strcat_sp: destMax is a constant and strSrc is a literal.
  466. c) strncpy_sp or strncat_sp: destMax and count are constants and strSrc is a literal.</td>
  467. </tr>
  468. </table>
  469. ##### Rule 2.15.18 Use secure functions provided by the community in the secure function library. Do not use dangerous functions related to memory operations
  470. <table>
  471. <thead>
  472. <tr>
  473. <th style="width: 100px; ">Function Type</th>
  474. <th style="width: 150px; ">Dangerous Function</th>
  475. <th>Secure Surrogate Function</th>
  476. </tr>
  477. </thead>
  478. <tr>
  479. <td rowspan="4">Memory copy</td>
  480. <td>memcpy or bcopy</td>
  481. <td>memcpy_s</td>
  482. </tr>
  483. <tr>
  484. <td>wmemcpy</td>
  485. <td>wmemcpy_s</td>
  486. </tr>
  487. <tr>
  488. <td>memmove</td>
  489. <td>memmove_s</td>
  490. </tr>
  491. <tr>
  492. <td>wmemmove</td>
  493. <td>wmemmove_s</td>
  494. </tr>
  495. <tr>
  496. <td rowspan="4">String copy</td>
  497. <td>strcpy</td>
  498. <td>strcpy_s</td>
  499. </tr>
  500. <tr>
  501. <td>wcscpy</td>
  502. <td>wcscpy_s</td>
  503. </tr>
  504. <tr>
  505. <td>strncpy</td>
  506. <td>strncpy_s</td>
  507. </tr>
  508. <tr>
  509. <td>wcsncpy</td>
  510. <td>wcsncpy_s</td>
  511. </tr>
  512. <tr>
  513. <td rowspan="4">Character string concatenation</td>
  514. <td>strcat</td>
  515. <td>strcat_s</td>
  516. </tr>
  517. <tr>
  518. <td>wcscat</td>
  519. <td>wcscat_s</td>
  520. </tr>
  521. <tr>
  522. <td>strncat</td>
  523. <td>strncat_s</td>
  524. </tr>
  525. <tr>
  526. <td>wcsncat</td>
  527. <td>wcsncat_s</td>
  528. </tr>
  529. <tr>
  530. <td rowspan="6">Format output</td>
  531. <td>sprintf</td>
  532. <td>sprintf_s</td>
  533. </tr>
  534. <tr>
  535. <td>swprintf</td>
  536. <td>swprintf_s</td>
  537. </tr>
  538. <tr>
  539. <td>vsprintf</td>
  540. <td>vsprintf_s</td>
  541. </tr>
  542. <tr>
  543. <td>vswprintf</td>
  544. <td>vswprintf_s</td>
  545. </tr>
  546. <tr>
  547. <td>snprintf</td>
  548. <td>snprintf_s or snprintf_truncated_s</td>
  549. </tr>
  550. <tr>
  551. <td>vsnprintf</td>
  552. <td>vsnprintf_s or vsnprintf_truncated_s</td>
  553. </tr>
  554. <tr>
  555. <td rowspan="12">Format input</td>
  556. <td>scanf</td>
  557. <td>scanf_s</td>
  558. </tr>
  559. <tr>
  560. <td>wscanf</td>
  561. <td>wscanf_s</td>
  562. </tr>
  563. <tr>
  564. <td>vscanf</td>
  565. <td>vscanf_s</td>
  566. </tr>
  567. <tr>
  568. <td>vwscanf</td>
  569. <td>vwscanf_s</td>
  570. </tr>
  571. <tr>
  572. <td>fscanf</td>
  573. <td>fscanf_s</td>
  574. </tr>
  575. <tr>
  576. <td>fwscanf</td>
  577. <td>fwscanf_s</td>
  578. </tr>
  579. <tr>
  580. <td>vfscanf</td>
  581. <td>vfscanf_s</td>
  582. </tr>
  583. <tr>
  584. <td>vfwscanf</td>
  585. <td>vfwscanf_s</td>
  586. </tr>
  587. <tr>
  588. <td>sscanf</td>
  589. <td>sscanf_s</td>
  590. </tr>
  591. <tr>
  592. <td>swscanf</td>
  593. <td>swscanf_s</td>
  594. </tr>
  595. <tr>
  596. <td>vsscanf</td>
  597. <td>vsscanf_s</td>
  598. </tr>
  599. <tr>
  600. <td>vswscanf</td>
  601. <td>vswscanf_s</td>
  602. </tr>
  603. <tr>
  604. <td rowspan="1">Standard input stream input</td>
  605. <td>gets</td>
  606. <td>gets_s</td>
  607. </tr>
  608. <tr>
  609. <td rowspan="1">Memory initialization</td>
  610. <td>memset</td>
  611. <td>memset_s</td>
  612. </tr>
  613. </table>
  614. ##### Rule 2.18.2 Correctly set the destMax parameter in secure functions
  615. ##### Rule 2.18.3 Do not encapsulate secure functions
  616. ##### Rule 2.18.4 Do not rename secure functions using macros
  617. ```cpp
  618. #define XXX_memcpy_s memcpy_s
  619. #define SEC_MEM_CPY memcpy_s
  620. #define XX_memset_s(dst, dstMax, val, n) memset_s((dst), (dstMax), (val), (n))
  621. ```
  622. ##### Rule 2.18.5 Do not customize secure functions
  623. Using macros to rename secure functions does not help static code scanning tools (non-compiled) customize rules for the misuse of secure functions. In addition, there are various naming styles.
  624. In addition, it is not conducive to reminding the code developer of the real usage of functions, and may easily cause misunderstanding of the code and misuse of the renamed secure functions. Renaming secure functions will not
  625. affect the checking capability of the secure functions.
  626. ```cpp
  627. void MemcpySafe(void *dest, unsigned int destMax, const void *src, unsigned int count) {
  628. ...
  629. }
  630. ```
  631. ##### Rule 2.18.6 Check the return values of secure functions and correctly process them
  632. In principle, if a secure function is used, its return value must be checked. If the return value is ! = EOK, this function should be returned immediately,
  633. and cannot be continued.
  634. A secure function may have multiple erroneous return values. If a secure function returns a failure, perform the following operations (one or more) based on specific product scenario before it is returned
  635. :
  636. (1) Record logs.
  637. (2) Return an error.
  638. (3) Call abort to exit the program immediately.
  639. ```cpp
  640. {
  641. ...
  642. err = memcpy_s(destBuff, destMax, src, srcLen);
  643. if (err != EOK) {
  644. MS_LOG("memcpy_s failed, err = %d\n", err);
  645. return FALSE;
  646. }
  647. ...
  648. }
  649. ```
  650. ##### Rule 2.18.7 Do not use external controllable data as function parameters for starting processes, such as system, popen, WinExec, ShellExecute, execl, xeclp, execle, execv, execvp and CreateProcess
  651. ##### Rule 2.18.8 Do not use external controllable data as parameters for module loading functions such as dlopen/LoadLibrary
  652. ##### Rule 2.18.9 Do not call non-asynchronous secure functions in signal processing routines
  653. Signal processing routines should be as simple as possible. If a non-asynchronous secure function is called in a signal processing routine, the execution of the function may not generate expected results.
  654. The signal handler in the following code writes logs by calling fprintf(), but the function is not asynchronous secure function.
  655. ```cpp
  656. void Handler(int sigNum) {
  657. ...
  658. fprintf(stderr, "%s\n", info);
  659. }
  660. ```
  661. ------------------