diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2025-03-06 17:49:50 +0000 | 
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2025-03-06 17:49:50 +0000 | 
| commit | 1c34280346af8284acdc0eae39496811d37df25d (patch) | |
| tree | dbe4218057c550b3be955f331fc1198c6cab5f3f /util | |
| parent | 108164cf95d9594884c2dcccba2691335e6f221b (diff) | |
Diffstat (limited to 'util')
| -rwxr-xr-x | util/check-format-commit.sh | 193 | ||||
| -rwxr-xr-x | util/check-format.pl | 14 | ||||
| -rwxr-xr-x | util/mkbuildinf.pl | 12 | ||||
| -rw-r--r-- | util/perl/OpenSSL/Template.pm | 9 | 
4 files changed, 120 insertions, 108 deletions
diff --git a/util/check-format-commit.sh b/util/check-format-commit.sh index 7e712dc48cf6..206827dd8669 100755 --- a/util/check-format-commit.sh +++ b/util/check-format-commit.sh @@ -6,24 +6,21 @@  # You can obtain a copy in the file LICENSE in the source distribution  # or at https://www.openssl.org/source/license.html  # -# This script is a wrapper around check-format.pl.  It accepts a commit sha -# value as input, and uses it to identify the files and ranges that were -# changed in that commit, filtering check-format.pl output only to lines that -# fall into the commits change ranges. -# - - -# List of Regexes to use when running check-format.pl. -# Style checks don't apply to any of these -EXCLUDED_FILE_REGEX=("\.pod" \ -                     "\.pl"  \ -                     "\.pm"  \ -                     "\.t"   \ -                     "\.yml" \ -                     "\.sh") - -# Exit code for the script -EXIT_CODE=0 +# This script is a wrapper around check-format.pl. +# It accepts the same commit revision range as 'git diff' as arguments, +# or just a single commit id, and uses it to identify the files and line ranges +# that were changed in that commit range, filtering check-format.pl output +# only to lines that fall into the change ranges of the changed files. +# examples: +# check-format-commit.sh       # check unstaged changes +# check-format-commit.sh HEAD +# check-format-commit.sh @~3.. +# check-format-commit.sh f5981c9629667a5a5d6 +# check-format-commit.sh f5981c9629667a5a5d6..ee0bf38e8709bf71888 + +# Allowlist of files to scan +# Currently this is any .c or .h file (with an optional .in suffix) +FILE_NAME_END_ALLOWLIST=("\.[ch]\(.in\)\?")  # Global vars @@ -45,94 +42,107 @@ cleanup() {  trap cleanup EXIT -# Get the canonical sha256 sum for the commit we are checking +# Get the list of ids of the commits we are checking, +# or empty for unstaged changes.  # This lets us pass in symbolic ref names like master/etc and  -# resolve them to sha256 sums easily -COMMIT=$(git rev-parse $1) +# resolve them to commit ids easily +COMMIT_RANGE="$@" +[ -n $COMMIT_RANGE ] && COMMIT_LAST=$(git rev-parse $COMMIT_RANGE) -# Fail gracefully if git rev-parse doesn't produce a valid -# commit +# Fail gracefully if git rev-parse doesn't produce a valid commit  if [ $? -ne 0 ]  then -    echo "$1 is not a valid revision" +    echo "$1 is not a valid commit range or commit id"      exit 1  fi -# Create a iteratable list of files to check for a -# given commit. It produces output of the format -# <commit id> <file name> <change start line>, <change line count> -touch $TEMPDIR/ranges.txt -git show $COMMIT | awk -v mycmt=$COMMIT ' +# If the commit range is exactly one revision, +# git rev-parse will output just the commit id of that one alone. +# In that case, we must manipulate a little to get a desirable result, +# as 'git diff' has a slightly different interpretation of a single commit id: +# it takes that to mean all commits up to HEAD, plus any unstaged changes. +if [ $(echo -n "$COMMIT_LAST" | wc -w) -ne 1 ]; then +    COMMIT_LAST=$(echo "$COMMIT_LAST" | head -1) +else +    # $COMMIT_RANGE is just one commit, make it an actual range +    COMMIT_RANGE=$COMMIT_RANGE^..$COMMIT_RANGE +fi + +# Create an iterable list of files to check formatting on, +# including the line ranges that are changed by the commits +# It produces output of this format: +# <file name> <change start line>, <change line count> +git diff -U0 $COMMIT_RANGE | awk '      BEGIN {myfile=""}  -    /+{3}/ { -        gsub(/b\//,"",$2); -        myfile=$2 -    } -    /@@/ { -        gsub(/+/,"",$3); -        printf mycmt " " myfile " " $3 "\n" -    }' >> $TEMPDIR/ranges.txt || true - -# filter out anything that matches on a filter regex -for i in ${EXCLUDED_FILE_REGEX[@]} -do -    touch $TEMPDIR/ranges.filter -    grep -v "$i" $TEMPDIR/ranges.txt >> $TEMPDIR/ranges.filter || true -    REMAINING_FILES=$(wc -l $TEMPDIR/ranges.filter | awk '{print $1}') -    if [ $REMAINING_FILES -eq 0 ] -    then -        echo "This commit has no files that require checking" -        exit 0 -    fi -    mv $TEMPDIR/ranges.filter $TEMPDIR/ranges.txt -done +    /^\+\+\+/ { sub(/^b./,"",$2); file=$2 } +    /^@@/     { sub(/^\+/,"",$3); range=$3; printf file " " range "\n" } +    ' > $TEMPDIR/ranges.txt -# check out the files from the commit level. -# For each file name in ranges, we show that file at the commit -# level we are checking, and redirect it to the same path, relative -# to $TEMPDIR/check-format.  This give us the full file to run -# check-format.pl on with line numbers matching the ranges in the -# $TEMPDIR/ranges.txt file -for j in $(grep $COMMIT $TEMPDIR/ranges.txt | awk '{print $2}') +# filter in anything that matches on a filter regex +for i in ${FILE_NAME_END_ALLOWLIST[@]}  do -    FDIR=$(dirname $j) -    mkdir -p $TEMPDIR/check-format/$FDIR -    git show $COMMIT:$j > $TEMPDIR/check-format/$j +    # Note the space after the $i below.  This is done because we want +    # to match on file name suffixes, but the input file is of the form +    # <commit> <file path> <range start>, <range length> +    # So we can't just match on end of line.  The additional space +    # here lets us match on suffixes followed by the expected space +    # in the input file +    grep "$i " $TEMPDIR/ranges.txt >> $TEMPDIR/ranges.filter || true  done -# Now for each file in $TEMPDIR/check-format run check-format.pl -# Note that we use the %P formatter in the find utilty.  This strips -# off the $TEMPDIR/check-format path prefix, leaving $j with the -# path to the file relative to the root of the source dir, so that  -# output from check-format.pl looks correct, relative to the root -# of the git tree. -for j in $(find $TEMPDIR/check-format -type f -printf "%P\n") +REMAINING_FILES=$(wc -l <$TEMPDIR/ranges.filter) +if [ $REMAINING_FILES -eq 0 ] +then +    echo "The given commit range has no C source file changes that require checking" +    exit 0 +fi + +# unless checking the format of unstaged changes, +# check out the files from the commit range. +if [ -n "$COMMIT_RANGE" ] +then +    # For each file name in ranges, we show that file at the commit range +    # we are checking, and redirect it to the same path, +    # relative to $TEMPDIR/check-format. +    # This give us the full file path to run check-format.pl on +    # with line numbers matching the ranges in the $TEMPDIR/ranges.filter file +    for j in $(awk '{print $1}' $TEMPDIR/ranges.filter | sort -u) +    do +        FDIR=$(dirname $j) +        mkdir -p $TEMPDIR/check-format/$FDIR +        git show $COMMIT_LAST:$j > $TEMPDIR/check-format/$j +    done +fi + +# Now for each file in $TEMPDIR/ranges.filter, run check-format.pl +for j in $(awk '{print $1}' $TEMPDIR/ranges.filter | sort -u)  do      range_start=()      range_end=()      # Get the ranges for this file. Create 2 arrays.  range_start contains      # the start lines for valid ranges from the commit.  the range_end array -    # contains the corresponding end line (note, since diff output gives us +    # contains the corresponding end line.  Note, since diff output gives us      # a line count for a change, the range_end[k] entry is actually      # range_start[k]+line count -    for k in $(grep $COMMIT $TEMPDIR/ranges.txt | grep $j | awk '{print $3}') +    for k in $(grep ^$j $TEMPDIR/ranges.filter | awk '{print $2}')      do -        RANGE=$k -        RSTART=$(echo $RANGE | awk -F',' '{print $1}') -        RLEN=$(echo $RANGE | awk -F',' '{print $2}') +        RSTART=$(echo $k | awk -F',' '{print $1}') +        RLEN=$(echo $k | awk -F',' '{print $2}') +        # when the hunk is just one line, its length is implied +        if [ -z "$RLEN" ]; then RLEN=1; fi          let REND=$RSTART+$RLEN          range_start+=($RSTART)          range_end+=($REND)      done -    # Go to our checked out tree -    cd $TEMPDIR/check-format +    # Go to our checked out tree, unless checking unstaged changes +    [ -n "$COMMIT_RANGE" ] && cd $TEMPDIR/check-format      # Actually run check-format.pl on the file, capturing the output -    # in a temporary file.  Note the format of check-patch.pl output is -    # <file name>:<line number>:<error text>:<offending line contents> -    $TOPDIR/util/check-format.pl $j > $TEMPDIR/format-results.txt +    # in a temporary file.  Note the format of check-format.pl output is +    # <file path>:<line number>:<error text>:<offending line contents> +    $TOPDIR/util/check-format.pl $j > $TEMPDIR/results.txt      # Now we filter the check-format.pl output based on the changed lines      # captured in the range_start/end arrays @@ -146,26 +156,15 @@ do          # Check here if any line in that output falls between any of the           # start/end ranges defined in the range_start/range_end array.          # If it does fall in that range, print the entire line to stdout -        # If anything is printed, have awk exit with a non-zero exit code          awk -v rstart=$RSTART -v rend=$REND -F':' ' -                BEGIN {rc=0} -                /:/ { -                    if (($2 >= rstart) && ($2 <= rend)) { -                        print $0; -                        rc=1 -                    } -                } -                END {exit rc;} -            ' $TEMPDIR/format-results.txt - -        # If awk exited with a non-zero code, this script will also exit -        # with a non-zero code -        if [ $? -ne 0 ] -        then -            EXIT_CODE=1 -        fi +                /:/ { if (rstart <= $2 && $2 <= rend) print $0 } +            ' $TEMPDIR/results.txt >>$TEMPDIR/results-filtered.txt      done  done +cat $TEMPDIR/results-filtered.txt -# Exit with the recorded exit code above -exit $EXIT_CODE +# If any findings were in range, exit with a different error code +if [ -s $TEMPDIR/results-filtered.txt ] +then +    exit 2 +fi diff --git a/util/check-format.pl b/util/check-format.pl index ef2c1920e722..559b9023d08c 100755 --- a/util/check-format.pl +++ b/util/check-format.pl @@ -791,7 +791,7 @@ while (<>) { # loop over all lines of all input files          # treat remaining blinded comments and string literal contents as (single) space during matching below          $intra_line =~ s/@+/ /g;                     # note that extra SPC has already been handled above          $intra_line =~ s/\s+$//;                     # strip any (resulting) space at EOL -        # replace ';;' or '; ;' by ';' in "for(;;)" and in "for (...)" unless "..." contains just SPC and ';' characters: +        # replace ';;' or '; ;' by ';' in "for (;;)" and in "for (...)" unless "..." contains just SPC and ';' characters:          $intra_line =~ s/((^|\W)for\s*\()([^;]*?)(\s*)(;\s?);(\s*)([^;]*)(\))/            "$1$3$4".("$3$4$5$6$7" eq ";" || $3 ne "" || $7 ne "" ? "" : $5).";$6$7$8"/eg;          # strip trailing ';' or '; ' in "for (...)" except in "for (;;)" or "for (;; )": @@ -904,7 +904,7 @@ while (<>) { # loop over all lines of all input files          # handle opening brace '{' after if/else/while/for/switch/do on line before          if ($hanging_offset > 0 && m/^[\s@]*{/ && # leading opening '{'              $line_before > 0 && -            $contents_before_ =~ m/(^|^.*\W)(if|else|while|for|switch|do)(\W.*$|$)/) { +            $contents_before_ =~ m/(^|^.*\W)(if|else|while|for|(OSSL_)?LIST_FOREACH(_\w+)?|switch|do)(\W.*$|$)/) {              $keyword_opening_brace = $1;              $hanging_offset -= INDENT_LEVEL; # cancel newly hanging_offset          } @@ -966,7 +966,7 @@ while (<>) { # loop over all lines of all input files      my $outermost_level = $block_indent - $preproc_offset == 0; -    report("more than one stmt") if !m/(^|\W)for(\W.*|$)/ && # no 'for' - TODO improve matching +    report("more than one stmt") if !m/(^|\W)(for|(OSSL_)?LIST_FOREACH(_\w+)?)(\W.*|$)/ && # no 'for' - TODO improve matching          m/;.*;/; # two or more terminators ';', so more than one statement      # check for code block containing a single line/statement @@ -1004,7 +1004,7 @@ while (<>) { # loop over all lines of all input files      my $assignment_start = 0;      my $tmp = $_;      $tmp =~ s/[\!<>=]=/@@/g; # blind (in-)equality symbols like '<=' as '@@' to prevent matching them as '=' below -    if      (m/^((^|.*\W)(if|while|for|switch))(\W.*|$)$/) { # (last) if/for/while/switch +    if      (m/^((^|.*\W)(if|while|for|(OSSL_)?LIST_FOREACH(_\w+)?|switch))(\W.*|$)$/) { # (last) if/for/while/switch          $paren_expr_start = 1;      } elsif (m/^((^|.*\W)(return|enum))(\W.*|$)/             # (last) return/enum          && !$in_expr && @nested_indents == 0 && parens_balance($1) == 0) { # not nested enum @@ -1135,7 +1135,7 @@ while (<>) { # loop over all lines of all input files                      $line_body_start = $contents =~ m/LONG BODY/ ? 0 : $line if $line_function_start != 0;                  }              } else { -                $line_opening_brace = $line if $keyword_opening_brace =~ m/if|do|while|for/; +                $line_opening_brace = $line if $keyword_opening_brace =~ m/if|do|while|for|(OSSL_)?LIST_FOREACH(_\w+)?/;                  # using, not assigning, $keyword_opening_brace here because it could be on an earlier line                  $line_opening_brace = $line if $keyword_opening_brace eq "else" && $extended_1_stmt &&                  # TODO prevent false positives for if/else where braces around single-statement branches @@ -1148,11 +1148,11 @@ while (<>) { # loop over all lines of all input files          }      } -    # check for opening brace after if/while/for/switch/do not on same line +    # check for opening brace after if/while/for/switch/do missing on same line      # note that "missing '{' on same line after '} else'" is handled further below      if (/^[\s@]*{/ && # leading '{'          $line_before > 0 && !($contents_before_ =~ m/^\s*#/) && # not preprocessor directive '#if -        (my ($head, $mid, $tail) = ($contents_before_ =~ m/(^|^.*\W)(if|while|for|switch|do)(\W.*$|$)/))) { +        (my ($head, $mid, $tail) = ($contents_before_ =~ m/(^|^.*\W)(if|while|for|(OSSL_)?LIST_FOREACH(_\w+)?|switch|do)(\W.*$|$)/))) {          my $brace_after  = $tail =~ /^[\s@]*{/; # any whitespace or comments then '{'          report("'{' not on same line as preceding '$mid'") if !$brace_after;      } diff --git a/util/mkbuildinf.pl b/util/mkbuildinf.pl index 1c273872be11..799ed3cdcd09 100755 --- a/util/mkbuildinf.pl +++ b/util/mkbuildinf.pl @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -9,17 +9,21 @@  use strict;  use warnings; -my ($cflags, $platform) = @ARGV; +my $platform = pop @ARGV; +my $cflags = join(' ', @ARGV); +$cflags =~ s(\\)(\\\\)g;  $cflags = "compiler: $cflags"; -my $date = gmtime($ENV{'SOURCE_DATE_EPOCH'} || time()) . " UTC"; +# Use the value of the envvar SOURCE_DATE_EPOCH, even if it's +# zero or the empty string. +my $date = gmtime($ENV{'SOURCE_DATE_EPOCH'} // time()) . " UTC";  print <<"END_OUTPUT";  /*   * WARNING: do not edit!   * Generated by util/mkbuildinf.pl   * - * Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy diff --git a/util/perl/OpenSSL/Template.pm b/util/perl/OpenSSL/Template.pm index 7411dd8ae8d7..ad93278ca761 100644 --- a/util/perl/OpenSSL/Template.pm +++ b/util/perl/OpenSSL/Template.pm @@ -42,6 +42,14 @@ use Text::Template 1.46;  our @ISA = qw(Text::Template);  # parent +sub tmpl_error { +    my (%err_dict) = @_; + +    $ERROR = $err_dict{"error"}; + +    return undef; +} +  sub new {      my $class = shift; @@ -66,6 +74,7 @@ sub fill_in {                                      output_on => sub { $self->output_on() },                                      output_off => sub { $self->output_off() },                                      %hash }, +                          BROKEN => \&tmpl_error,                            %opts);  }  | 
