Support for the automatic configuration of the UPX dll/exe packer.
[obnox/wireshark/wip.git] / tools / checkAPIs.pl
1 #!/usr/bin/env perl
2
3 #
4 # Copyright 2006, Jeff Morriss <jeff.morriss[AT]ulticom.com>
5 #
6 # A simple tool to check source code for function calls that should not
7 # be called by Wireshark code.
8 #
9 # $Id$
10 #
11 # Wireshark - Network traffic analyzer
12 # By Gerald Combs <gerald@wireshark.org>
13 # Copyright 1998 Gerald Combs
14 #
15 # This program is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #
29
30 use strict;
31
32 # APIs that MUST NOT be used in Wireshark
33 my @prohibitedAPIs=
34 (
35         # Memory-unsafe APIs
36         # Use something that won't overwrite the end of your buffer instead
37         # of these:
38         'gets',
39         'sprintf',
40         'vsprintf',
41         'strcpy',
42         'strcat',
43         'cftime',
44         'ascftime',
45         ### non-portable APIs
46         # use glib (g_*) versions instead of these:
47         'ntohl',
48         'ntohs',
49         'htonl',
50         'htons',
51         # use ep_ or se_ functions instead of these:
52         'malloc',
53         'free',
54 );
55
56 # APIs that SHOULD NOT be used in Wireshark (any more)
57 my @deprecatedAPIs=
58 (
59         # Wireshark should not write to stdout (?)
60         # (Of course tshark should!)
61         'printf',
62         'perror',
63         # Use PROTO_ITEM_SET_HIDDEN instead of these:
64         'proto_tree_add_item_hidden',
65         'proto_tree_add_bytes_hidden',
66         'proto_tree_add_time_hidden',
67         'proto_tree_add_ipxnet_hidden',
68         'proto_tree_add_ipv4_hidden',
69         'proto_tree_add_ipv6_hidden',
70         'proto_tree_add_ether_hidden',
71         'proto_tree_add_guid_hidden',
72         'proto_tree_add_oid_hidden',
73         'proto_tree_add_string_hidden',
74         'proto_tree_add_boolean_hidden',
75         'proto_tree_add_float_hidden',
76         'proto_tree_add_double_hidden',
77         'proto_tree_add_uint_hidden',
78         'proto_tree_add_int_hidden',
79 );
80
81 # Given a list of APIs and the contents of a file, see if the API appears
82 # in the file.  If so, push the API onto the provided list.
83 sub findAPIinList($$$)
84 {
85     my ($apiList, $fileContentsRef, $foundAPIsRef)=@_;
86     
87     for my $api (@{$apiList})
88     {
89         if ($$fileContentsRef =~ m/\W$api\W*\(/)
90         {
91             push @{$foundAPIsRef},$api;
92         }
93     }
94 }
95
96 # The below Regexp are based on those from:
97 # http://aspn.activestate.com/ASPN/Cookbook/Rx/Recipe/59811
98 # They are in the public domain.
99
100 # 1. A complicated regex which matches C-style comments.
101 my $CComment = qr{/\*[^*]*\*+([^/*][^*]*\*+)*/};
102
103 # 1.a A regex that matches C++-style comments.
104 #my $CppComment = qr{//(.*?)\n};
105
106 # 2. A regex which matches double-quoted strings.
107 my $DoubleQuotedStr = qr{(?:\"(?:\\.|[^\"\\])*\")};
108
109 # 3. A regex which matches single-quoted strings.
110 my $SingleQuotedStr = qr{(?:\'(?:\\.|[^\'\\])*\')};
111
112 # 4. Now combine 1 through 3 to produce a regex which
113 #    matches _either_ double or single quoted strings
114 #    OR comments. We surround the comment-matching
115 #    regex in capturing parenthesis to store the contents
116 #    of the comment in $1.
117 #    my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)|($CppComment)};
118
119 # 4. Wireshark is strictly a C program so don't take out C++ style comments
120 #    since they shouldn't be there anyway...
121 my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)};
122
123 #
124 # MAIN
125 #
126 my $errorCount = 0;
127 while ($_ = $ARGV[0])
128 {
129         shift;
130         my $filename = $_;
131         my @foundProhibitedAPIs = ();
132         my @foundDeprecatedAPIs = ();
133
134         die "No such file: \"$filename\"" if (! -e $filename);
135
136         # delete leading './'
137         $filename =~ s@^\./@@;
138
139         # Read in the file (ouch, but it's easier that way)
140         my $fileContents = `cat $filename`;
141
142         # Remove all the C-comments and strings
143         $fileContents =~ s {$commentAndStringRegex} []g;
144
145         if ($fileContents =~ m{//})
146         {
147                 print "Error: Found C++ style comments\n";
148                 $errorCount++;
149         }
150
151         findAPIinList(\@prohibitedAPIs, \$fileContents, \@foundProhibitedAPIs);
152
153         # the use of "prohibited" APIs is an error, increment the error count
154         $errorCount += @foundProhibitedAPIs;
155
156         findAPIinList(\@deprecatedAPIs, \$fileContents, \@foundDeprecatedAPIs);
157         # (the use of deprecated APIs is bad but not an error)
158
159         print "Error: Found prohibited APIs in ".$filename.": ".join(',', @foundProhibitedAPIs)."\n" if @foundProhibitedAPIs;
160         print "Warning: Found deprecated APIs in ".$filename.": ".join(',', @foundDeprecatedAPIs)."\n" if @foundDeprecatedAPIs;
161
162 }
163
164 exit($errorCount);