Subject: [PATCH 03/18] checkbashisms: simplify mixed single/double balanced quotes correctly

From: Raphael Geissert <[email-masked]>
Date: Sun, 21 Oct 2012 00:19:30 -0500

Code like "'"'"'"'" was incorrectly simplified as ''" and then to just ",
making it believe a string was being opened.

Signed-off-by: Raphael Geissert <[email-masked]>
---
 scripts/checkbashisms.pl |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/scripts/checkbashisms.pl b/scripts/checkbashisms.pl
index 9ebc3f7..52f72b8 100755
--- a/scripts/checkbashisms.pl
+++ b/scripts/checkbashisms.pl
@@ -298,8 +298,26 @@ foreach my $filename (@ARGV) {
 		    my $otherquote = ($quote eq "\"" ? "\'" : "\"");
 
 		    # Remove balanced quotes and their content
-		    $templine =~ s/(^|[^\\\"](?:\\\\)*)\'[^\']*\'/$1/g;
-		    $templine =~ s/(^|[^\\\'](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1/g;
+		    while (1) {
+			my ($length_single, $length_double) = (0, 0);
+
+			# Determine which one would match first:
+			if ($templine =~ m/(^.+?(?:^|[^\\\"](?:\\\\)*)\')[^\']*\'/) {
+			    $length_single = length($1);
+			}
+			if ($templine =~ m/(^.*?(?:^|[^\\\'](?:\\\\)*)\")(?:\\.|[^\\\"])+\"/) {
+			    $length_double = length($1);
+			}
+
+			# Now simplify accordingly (shorter is preferred):
+			if ($length_single != 0 && ($length_single < $length_double || $length_double == 0)) {
+			    $templine =~ s/(^|[^\\\"](?:\\\\)*)\'[^\']*\'/$1/;
+			} elsif ($length_double != 0) {
+			    $templine =~ s/(^|[^\\\'](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1/;
+			} else {
+			    last;
+			}
+		    }
 
 		    # Don't flag quotes that are themselves quoted
 		    # "a'b"
-- 
1.7.10