]> bicyclesonthemoon.info Git - botm/config/commitdiff
introduce masked replacement to avoid undefined behavior
authorb <rowerynaksiezycu@gmail.com>
Mon, 19 Sep 2022 21:10:59 +0000 (21:10 +0000)
committerb <rowerynaksiezycu@gmail.com>
Mon, 19 Sep 2022 21:10:59 +0000 (21:10 +0000)
configure.pl

index 68c24875bf96cfeb7e785c93fcaef66d161bbfd9..9952e8d7c41cf7a7091b3c595a0ac7ace689ca79 100755 (executable)
@@ -494,6 +494,28 @@ sub replace {
        return (1, $before.$replacement.$after);
 }
 
+# replace but with mask to avoid duplicated replacement
+sub replace_masked {
+       (my $text, my $mask, my $to_replace, my $replacement) = @_;
+       
+       my $ind = index($mask, $to_replace);
+       if ($ind <0) {
+               return (0, $text, $mask);
+       }
+       my $len = length($to_replace);
+       
+       my $text_before = substr($text, 0, $ind);
+       my $mask_before = substr($mask, 0, $ind);
+       my $mask_insert = "\r" x length($replacement); # CR can never appear in $text
+       my $text_after = substr($text, $ind+$len);
+       my $mask_after = substr($mask, $ind+$len);
+       
+       $text = $text_before.$replacement.$text_after;
+       $mask = $mask_before.$mask_insert.$mask_after;
+       
+       return (1, $text, $mask);
+}
+
 sub print_debug {
        (my $depth, my $text) = @_;
        if ($debug_enabled) {
@@ -976,9 +998,10 @@ sub convert_file {
                                next LINE;
                        }
                }
+               my $mask = $line;
                foreach my $key (keys %replace_keyword) {
                        do {
-                               ($status, $line) = replace($line, $key, $replace_keyword{$key});
+                               ($status, $line, $mask) = replace_masked($line, $mask, $key, $replace_keyword{$key});
                        } while ($status);
                }
                print $out "$line\n";