]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
util/find-doc-nits: Check function macros in history
authorNorbert Pocs <norbertpocs0@gmail.com>
Tue, 22 Apr 2025 18:47:39 +0000 (20:47 +0200)
committerTomas Mraz <tomas@openssl.org>
Tue, 29 Apr 2025 17:35:49 +0000 (19:35 +0200)
Add a checker for function macros if they are present in the HISTORY
section of the man page.

Resolves: #26774

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27488)

util/find-doc-nits

index 892375a1b6a938a7fc01189f0eec3da9453db6ad..d19a364a771f2ac3eedc3a87e43274b4335e08d9 100755 (executable)
@@ -112,6 +112,61 @@ my $ignored = qr/(?| ^i2d_
                  |   ^OSSL_[BL]E(16|32|64)TOH   # undefed
                  )/x;
 
+# There are macro functions added before version 1.1.1 we don't want to track
+# in the history sections.
+my %exclude_macro_history = map { $_ => 1 } qw(
+        BIO_append_filename BIO_ctrl_dgram_connect BIO_ctrl_set_connected
+        BIO_destroy_bio_pair BIO_dgram_get_mtu BIO_dgram_get_mtu_overhead
+        BIO_dgram_get_peer BIO_dgram_recv_timedout BIO_dgram_send_timedout
+        BIO_dgram_set_peer BIO_do_accept BIO_do_connect BIO_do_handshake BIO_eof
+        BIO_flush BIO_get_accept_ip_family BIO_get_accept_name
+        BIO_get_accept_port BIO_get_app_data BIO_get_bind_mode
+        BIO_get_buffer_num_lines BIO_get_cipher_ctx BIO_get_cipher_status
+        BIO_get_close BIO_get_conn_hostname BIO_get_conn_ip_family
+        BIO_get_conn_port BIO_get_ex_new_index BIO_get_fd BIO_get_fp
+        BIO_get_info_callback BIO_get_mem_data BIO_get_mem_ptr
+        BIO_get_num_renegotiates BIO_get_peer_name BIO_get_peer_port
+        BIO_get_read_request BIO_get_ssl BIO_get_write_buf_size
+        BIO_get_write_guarantee BIO_make_bio_pair BIO_pending BIO_read_filename
+        BIO_reset BIO_rw_filename BIO_seek BIO_set_accept_bios
+        BIO_set_accept_ip_family BIO_set_accept_name BIO_set_accept_port
+        BIO_set_app_data BIO_set_bind_mode BIO_set_buffer_read_data
+        BIO_set_buffer_size BIO_set_close BIO_set_conn_hostname
+        BIO_set_conn_ip_family BIO_set_conn_port BIO_set_fd BIO_set_fp
+        BIO_set_info_callback BIO_set_md BIO_set_mem_buf BIO_set_mem_eof_return
+        BIO_set_nbio BIO_set_nbio_accept BIO_set_read_buffer_size BIO_set_ssl
+        BIO_set_ssl_mode BIO_set_ssl_renegotiate_bytes
+        BIO_set_ssl_renegotiate_timeout BIO_set_write_buf_size
+        BIO_set_write_buffer_size BIO_shutdown_wr BIO_tell BIO_wpending
+        BIO_write_filename BN_mod BN_num_bytes BN_one EVP_OpenUpdate
+        EVP_SealUpdate OPENSSL_clear_free OPENSSL_clear_realloc OPENSSL_free
+        OPENSSL_malloc OPENSSL_malloc_init OPENSSL_memdup OPENSSL_realloc
+        OPENSSL_strdup OPENSSL_strndup OPENSSL_zalloc
+        SSL_CTX_add_extra_chain_cert SSL_CTX_clear_extra_chain_certs
+        SSL_CTX_clear_mode SSL_CTX_disable_ct SSL_CTX_get_default_read_ahead
+        SSL_CTX_get_extra_chain_certs SSL_CTX_get_extra_chain_certs_only
+        SSL_CTX_get_max_cert_list SSL_CTX_get_mode SSL_CTX_get_read_ahead
+        SSL_CTX_get_session_cache_mode SSL_CTX_sess_accept
+        SSL_CTX_sess_accept_good SSL_CTX_sess_accept_renegotiate
+        SSL_CTX_sess_cache_full SSL_CTX_sess_cb_hits SSL_CTX_sess_connect
+        SSL_CTX_sess_connect_good SSL_CTX_sess_connect_renegotiate
+        SSL_CTX_sess_get_cache_size SSL_CTX_sess_hits SSL_CTX_sess_misses
+        SSL_CTX_sess_number SSL_CTX_sess_set_cache_size SSL_CTX_sess_timeouts
+        SSL_CTX_set_dh_auto SSL_CTX_set_ecdh_auto SSL_CTX_set_max_cert_list
+        SSL_CTX_set_mode SSL_CTX_set_msg_callback_arg SSL_CTX_set_read_ahead
+        SSL_CTX_set_session_cache_mode SSL_CTX_set_tlsext_servername_arg
+        SSL_CTX_set_tlsext_servername_callback SSL_CTX_set_tmp_dh
+        SSL_CTX_set_tmp_ecdh SSL_clear_mode SSL_disable_ct SSL_get_cipher
+        SSL_get_cipher_bits SSL_get_cipher_name SSL_get_cipher_version
+        SSL_get_extms_support SSL_get_max_cert_list SSL_get_mode
+        SSL_get_peer_signature_nid SSL_get_secure_renegotiation_support
+        SSL_get_server_tmp_key SSL_get_time SSL_get_timeout SSL_in_accept_init
+        SSL_in_connect_init SSL_set_dh_auto SSL_set_ecdh_auto
+        SSL_set_max_cert_list SSL_set_mode SSL_set_msg_callback_arg SSL_set_time
+        SSL_set_timeout SSL_set_tlsext_host_name SSL_set_tmp_dh SSL_set_tmp_ecdh
+        SSL_want_async SSL_want_async_job SSL_want_nothing SSL_want_read
+        SSL_want_write SSL_want_x509_lookup X509_LOOKUP_add_dir);
+
 # A common regexp for C symbol names
 my $C_symbol = qr/\b[[:alpha:]][_[:alnum:]]*\b/;
 
@@ -882,6 +937,7 @@ my %name_map = ();
 # 'other' : belongs in libcrypto or libssl (loaded from other.syms)
 # 'internal' : Internal
 # 'public' : Public (generic name or external documentation)
+# 'macro_functions' : Used to check history of macro functions
 # Any of these values except 'public' may be prefixed with 'missing_'
 # to indicate that they are known to be missing.
 my %state;
@@ -893,6 +949,13 @@ my %history;
 # 'other' : belongs in libcrypto or libssl (loaded from other.syms)
 # 'internal' : Internal
 my %missing;
+# A list of definitions which may be function names.
+# This reads util/other.syms to get the public names and checks which of them
+# are functions in `checkmacros` function
+my @history_maybe_macro_functions;
+# The list of macros found by checking defines in our header files
+# Saves the filename for error handling purposes
+my %macros_maybe_undocumented;
 
 # Parse libcrypto.num, etc., and return sorted list of what's there.
 sub loadnum ($;$) {
@@ -913,6 +976,10 @@ sub loadnum ($;$) {
                 $history{$fields[0].'(3)'} = $type.$fields[2];
             }
         }
+        if ($type && $type eq "other" && $fields[1] eq "define" &&
+            scalar @fields == 2) {
+            push(@history_maybe_macro_functions, $fields[0]);
+        }
         die "Malformed line $. in $file: $_"
             if scalar @fields != 2 && scalar @fields != 4;
         $state{$fields[0].'(3)'} = $type // 'internal';
@@ -963,12 +1030,9 @@ sub checkstate () {
     }
 }
 
-# Check for undocumented macros; ignore those in the "missing" file
-# and do simple check for #define in our header files.
+# Check for undocumented and history of macros; ignore those in the
+# "missing" file and do simple check for #define in our header files.
 sub checkmacros {
-    my $count = 0;
-    my %seen;
-
     foreach my $f ( files(TAGS => 'public_header') ) {
         # Skip some internals we don't want to document yet.
         my $b = basename($f);
@@ -980,18 +1044,36 @@ sub checkmacros {
         while ( <IN> ) {
             next unless /^#\s*define\s*(\S+)\(/;
             my $macro = "$1(3)"; # We know they're all in section 3
-            next if defined $name_map{$macro}
-                || defined $missing{$macro}
-                || defined $seen{$macro}
+
+            next if defined $missing{$macro}
+                || exists $exclude_macro_history{$1}
                 || $macro =~ /$ignored/;
 
-            err("$f:", "macro $macro undocumented")
-                if $opt_d || $opt_e;
-            $count++;
-            $seen{$macro} = 1;
+            if ($opt_i && grep {$_ eq $1} @history_maybe_macro_functions) {
+                $history{$macro} = "macro_functions";
+                $state{$macro} = "macro_functions";
+            }
+
+            next if defined $macros_maybe_undocumented{$macro};
+            
+            $macros_maybe_undocumented{$macro} = $f;
         }
         close(IN);
     }
+}
+
+# Check remaining macros against $name_map
+# This function has to be called after checkmacros
+sub checkmacros_undocumented {
+    my $count = 0;
+
+    foreach my $m ( keys %macros_maybe_undocumented ) {
+        next if defined $name_map{$m};
+        err("$macros_maybe_undocumented{$m}:", "macro $m undocumented")
+            if $opt_d || $opt_e;
+        $count++;
+    }
+
     err("# $count macros undocumented (count is approximate)")
         if $count > 0;
 }
@@ -1256,6 +1338,12 @@ if ( $opt_o ) {
     loadmissing('util/missingssl-internal.txt');
 }
 
+# Load the list of macros that are missing from history section
+# and save the remaining macros for checking of undocumentation
+if ( $opt_u || $opt_v) {
+    checkmacros();
+}
+
 if ( $opt_n || $opt_l || $opt_u || $opt_v ) {
     my @files_to_read = ( $opt_n && @ARGV ) ? @ARGV : files(TAGS => 'manual');
 
@@ -1290,7 +1378,8 @@ checkstate();
 if ( $opt_u || $opt_v) {
     printem('crypto');
     printem('ssl');
-    checkmacros();
+    checkmacros_undocumented();
+    printem('macro_functions');
 }
 
 exit $status;