]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Require a proof of suitable snprintf(3) implementation. 1031/head
authorDenis Ovsienko <[email protected]>
Mon, 30 Jan 2023 20:31:20 +0000 (20:31 +0000)
committerDenis Ovsienko <[email protected]>
Thu, 16 Feb 2023 20:55:56 +0000 (20:55 +0000)
My earlier commit fbd4415 did a wrong thing because it caused a failure
to fail in "make check" on Solaris 9, whereas the right thing to do when
printf() does not work as expected would be to fail the build with a
useful error message.   Implement that by testing snprintf() in Autoconf
and CMake (assume that in a given libc implementation all functions in
the printf() family have the same level of support for conversion
specifications).  Return 18 tests from the conditional space back into
TESTLIST.

CHANGES
CMakeLists.txt
configure.ac
doc/README.solaris.md
tests/TESTLIST
tests/printf_z.tests [deleted file]

diff --git a/CHANGES b/CHANGES
index 10a48e3de5407986045bc8916fef918b326ec8e8..08139588c4ab5818807ad80444ed2421e8c39e98 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -45,6 +45,8 @@ DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
       Add a configure option to help debugging (--enable-instrument-functions)
       autoconf: Add autogen.sh, remove configure and config.h.in and put
         these generated files in the release tarball.
+      At build time require a proof of suitable snprintf(3) implementation in
+        libc (and document Solaris 9 as unsupported because of that).
 
 DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
   Summary for 4.99.4 tcpdump release (so far!)
index 52c039f2bfb561cdd47f0a497e564ca2b4142db8..2cfe40e97cb8695d8ff069b35b1066276c33a0a7 100644 (file)
@@ -419,6 +419,58 @@ if(NOT HAVE_SNPRINTF)
     message(FATAL_ERROR "snprintf() is required but wasn't found")
 endif()
 
+#
+# Require a proof of suitable snprintf(3), same as in Autoconf.
+#
+include(CheckCSourceRuns)
+check_c_source_runs("
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+
+int main()
+{
+  char buf[100];
+  uint64_t t = (uint64_t)1 << 32;
+
+  snprintf(buf, sizeof(buf), \"%zu\", sizeof(buf));
+  if (strncmp(buf, \"100\", sizeof(buf)))
+    return 1;
+
+  snprintf(buf, sizeof(buf), \"%zd\", -sizeof(buf));
+  if (strncmp(buf, \"-100\", sizeof(buf)))
+    return 2;
+
+  snprintf(buf, sizeof(buf), \"%\" PRId64, -t);
+  if (strncmp(buf, \"-4294967296\", sizeof(buf)))
+    return 3;
+
+  snprintf(buf, sizeof(buf), \"0o%\" PRIo64, t);
+  if (strncmp(buf, \"0o40000000000\", sizeof(buf)))
+    return 4;
+
+  snprintf(buf, sizeof(buf), \"0x%\" PRIx64, t);
+  if (strncmp(buf, \"0x100000000\", sizeof(buf)))
+    return 5;
+
+  snprintf(buf, sizeof(buf), \"%\" PRIu64, t);
+  if (strncmp(buf, \"4294967296\", sizeof(buf)))
+    return 6;
+
+  return 0;
+}
+
+"
+    SUITABLE_SNPRINTF
+)
+if(NOT SUITABLE_SNPRINTF)
+    message(FATAL_ERROR
+"The snprintf(3) implementation in this libc is not suitable,
+tcpdump would not work correctly even if it managed to compile."
+    )
+endif()
+
 check_function_exists(getopt_long HAVE_GETOPT_LONG)
 check_function_exists(setlinebuf HAVE_SETLINEBUF)
 #
index 890e9e0dcfea81828711ad4e9276caa8c3280924..73e5f79f87ded819ebc3168815a7770c83ace6f3 100644 (file)
@@ -433,21 +433,58 @@ AC_CHECK_FUNC(snprintf,,
     AC_MSG_ERROR([snprintf() is required but wasn't found]))
 
 #
-# Define HAVE_NO_PRINTF_Z to make it possible to disable test cases that
-# depend on %zu.
+# It became apparent at some point that using a suitable C99 compiler does not
+# automatically mean snprintf(3) implementation in the libc supports all the
+# modifiers and specifiers used in the project, so let's test that before the
+# build, not after.
 #
-AC_MSG_CHECKING([whether printf(3) supports the z length modifier])
+# Testing the sizeof_t length modifier takes making an snprintf() call and
+# comparing the actual result with the expected result.  If this fails, it will
+# most likely happen at run time, not compile time.
+#
+# Testing the 64-bit conversion specifiers in addition to that requires the
+# <inttypes.h> header to be present and the macros to be defined, so if this
+# fails, it will more likely happen at compile time.
+#
+AC_MSG_CHECKING([whether snprintf is suitable])
 AC_RUN_IFELSE(
     [
         AC_LANG_SOURCE([[
 #include <stdio.h>
 #include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
 
 int main()
 {
   char buf[100];
+  uint64_t t = (uint64_t)1 << 32;
+
   snprintf(buf, sizeof(buf), "%zu", sizeof(buf));
-  return strncmp(buf, "100", sizeof(buf)) ? 1 : 0;
+  if (strncmp(buf, "100", sizeof(buf)))
+    return 1;
+
+  snprintf(buf, sizeof(buf), "%zd", -sizeof(buf));
+  if (strncmp(buf, "-100", sizeof(buf)))
+    return 2;
+
+  snprintf(buf, sizeof(buf), "%" PRId64, -t);
+  if (strncmp(buf, "-4294967296", sizeof(buf)))
+    return 3;
+
+  snprintf(buf, sizeof(buf), "0o%" PRIo64, t);
+  if (strncmp(buf, "0o40000000000", sizeof(buf)))
+    return 4;
+
+  snprintf(buf, sizeof(buf), "0x%" PRIx64, t);
+  if (strncmp(buf, "0x100000000", sizeof(buf)))
+    return 5;
+
+  snprintf(buf, sizeof(buf), "%" PRIu64, t);
+  if (strncmp(buf, "4294967296", sizeof(buf)))
+    return 6;
+
+  return 0;
 }
         ]])
     ],
@@ -456,8 +493,9 @@ int main()
     ],
     [
         AC_MSG_RESULT(no)
-        AC_DEFINE(HAVE_NO_PRINTF_Z, 1,
-            [Define to 1 if printf(3) does not support the z length modifier.])
+        AC_MSG_ERROR(
+[The snprintf(3) implementation in this libc is not suitable,
+tcpdump would not work correctly even if it managed to compile.])
     ],
     [
         AC_MSG_RESULT(not while cross-compiling)
index afdd8f7356e1ddf10cd6a2fb33f75abb155c3fbe..86571e21ae112b0de26485ed8e7a0516b8c4fccd 100644 (file)
@@ -39,3 +39,8 @@ developer/gcc
 developer/llvm/clang
 ENDOFTEXT
 ```
+
+## Solaris 9
+
+This version of this OS is not supported because the snprintf(3) implementation
+in its libc is not suitable.
index 0f300a6dab905742c2a6edfa77a191a2d956e231..e14099aa609f62d8df59da57a6d862bde98e626c 100644 (file)
@@ -128,15 +128,15 @@ mpls-over-udp  mpls-over-udp.pcap  mpls-over-udp.out
 mpls-over-udp-v  mpls-over-udp.pcap  mpls-over-udp-v.out -v
 
 # OSPF tests
-# In printf_z.tests:
-# ospf-gmpls
-# ospf-nssa-bitnt
-# ospf3_ah-vv
-# ospf3_bc-vv
-# ospf3_mp-vv
-# ospf3_nbma-vv
-# ospf2-seg-fault-1-v (fuzzed pcap)
+ospf-gmpls     ospf-gmpls.pcap                         ospf-gmpls.out          -v
+ospf-nssa-bitnt        ospf-nssa-bitnt.pcap                    ospf-nssa-bitnt.out     -v
+ospf3_ah-vv    OSPFv3_with_AH.pcap                     ospf3_ah-vv.out         -v -v
 ospf3_auth-vv  ospf3_auth.pcapng                       ospf3_auth-vv.out       -v -v
+ospf3_bc-vv    OSPFv3_broadcast_adjacency.pcap         ospf3_bc-vv.out         -v -v
+ospf3_mp-vv    OSPFv3_multipoint_adjacencies.pcap      ospf3_mp-vv.out         -v -v
+ospf3_nbma-vv  OSPFv3_NBMA_adjacencies.pcap            ospf3_nbma-vv.out       -v -v
+# fuzzed pcap
+ospf2-seg-fault-1-v  ospf2-seg-fault-1.pcapng  ospf2-seg-fault-1-v.out  -v
 
 # IKEv2 tests
 ikev2four      ikev2four.pcap          ikev2four.out   -v
@@ -313,8 +313,7 @@ geonet_v0_and_calm_fast     geonet_v0_and_calm_fast.pcap    geonet_v0_and_calm_fast.out
 
 # M3UA tests
 m3ua isup.pcap isup.out
-# In printf_z.tests:
-# m3ua-vv
+m3ua-vv isup.pcap isupvv.out -vv
 
 # NFLOG test case
 nflog-e nflog.pcap nflog-e.out -e
@@ -399,8 +398,7 @@ isis-seg-fault-3-v isis-seg-fault-3.pcapng isis-seg-fault-3-v.out -v
 isis_sid       isis_sid.pcap                   isis_sid.out    -v
 
 # RSVP tests
-# In printf_z.tests:
-# rsvp_infloop-v
+rsvp_infloop-v rsvp-infinite-loop.pcap         rsvp_infloop-v.out      -v
 rsvp_cap       rsvp_cap.pcap                   rsvp_cap.out            -v
 # fuzzed pcap
 rsvp-inf-loop-2-v rsvp-inf-loop-2.pcapng       rsvp-inf-loop-2-v.out -v
@@ -412,8 +410,7 @@ hdlc3       HDLC.pcap               hdlc3.out
 hdlc4  hdlc_slarp.pcapng       hdlc4.out
 
 # DECnet test case
-# In printf_z.tests:
-# decnet
+decnet         DECnet_Phone.pcap       decnet.out
 
 # RADIUS tests
 radius-v       RADIUS.pcap     radius-v.out    -v
@@ -635,16 +632,14 @@ icmp-cksum-oobr-3 icmp-cksum-oobr-3.pcapng        icmp-cksum-oobr-3.out   -vvv -e
 icmp-cksum-oobr-4      icmp-cksum-oobr-4.pcapng        icmp-cksum-oobr-4.out   -vvv -e
 tok2str-oobr-1         tok2str-oobr-1.pcap             tok2str-oobr-1.out      -vvv -e
 tok2str-oobr-2         tok2str-oobr-2.pcap             tok2str-oobr-2.out      -vvv -e
-# In printf_z.tests:
-#eigrp-tlv-oobr
+eigrp-tlv-oobr         eigrp-tlv-oobr.pcap             eigrp-tlv-oobr.out      -vvv -e
 zephyr-oobr            zephyr-oobr.pcap                zephyr-oobr.out         -vvv -e
 isakmp-no-none-np      isakmp-no-none-np.pcapng        isakmp-no-none-np.out   -vvv -e
 telnet-iac-check-oobr  telnet-iac-check-oobr.pcap      telnet-iac-check-oobr.out       -vvv -e
 resp_4_infiniteloop    resp_4_infiniteloop.pcapng      resp_4_infiniteloop.out -vvv -e
 dns_fwdptr             dns_fwdptr.pcap                 dns_fwdptr.out          -vvv -e
-# In printf_z.tests:
-# isis-areaaddr-oobr-1
-# isis-areaaddr-oobr-2
+isis-areaaddr-oobr-1   isis-areaaddr-oobr-1.pcap       isis-areaaddr-oobr-1.out                -vvv -e
+isis-areaaddr-oobr-2   isis-areaaddr-oobr-2.pcap       isis-areaaddr-oobr-2.out                -vvv -e
 isis-extd-ipreach-oobr isis-extd-ipreach-oobr.pcap     isis-extd-ipreach-oobr.out              -vvv -e
 lldp-infinite-loop-1   lldp-infinite-loop-1.pcap       lldp-infinite-loop-1.out                -vvv -e
 lldp-infinite-loop-2   lldp-infinite-loop-2.pcap       lldp-infinite-loop-2.out                -vvv -e
@@ -662,8 +657,7 @@ juniper_es_oobr             juniper_es_oobr.pcap            juniper_es_oobr.out     -vvv -e
 
 # bad packets from Yannick Formaggio
 l2tp-avp-overflow      l2tp-avp-overflow.pcap          l2tp-avp-overflow.out   -v
-# In printf_z.tests:
-# pktap-heap-overflow
+pktap-heap-overflow    pktap-heap-overflow.pcap        pktap-heap-overflow.out -v
 wb-oobr                        wb-oobr.pcap                    wb-oobr.out     -v
 
 # bad packets from Bhargava Shastry
@@ -804,10 +798,9 @@ nfs-cannot-pad-32-bit nfs-cannot-pad-32-bit.pcap nfs-cannot-pad-32-bit.out
 #
 # See http://marc.info/?l=tcpdump-workers&m=95552439022555
 #
-# In printf_z.tests:
-# dns-zlip-1
-# dns-zlip-2
-# dns-zlip-3
+dns-zlip-1             dns-zlip-1.pcap         dns-zlip-1.out
+dns-zlip-2             dns-zlip-2.pcap         dns-zlip-2.out
+dns-zlip-3             dns-zlip-3.pcap         dns-zlip-3.out
 
 # NTP tests
 ntp                    ntp.pcap                ntp.out
@@ -868,8 +861,7 @@ arista-ether-ev          arista_ether.pcap        arista_ether-ev.out      -ev
 huge-tipc-messages     huge-tipc-messages.pcap huge-tipc-messages.out
 
 # CVE-2018-10105 bad packets from Luis Rocha
-# In printf_z.tests:
-# sflow_print-segv
+sflow_print-segv sflow_print-segv.pcap sflow_print-segv.out -v
 # two more in smb.tests
 
 #ptp tests
diff --git a/tests/printf_z.tests b/tests/printf_z.tests
deleted file mode 100644 (file)
index a08199d..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-# -*- perl -*-
-
-$testlist = [
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf-gmpls',
-        input => 'ospf-gmpls.pcap',
-        output => 'ospf-gmpls.out',
-        args   => '-v'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf-nssa-bitnt',
-        input => 'ospf-nssa-bitnt.pcap',
-        output => 'ospf-nssa-bitnt.out',
-        args   => '-v'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf3_ah-vv',
-        input => 'OSPFv3_with_AH.pcap',
-        output => 'ospf3_ah-vv.out',
-        args   => '-vv'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf3_bc-vv',
-        input => 'OSPFv3_broadcast_adjacency.pcap',
-        output => 'ospf3_bc-vv.out',
-        args   => '-vv'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf3_mp-vv',
-        input => 'OSPFv3_multipoint_adjacencies.pcap',
-        output => 'ospf3_mp-vv.out',
-        args   => '-vv'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf3_nbma-vv',
-        input => 'OSPFv3_NBMA_adjacencies.pcap',
-        output => 'ospf3_nbma-vv.out',
-        args   => '-vv'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'ospf2-seg-fault-1-v',
-        input => 'ospf2-seg-fault-1.pcapng',
-        output => 'ospf2-seg-fault-1-v.out',
-        args   => '-v'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'm3ua-vv',
-        input => 'isup.pcap',
-        output => 'isupvv.out',
-        args   => '-vv'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'rsvp_infloop-v',
-        input => 'rsvp-infinite-loop.pcap',
-        output => 'rsvp_infloop-v.out',
-        args   => '-v'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'decnet',
-        input => 'DECnet_Phone.pcap',
-        output => 'decnet.out',
-        args   => ''
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'eigrp-tlv-oobr',
-        input => 'eigrp-tlv-oobr.pcap',
-        output => 'eigrp-tlv-oobr.out',
-        args   => '-vvv -e'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'isis-areaaddr-oobr-1',
-        input => 'isis-areaaddr-oobr-1.pcap',
-        output => 'isis-areaaddr-oobr-1.out',
-        args   => '-vvv -e'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'isis-areaaddr-oobr-2',
-        input => 'isis-areaaddr-oobr-2.pcap',
-        output => 'isis-areaaddr-oobr-2.out',
-        args   => '-vvv -e'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'pktap-heap-overflow',
-        input => 'pktap-heap-overflow.pcap',
-        output => 'pktap-heap-overflow.out',
-        args   => '-v'
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'dns-zlip-1',
-        input => 'dns-zlip-1.pcap',
-        output => 'dns-zlip-1.out',
-        args   => ''
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'dns-zlip-2',
-        input => 'dns-zlip-2.pcap',
-        output => 'dns-zlip-2.out',
-        args   => ''
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'dns-zlip-3',
-        input => 'dns-zlip-3.pcap',
-        output => 'dns-zlip-3.out',
-        args   => ''
-    },
-    {
-        config_unset => 'HAVE_NO_PRINTF_Z',
-        name => 'sflow_print-segv',
-        input => 'sflow_print-segv.pcap',
-        output => 'sflow_print-segv.out',
-        args   => '-v'
-    },
-];
-
-1;