#!/usr/bin/env perl # # Copyright 2006, Jeff Morriss # # A simple tool to check source code for function calls that should not # be called by Wireshark code. # # $Id$ # # Wireshark - Network traffic analyzer # By Gerald Combs # Copyright 1998 Gerald Combs # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # use strict; # APIs that MUST NOT be used in Wireshark my @prohibitedAPIs= ( # Memory-unsafe APIs # Use something that won't overwrite the end of your buffer instead # of these: 'gets', 'sprintf', 'vsprintf', 'strcpy', 'strncpy', 'strcat', 'strncat', 'cftime', 'ascftime', ### non-portable APIs # use glib (g_*) versions instead of these: 'ntohl', 'ntohs', 'htonl', 'htons', 'strdup', 'strndup', ### non-ANSI C # use memset, memcpy, memcmp instead of these: 'bzero', 'bcopy', 'bcmp', # use ep_*, se_*, or g_* functions instead of these: # (One thing to be aware of is that space allocated with malloc() # may not be freeable--at least on Windows--with g_free() and # vice-versa.) 'malloc', 'free', # Locale-unsafe APIs # These may have unexpected behaviors in some locales (e.g., # "I" isn't always the upper-case form of "i", and "i" isn't # always the lower-case form of "I"). Use the g_ascii_* version # instead. 'strcasecmp', 'strncasecmp', 'g_strcasecmp', 'g_strncasecmp', 'g_strup', 'g_strdown', 'g_string_up', 'g_string_down', # Use the ws_* version of these: # (Necessary because on Windows we use UTF8 for throughout the code # so we must tweak that to UTF16 before operating on the file. Code # using these functions will work unless the file/path name contains # non-ASCII chars.) 'open', 'rename', 'mkdir', 'stat', 'unlink', 'remove', 'fopen', 'freopen', # Misc 'tmpnam' # use mkstemp ); # APIs that SHOULD NOT be used in Wireshark (any more) my @deprecatedAPIs= ( ### Depreciated glib functions # use g_string_printf() instead of: 'g_string_sprintf', # use g_string_append_printf instead of: 'g_string_sprintfa', 'g_tree_traverse', 'g_basename', 'g_dirname', 'g_hash_table_freeze', 'g_hash_table_thaw', 'G_HAVE_GINT64', 'g_io_channel_close', 'g_io_channel_read', 'g_io_channel_seek', 'g_io_channel_write', 'g_main_new', 'g_main_destroy', 'g_main_run', 'g_main_set_poll_func', 'g_scanner_add_symbol', 'g_scanner_remove_symbol', 'g_scanner_foreach_symbol', 'g_scanner_freeze_symbol_table', 'g_scanner_thaw_symbol_table', # Wireshark should not write to stdout (?) # (Of course tshark should!) 'printf', 'perror', # Use PROTO_ITEM_SET_HIDDEN instead of these: 'proto_tree_add_item_hidden', 'proto_tree_add_bytes_hidden', 'proto_tree_add_time_hidden', 'proto_tree_add_ipxnet_hidden', 'proto_tree_add_ipv4_hidden', 'proto_tree_add_ipv6_hidden', 'proto_tree_add_ether_hidden', 'proto_tree_add_guid_hidden', 'proto_tree_add_oid_hidden', 'proto_tree_add_string_hidden', 'proto_tree_add_boolean_hidden', 'proto_tree_add_float_hidden', 'proto_tree_add_double_hidden', 'proto_tree_add_uint_hidden', 'proto_tree_add_int_hidden', ); # Given a list of APIs and the contents of a file, see if the API appears # in the file. If so, push the API onto the provided list. sub findAPIinList($$$) { my ($apiList, $fileContentsRef, $foundAPIsRef)=@_; for my $api (@{$apiList}) { if ($$fileContentsRef =~ m/\W$api\W*\(/) { push @{$foundAPIsRef},$api; } } } # The below Regexp are based on those from: # http://aspn.activestate.com/ASPN/Cookbook/Rx/Recipe/59811 # They are in the public domain. # 1. A complicated regex which matches C-style comments. my $CComment = qr{/\*[^*]*\*+([^/*][^*]*\*+)*/}; # 1.a A regex that matches C++-style comments. #my $CppComment = qr{//(.*?)\n}; # 2. A regex which matches double-quoted strings. my $DoubleQuotedStr = qr{(?:\"(?:\\.|[^\"\\])*\")}; # 3. A regex which matches single-quoted strings. my $SingleQuotedStr = qr{(?:\'(?:\\.|[^\'\\])*\')}; # 4. Now combine 1 through 3 to produce a regex which # matches _either_ double or single quoted strings # OR comments. We surround the comment-matching # regex in capturing parenthesis to store the contents # of the comment in $1. # my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)|($CppComment)}; # 4. Wireshark is strictly a C program so don't take out C++ style comments # since they shouldn't be there anyway... my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)}; # # MAIN # my $errorCount = 0; while ($_ = $ARGV[0]) { shift; my $filename = $_; my @foundProhibitedAPIs = (); my @foundDeprecatedAPIs = (); die "No such file: \"$filename\"" if (! -e $filename); # delete leading './' $filename =~ s@^\./@@; # Read in the file (ouch, but it's easier that way) my $fileContents = `cat $filename`; if ($fileContents =~ m{[\x80-\xFF]}) { print "Warning: found non-ASCII characters in " .$filename."\n"; # Treat as warning # $errorCount++; } if ($fileContents =~ m{%ll}) { # use G_GINT64_MODIFIER instead of ll print "Error: found %ll in " .$filename."\n"; $errorCount++; } if (! ($fileContents =~ m{\$Id.*\$})) { print "Warning: ".$filename." does not have an SVN Id tag.\n"; } # Remove all the C-comments and strings $fileContents =~ s {$commentAndStringRegex} []g; if ($fileContents =~ m{//}) { print "Error: Found C++ style comments in " .$filename."\n"; $errorCount++; } findAPIinList(\@prohibitedAPIs, \$fileContents, \@foundProhibitedAPIs); # the use of "prohibited" APIs is an error, increment the error count $errorCount += @foundProhibitedAPIs; findAPIinList(\@deprecatedAPIs, \$fileContents, \@foundDeprecatedAPIs); # (the use of deprecated APIs is bad but not an error) print "Error: Found prohibited APIs in ".$filename.": ".join(',', @foundProhibitedAPIs)."\n" if @foundProhibitedAPIs; print "Warning: Found deprecated APIs in ".$filename.": ".join(',', @foundDeprecatedAPIs)."\n" if @foundDeprecatedAPIs; } exit($errorCount);