1414# problems we disallow the direct use of memcpy. The exceptions are in
1515# third-party code and in platform/globals.h which uses it to implement
1616# bit_cast and bit_copy.
17- def CheckMemcpy (filename ):
17+ # pthread_detach (and therefore std::thread::detach) have a bug that can
18+ # result in crashes. https://sourceware.org/bugzilla/show_bug.cgi?id=19951
19+ BANNED_FUNCTIONS = [
20+ ['\\ bmemcpy\\ (' , 'memcpy' ],
21+ ['\\ bpthread_detach\\ (' , 'pthread_detach' ],
22+ ['\\ bdetach\\ (' , 'std::thread::detach' ],
23+ ]
24+
25+
26+ def CheckBannedFunctions (filename ):
1827 if filename .endswith (os .path .join ('platform' , 'globals.h' )) or \
1928 filename .find ('third_party' ) != - 1 :
2029 return 0
2130 fh = open (filename , 'r' )
2231 content = fh .read ()
23- match = re .search ('\\ bmemcpy\\ b' , content )
24- if match :
25- offset = match .start ()
26- end_of_line = content .index ('\n ' , offset )
27- # We allow explicit use of memcpy with an opt-in via NOLINT
28- if 'NOLINT' not in content [offset :end_of_line ]:
29- line_number = content [0 :match .start ()].count ('\n ' ) + 1
30- print ("%s:%d: use of memcpy is forbidden" % (filename , line_number ))
31- return 1
32+
33+ for banned_function in BANNED_FUNCTIONS :
34+ pattern = banned_function [0 ]
35+ name = banned_function [1 ]
36+ match = re .search (pattern , content )
37+ if match :
38+ offset = match .start ()
39+ end_of_line = content .index ('\n ' , offset )
40+ # We allow explicit use of memcpy with an opt-in via NOLINT
41+ if 'NOLINT' not in content [offset :end_of_line ]:
42+ line_number = content [0 :match .start ()].count ('\n ' ) + 1
43+ print ("%s:%d: use of %s is forbidden" %
44+ (filename , line_number , name ))
45+ return 1
3246 return 0
3347
3448
3549def RunLint (input_api , output_api ):
3650 result = []
3751 cpplint ._cpplint_state .ResetErrorCounts ()
38- memcpy_match_count = 0
52+ banned_match_count = 0
3953 # Find all .cc and .h files in the change list.
4054 for git_file in input_api .AffectedTextFiles ():
4155 filename = git_file .AbsoluteLocalPath ()
@@ -47,10 +61,10 @@ def RunLint(input_api, output_api):
4761 # Run cpplint on the file.
4862 cpplint .ProcessFile (filename , 1 )
4963 # Check for memcpy use.
50- memcpy_match_count += CheckMemcpy (filename )
64+ banned_match_count += CheckBannedFunctions (filename )
5165
5266 # Report a presubmit error if any of the files had an error.
53- if cpplint ._cpplint_state .error_count > 0 or memcpy_match_count > 0 :
67+ if cpplint ._cpplint_state .error_count > 0 or banned_match_count > 0 :
5468 result = [output_api .PresubmitError ('Failed cpplint check.' )]
5569 return result
5670
0 commit comments