Cleaned up code for patch handling, fix bug in subdir handling, include patch info in help.

git-svn-id: svn+ssh://svn.code.sf.net/p/flawfinder/code/trunk@10 5c01084b-1f27-0410-9f85-80411afe95dc
This commit is contained in:
dwheeler 2007-01-16 14:32:07 +00:00
parent 6f58639f5f
commit bff102b656
2 changed files with 63 additions and 51 deletions

View File

@ -1,3 +1,7 @@
2007-01-16 Sebastien Tandel <sebastien, at, tandel (doht) be)
* Cleaned up code for patch handling, fix bug in subdir handling,
include patch info in help.
2007-01-15 Steve Kemp <steve at shellcode dot org> 2007-01-15 Steve Kemp <steve at shellcode dot org>
* Fix Debian bug #268236. * Fix Debian bug #268236.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=268236 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=268236

View File

@ -127,6 +127,7 @@ blank_line = re.compile( r'(?m)^\s+$' )
# format, use "patch" to apply it, and then use "diff -u" to create a # format, use "patch" to apply it, and then use "diff -u" to create a
# unified format. # unified format.
# #
diff_index_filename = re.compile( r'^Index:\s+(?P<filename>.*)' ) diff_index_filename = re.compile( r'^Index:\s+(?P<filename>.*)' )
diff_newfile = re.compile( r'^\+\+\+\s(?P<filename>.*)$' ) diff_newfile = re.compile( r'^\+\+\+\s(?P<filename>.*)$' )
diff_hunk = re.compile( r'^@@ -\d+(,\d+)?\s+\+(?P<linenumber>\d+)[, ].*@@$' ) diff_hunk = re.compile( r'^@@ -\d+(,\d+)?\s+\+(?P<linenumber>\d+)[, ].*@@$' )
@ -141,6 +142,24 @@ diff_line_del = re.compile( r'^-[^-].*' )
# Note that the expression below is Y10K (and Y100K) ready. :-). # Note that the expression below is Y10K (and Y100K) ready. :-).
diff_findjunk = re.compile( r'^(?P<filename>.*)((\s\d\d\d\d+-\d\d-\d\d\s+\d\d:\d[0-9:.]+Z?(\s+[\-\+0-9A-Z]+)?)|(\s[A-Za-z][a-z]+\s[A-za-z][a-z]+\s\d+\s\d+:\d[0-9:.]+Z?(\s[\-\+0-9]*)?\s\d\d\d\d+)|(\s\(.*\)))\s*$') diff_findjunk = re.compile( r'^(?P<filename>.*)((\s\d\d\d\d+-\d\d-\d\d\s+\d\d:\d[0-9:.]+Z?(\s+[\-\+0-9A-Z]+)?)|(\s[A-Za-z][a-z]+\s[A-za-z][a-z]+\s\d+\s\d+:\d[0-9:.]+Z?(\s[\-\+0-9]*)?\s\d\d\d\d+)|(\s\(.*\)))\s*$')
def is_svn_diff(sLine):
if (sLine.find('Index:') != -1):
return True
return False
def svn_diff_get_filename(sLine):
return diff_index_filename.match(sLine)
def gnu_diff_get_filename(sLine):
newfile_match = diff_newfile.match(sLine)
if (newfile_match):
patched_filename = string.strip(newfile_match.group('filename'))
# Clean up filename - remove trailing timestamp and/or (comment).
return diff_findjunk.match(patched_filename)
return None
# For each file found in the file patch_file, keep the # For each file found in the file patch_file, keep the
# line numbers of the new file (after patch is applied) which are added. # line numbers of the new file (after patch is applied) which are added.
# We keep this information in a hash table for a quick access later. # We keep this information in a hash table for a quick access later.
@ -157,68 +176,56 @@ def load_patch_info(patch_file):
patched_filename = "" # Name of new file patched by current hunk. patched_filename = "" # Name of new file patched by current hunk.
sLine = hPatch.readline()
#Heuristic to determine if it's a svn diff or a GNU diff.
#Read the first line. If it contains 'Index:', it's a svn diff else it is a
#GNU diff.
#By default we try to get filename in svn diff
fn_get_filename=svn_diff_get_filename
if (is_svn_diff(sLine) == False):
fn_get_filename=gnu_diff_get_filename
while True: # Loop-and-half construct. Read a line, end loop when no more while True: # Loop-and-half construct. Read a line, end loop when no more
sLine = hPatch.readline()
if (sLine == ''): break # Done reading.
# This is really a sequence of if ... elsif ... elsif..., but # This is really a sequence of if ... elsif ... elsif..., but
# because Python forbids '=' in conditions, we do it this way. # because Python forbids '=' in conditions, we do it this way.
index_filename_match = diff_index_filename.match(sLine) filename_match = fn_get_filename(sLine)
if (index_filename_match): if (filename_match):
patched_filename = string.strip(index_filename_match.group('filename')) patched_filename = string.strip(filename_match.group('filename'))
index_statement = True
# Should never happen (like below):
if (patch.has_key(patched_filename) == True): if (patch.has_key(patched_filename) == True):
error("filename occurs more than once in the patch: %s" % error("filename occurs more than once in the patch: %s" %
patched_filename) patched_filename)
sys.exit(1)
else: else:
patch[patched_filename] = {} patch[patched_filename] = {}
else: else:
newfile_match = diff_newfile.match(sLine) hunk_match = diff_hunk.match(sLine)
# We'll ignore the match if patched_filename already set. This makes if (hunk_match):
# "Index:" takes precedence over "+++". We do this because "Index:" if (patched_filename == ""):
# doesn't have junk after it that might be mistaken for part error("wrong type of patch file : we have a line number without having seen a filename")
# of the filename. sys.exit(1)
if ( (not index_statement) and newfile_match): initial_number= hunk_match.group('linenumber')
patched_filename = string.strip(newfile_match.group('filename')) line_counter= 0
# Clean up filename - remove trailing timestamp and/or (comment).
findjunk_match = diff_findjunk.match(patched_filename)
if (findjunk_match):
patched_filename = string.strip(findjunk_match.group('filename'))
# Now we have the filename! Check if we've already seen it
# (we should not have), just like above:
if (patch.has_key(patched_filename)):
error("filename occurs more than once in the patch: %s" %
patched_filename)
else:
patch[patched_filename] = {}
else: else:
hunk_match = diff_hunk.match(sLine) line_added_match = diff_line_added.match(sLine)
if (hunk_match): if (line_added_match):
if (patched_filename == ""): line_added = line_counter + int(initial_number)
error("wrong type of patch file : we have a line number without having seen a filename") patch[patched_filename][line_added] = True
initial_number= hunk_match.group('linenumber') # Let's also warn about the lines above and below this one,
line_counter= 0 # so that errors that "leak" into adjacent lines are caught.
# Besides, if you're creating a patch, you had to at least look
# at adjacent lines, so you're in a position to fix them.
patch[patched_filename][line_added - 1] = True
patch[patched_filename][line_added + 1] = True
line_counter += 1
else:
line_del_match = diff_line_del.match(sLine)
if (line_del_match == None):
line_counter += 1
else: sLine = hPatch.readline()
line_added_match = diff_line_added.match(sLine) if (sLine == ''): break # Done reading.
if (line_added_match):
line_added = line_counter + int(initial_number)
patch[patched_filename][line_added] = True
# Let's also warn about the lines above and below this one,
# so that errors that "leak" into adjacent lines are caught.
# Besides, if you're creating a patch, you had to at least look
# at adjacent lines, so you're in a position to fix them.
patch[patched_filename][line_added - 1] = True
patch[patched_filename][line_added + 1] = True
line_counter += 1
else:
line_del_match = diff_line_del.match(sLine)
if (line_del_match == None):
line_counter += 1
return patch return patch
@ -1448,7 +1455,8 @@ def maybe_process_file(f, patch_infos):
if not quiet: print "Warning: skipping symbolic link directory", h(f) if not quiet: print "Warning: skipping symbolic link directory", h(f)
num_links_skipped = num_links_skipped + 1 num_links_skipped = num_links_skipped + 1
return return
if (skipdotdir and ("." == os.path.basename(f)[0])): base_filename = os.path.basename(f)
if (skipdotdir and len(base_filename) > 0 and ("." == base_filename[0])):
if not quiet: print "Warning: skipping directory with initial dot", h(f) if not quiet: print "Warning: skipping directory with initial dot", h(f)
num_dotdirs_skipped = num_dotdirs_skipped + 1 num_dotdirs_skipped = num_dotdirs_skipped + 1
return return
@ -1512,7 +1520,7 @@ flawfinder [--help] [--context] [-c] [--columns | -C] [--html]
[--dataonly | -D] [--dataonly | -D]
[--minlevel=X | -m X] [--minlevel=X | -m X]
[--immediate] [-i] [--inputs | -I] [--neverignore | -n] [--immediate] [-i] [--inputs | -I] [--neverignore | -n]
[--quiet | -Q] [--singleline | -S ] [ --patch=F ] [--quiet | -Q] [--singleline | -S ]
[--loadhitlist=F ] [ --savehitlist=F ] [ --diffhitlist=F ] [--loadhitlist=F ] [ --savehitlist=F ] [ --diffhitlist=F ]
[--listrules] [--listrules]
[--] [ source code file or source root directory ]+ [--] [ source code file or source root directory ]+