Add --ignore-flag and --ignore-line options.
authorSimon Ruderich <simon@ruderich.org>
Tue, 10 Apr 2012 22:23:20 +0000 (00:23 +0200)
committerSimon Ruderich <simon@ruderich.org>
Tue, 10 Apr 2012 22:23:20 +0000 (00:23 +0200)
MANIFEST
bin/blhc
t/logs/ignore-flag [new file with mode: 0644]
t/logs/ignore-line [new file with mode: 0644]
t/tests.t

index d6c38b36511b7df62735e77ab3cd637602ae4834..4df8ddba3d3bea462727469fe61b65e8cb682111 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -36,6 +36,8 @@ t/logs/good-bindnow
 t/logs/good-library
 t/logs/good-multiline
 t/logs/good-pie
+t/logs/ignore-flag
+t/logs/ignore-line
 t/logs/libtool
 t/logs/make
 t/logs/verbose-build
index 38466e4cca55187111ec244577cd12461dc384ad..87a798810773fda45e7404de658b2a2ddbb4fe22 100755 (executable)
--- a/bin/blhc
+++ b/bin/blhc
@@ -426,6 +426,8 @@ my $option_help    = 0;
 my $option_version = 0;
 my $option_pie     = 0;
 my $option_bindnow = 0;
+my @option_ignore_flag = ();
+my @option_ignore_line = ();
 my $option_all     = 0;
 my $option_arch    = undef;
 my $option_buildd  = 0;
@@ -437,6 +439,9 @@ if (not Getopt::Long::GetOptions(
             'pie'      => \$option_pie,
             'bindnow'  => \$option_bindnow,
             'all'      => \$option_all,
+            # Ignore.
+            'ignore-flag=s' => \@option_ignore_flag,
+            'ignore-line=s' => \@option_ignore_line,
             # Misc.
             'color'    => \$option_color,
             'arch=s'   => \$option_arch,
@@ -480,16 +485,36 @@ if ($option_all) {
     $option_bindnow = 1;
 }
 
+# Strip flags which should be ignored.
+if (scalar @option_ignore_flag > 0) {
+    my %ignores = map { $_ => 1 } @option_ignore_flag;
+    foreach my $flags (@flag_refs) {
+        @{$flags} = grep {
+            # Flag found as string.
+            not exists $ignores{$_}
+            # Flag found as string representation of regexp.
+                and (not defined $flag_renames{$_}
+                        or not exists $ignores{$flag_renames{$_}})
+            } @{$flags};
+    }
+}
+
 # Precompile all flag regexps. any_flags_used(), all_flags_used() get a lot
 # faster with this.
 foreach my $flags (@flag_refs_all) {
     @{$flags} = compile_flag_regexp(\%flag_renames, @{$flags});
 }
 
+# Precompile ignore line regexps, also anchor at beginning and end of line.
+foreach my $ignore (@option_ignore_line) {
+    $ignore = qr/^$ignore$/;
+}
+
 # Final exit code.
 my $exit = 0;
 
-FILE: foreach my $file (@ARGV) {
+FILE:
+foreach my $file (@ARGV) {
     print "checking '$file'...\n" if scalar @ARGV > 1;
 
     open my $fh, '<', $file or die "$!: $file";
@@ -726,9 +751,15 @@ FILE: foreach my $file (@ARGV) {
         @ldflags = (@ldflags, @def_ldflags_bindnow);
     }
 
+LINE:
     for (my $i = 0; $i < scalar @input; $i++) {
         my $line = $input[$i];
 
+        # Ignore line if requested.
+        foreach my $ignore (@option_ignore_line) {
+            next LINE if $line =~ /$ignore/;
+        }
+
         my $skip = 0;
         if (is_non_verbose_build($line, $input[$i + 1], \$skip)) {
             if (not $option_buildd) {
@@ -981,6 +1012,23 @@ Don't require Term::ANSIColor.
 
 Use colored (ANSI) output for warning messages.
 
+=item B<--ignore-flag> I<flag>
+
+Don't print an error when the specific flag is missing in a compiler line.
+I<flag> is a string.
+
+Used to prevent false positives. This option can be specified multiple times.
+
+=item B<--ignore-line> I<regex>
+
+Ignore lines matching the given Perl regex. I<regex> is automatically anchored
+at the beginning and end of the line to prevent false negatives.
+
+B<NOTE>: Not the input lines are checked, but the lines which are displayed in
+warnings (which have line continuation resolved).
+
+Used to prevent false positives. This option can be specified multiple times.
+
 =item B<--pie>
 
 Force check for all +pie hardening flags. By default it's auto detected.
diff --git a/t/logs/ignore-flag b/t/logs/ignore-flag
new file mode 100644 (file)
index 0000000..ac24322
--- /dev/null
@@ -0,0 +1,5 @@
+dpkg-buildpackage: source package test
+
+gcc -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-a.c
+gcc    -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-b.c
+gcc -g     -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-c.c
diff --git a/t/logs/ignore-line b/t/logs/ignore-line
new file mode 100644 (file)
index 0000000..e1c6c7e
--- /dev/null
@@ -0,0 +1,10 @@
+dpkg-buildpackage: source package test
+
+    ./prepare-script gcc test-a.c test-b.c test-c.c
+
+./prepare-script gcc test-a.c
+gcc -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-a.c
+./prepare-script gcc test-b.c
+gcc -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-b.c
+./prepare-script gcc test-c.c
+gcc -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-c.c
index d9c15c311f23ee4dfb0c61682e9385293eced2e9..e238b1ad58aa188ec45cc51ef02c487f82b821ff 100644 (file)
--- a/t/tests.t
+++ b/t/tests.t
@@ -19,7 +19,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 122;
+use Test::More tests => 130;
 
 
 sub is_blhc {
@@ -71,6 +71,28 @@ is_blhc 'arch-avr32', '--color', 8,
 ";
 
 
+# Ignore missing compiler flags.
+
+is_blhc 'ignore-flag', '--ignore-flag -g', 8,
+        'CFLAGS missing (-O2): gcc -g     -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -c test-c.c
+';
+
+is_blhc 'ignore-flag', '--ignore-flag -g --ignore-flag -O2', 0,
+        '';
+
+
+# Ignore certain lines.
+
+is_blhc 'ignore-line', '--ignore-line "\./prepare-script gcc test-[a-z]\.c"', 8,
+        'CFLAGS missing (-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security):     ./prepare-script gcc test-a.c test-b.c test-c.c
+CPPFLAGS missing (-D_FORTIFY_SOURCE=2):     ./prepare-script gcc test-a.c test-b.c test-c.c
+LDFLAGS missing (-Wl,-z,relro):     ./prepare-script gcc test-a.c test-b.c test-c.c
+';
+
+is_blhc 'ignore-line', '--ignore-line "\./prepare-script gcc test-[a-z]\.c" --ignore-line "\s*\./prepare-script gcc test-[a-z]\.c .+"', 0,
+        '';
+
+
 # Correct build logs.
 
 is_blhc 'good', '', 0,