diff --git a/diffutils-3.7-coverity.patch b/diffutils-3.7-coverity.patch new file mode 100644 index 0000000..41d7756 --- /dev/null +++ b/diffutils-3.7-coverity.patch @@ -0,0 +1,315 @@ +diff -up diffutils-3.7/lib/careadlinkat.c.me diffutils-3.7/lib/careadlinkat.c +--- diffutils-3.7/lib/careadlinkat.c.me 2021-03-23 23:19:06.957542021 +0100 ++++ diffutils-3.7/lib/careadlinkat.c 2021-03-23 23:22:29.309145314 +0100 +@@ -1,6 +1,6 @@ + /* Read symbolic links into a buffer without size limitation, relative to fd. + +- Copyright (C) 2001, 2003-2004, 2007, 2009-2018 Free Software Foundation, ++ Copyright (C) 2001, 2003-2004, 2007, 2009-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify +@@ -38,75 +38,64 @@ + + #include "allocator.h" + +-/* Assuming the current directory is FD, get the symbolic link value +- of FILENAME as a null-terminated string and put it into a buffer. +- If FD is AT_FDCWD, FILENAME is interpreted relative to the current +- working directory, as in openat. +- +- If the link is small enough to fit into BUFFER put it there. +- BUFFER's size is BUFFER_SIZE, and BUFFER can be null +- if BUFFER_SIZE is zero. +- +- If the link is not small, put it into a dynamically allocated +- buffer managed by ALLOC. It is the caller's responsibility to free +- the returned value if it is nonnull and is not BUFFER. A null +- ALLOC stands for the standard allocator. +- +- The PREADLINKAT function specifies how to read links. It operates +- like POSIX readlinkat() +- +- but can assume that its first argument is the same as FD. ++enum { STACK_BUF_SIZE = 1024 }; + +- If successful, return the buffer address; otherwise return NULL and +- set errno. */ ++/* Act like careadlinkat (see below), with an additional argument ++ STACK_BUF that can be used as temporary storage. + +-char * +-careadlinkat (int fd, char const *filename, ++ If GCC_LINT is defined, do not inline this function with GCC 10.1 ++ and later, to avoid creating a pointer to the stack that GCC ++ -Wreturn-local-addr incorrectly complains about. See: ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 ++ Although the noinline attribute can hurt performance a bit, no better way ++ to pacify GCC is known; even an explicit #pragma does not pacify GCC. ++ When the GCC bug is fixed this workaround should be limited to the ++ broken GCC versions. */ ++#if __GNUC_PREREQ (10, 1) ++# if defined GCC_LINT || defined lint ++__attribute__ ((__noinline__)) ++# elif __OPTIMIZE__ && !__NO_INLINE__ ++# define GCC_BOGUS_WRETURN_LOCAL_ADDR ++# endif ++#endif ++static char * ++readlink_stk (int fd, char const *filename, + char *buffer, size_t buffer_size, + struct allocator const *alloc, +- ssize_t (*preadlinkat) (int, char const *, char *, size_t)) ++ ssize_t (*preadlinkat) (int, char const *, char *, size_t), ++ char stack_buf[STACK_BUF_SIZE]) + { + char *buf; + size_t buf_size; + size_t buf_size_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; +- char stack_buf[1024]; + + if (! alloc) + alloc = &stdlib_allocator; + +- if (! buffer_size) ++ if (!buffer) + { +- /* Allocate the initial buffer on the stack. This way, in the +- common case of a symlink of small size, we get away with a +- single small malloc() instead of a big malloc() followed by a +- shrinking realloc(). */ + buffer = stack_buf; +- buffer_size = sizeof stack_buf; ++ buffer_size = STACK_BUF_SIZE; + } + + buf = buffer; + buf_size = buffer_size; + +- do ++ while (buf) + { + /* Attempt to read the link into the current buffer. */ + ssize_t link_length = preadlinkat (fd, filename, buf, buf_size); + size_t link_size; + if (link_length < 0) + { +- /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1 +- with errno == ERANGE if the buffer is too small. */ +- int readlinkat_errno = errno; +- if (readlinkat_errno != ERANGE) ++ if (buf != buffer) + { +- if (buf != buffer) +- { +- alloc->free (buf); +- errno = readlinkat_errno; +- } +- return NULL; ++ int readlinkat_errno = errno; ++ alloc->free (buf); ++ errno = readlinkat_errno; + } ++ return NULL; + } + + link_size = link_length; +@@ -117,19 +106,19 @@ careadlinkat (int fd, char const *filena + + if (buf == stack_buf) + { +- char *b = (char *) alloc->allocate (link_size); ++ char *b = alloc->allocate (link_size); + buf_size = link_size; + if (! b) + break; +- memcpy (b, buf, link_size); +- buf = b; ++ return memcpy (b, buf, link_size); + } +- else if (link_size < buf_size && buf != buffer && alloc->reallocate) ++ ++ if (link_size < buf_size && buf != buffer && alloc->reallocate) + { + /* Shrink BUF before returning it. */ +- char *b = (char *) alloc->reallocate (buf, link_size); ++ char *b = alloc->reallocate (buf, link_size); + if (b) +- buf = b; ++ return b; + } + + return buf; +@@ -138,8 +127,8 @@ careadlinkat (int fd, char const *filena + if (buf != buffer) + alloc->free (buf); + +- if (buf_size <= buf_size_max / 2) +- buf_size *= 2; ++ if (buf_size < buf_size_max / 2) ++ buf_size = 2 * buf_size + 1; + else if (buf_size < buf_size_max) + buf_size = buf_size_max; + else if (buf_size_max < SIZE_MAX) +@@ -149,12 +138,53 @@ careadlinkat (int fd, char const *filena + } + else + break; +- buf = (char *) alloc->allocate (buf_size); ++ buf = alloc->allocate (buf_size); + } +- while (buf); + + if (alloc->die) + alloc->die (buf_size); + errno = ENOMEM; + return NULL; + } ++ ++ ++/* Assuming the current directory is FD, get the symbolic link value ++ of FILENAME as a null-terminated string and put it into a buffer. ++ If FD is AT_FDCWD, FILENAME is interpreted relative to the current ++ working directory, as in openat. ++ ++ If the link is small enough to fit into BUFFER put it there. ++ BUFFER's size is BUFFER_SIZE, and BUFFER can be null ++ if BUFFER_SIZE is zero. ++ ++ If the link is not small, put it into a dynamically allocated ++ buffer managed by ALLOC. It is the caller's responsibility to free ++ the returned value if it is nonnull and is not BUFFER. A null ++ ALLOC stands for the standard allocator. ++ ++ The PREADLINKAT function specifies how to read links. It operates ++ like POSIX readlinkat() ++ ++ but can assume that its first argument is the same as FD. ++ ++ If successful, return the buffer address; otherwise return NULL and ++ set errno. */ ++ ++char * ++careadlinkat (int fd, char const *filename, ++ char *buffer, size_t buffer_size, ++ struct allocator const *alloc, ++ ssize_t (*preadlinkat) (int, char const *, char *, size_t)) ++{ ++ /* Allocate the initial buffer on the stack. This way, in the ++ common case of a symlink of small size, we get away with a ++ single small malloc instead of a big malloc followed by a ++ shrinking realloc. */ ++ #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR ++ #warning "GCC might issue a bogus -Wreturn-local-addr warning here." ++ #warning "See ." ++ #endif ++ char stack_buf[STACK_BUF_SIZE]; ++ return readlink_stk (fd, filename, buffer, buffer_size, alloc, ++ preadlinkat, stack_buf); ++} +diff -up diffutils-3.7/src/diff.c.me diffutils-3.7/src/diff.c +diff -up diffutils-3.7/src/diff.h.me diffutils-3.7/src/diff.h +--- diffutils-3.7/src/diff.h.me 2021-03-23 22:47:04.509390138 +0100 ++++ diffutils-3.7/src/diff.h 2021-03-23 22:58:35.022552755 +0100 +@@ -392,7 +392,7 @@ extern void print_sdiff_script (struct c + extern char const change_letter[4]; + extern char const pr_program[]; + extern char *concat (char const *, char const *, char const *); +-extern bool (*lines_differ) (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE; ++extern bool (*lines_differ) (char const *, size_t, char const *, size_t); + extern bool lines_differ_singlebyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE; + #ifdef HANDLE_MULTIBYTE + extern bool lines_differ_multibyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE; +diff -up diffutils-3.7/src/util.c.me diffutils-3.7/src/util.c +--- diffutils-3.7/src/util.c.me 2021-03-23 23:01:58.105168496 +0100 ++++ diffutils-3.7/src/util.c 2021-03-23 23:18:18.833918967 +0100 +@@ -1144,6 +1144,7 @@ lines_differ_singlebyte (char const *s1, + } + + #ifdef HANDLE_MULTIBYTE ++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + # define MBC2WC(T, END, MBLENGTH, WC, STATE, CONVFAIL) \ + do \ + { \ +diff -up diffutils-3.7/lib/regcomp.c.me diffutils-3.7/lib/regcomp.c +--- diffutils-3.7/lib/regcomp.c.me 2021-03-24 09:01:20.582271604 +0100 ++++ diffutils-3.7/lib/regcomp.c 2021-03-24 09:03:54.125287605 +0100 +@@ -3674,7 +3674,6 @@ build_charclass_op (re_dfa_t *dfa, RE_TR + Idx alloc = 0; + #endif /* not RE_ENABLE_I18N */ + reg_errcode_t ret; +- re_token_t br_token; + bin_tree_t *tree; + + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +@@ -3725,11 +3724,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TR + #endif + + /* Build a tree for simple bracket. */ +-#if defined GCC_LINT || defined lint +- memset (&br_token, 0, sizeof br_token); +-#endif +- br_token.type = SIMPLE_BRACKET; +- br_token.opr.sbcset = sbcset; ++ re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset }; + tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (__glibc_unlikely (tree == NULL)) + goto build_word_op_espace; +@@ -3820,11 +3815,7 @@ static bin_tree_t * + create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, + re_token_type_t type) + { +- re_token_t t; +-#if defined GCC_LINT || defined lint +- memset (&t, 0, sizeof t); +-#endif +- t.type = type; ++ re_token_t t = { .type = type }; + return create_token_tree (dfa, left, right, &t); + } + +diff -up diffutils-3.7/lib/regexec.c.me diffutils-3.7/lib/regexec.c +--- diffutils-3.7/lib/regexec.c.me 2021-03-24 08:50:16.101143023 +0100 ++++ diffutils-3.7/lib/regexec.c 2021-03-24 08:55:03.347246385 +0100 +@@ -828,7 +828,9 @@ re_search_internal (const regex_t *preg, + break; + if (__glibc_unlikely (err != REG_NOMATCH)) + goto free_return; ++#ifdef DEBUG + match_last = -1; ++#endif + } + else + break; /* We found a match. */ +@@ -3693,6 +3695,7 @@ group_nodes_into_DFAstates (const re_dfa + bitset_empty (accepts); + } + } ++ assume (ndests <= SBC_MAX); + return ndests; + error_return: + for (j = 0; j < ndests; ++j) +diff -up diffutils-3.7/lib/regex_internal.h.me diffutils-3.7/lib/regex_internal.h +--- diffutils-3.7/lib/regex_internal.h.me 2021-03-24 08:54:03.464477733 +0100 ++++ diffutils-3.7/lib/regex_internal.h 2021-03-24 08:54:22.824728618 +0100 +@@ -34,6 +34,7 @@ + #include + + #include ++#include + + #ifdef _LIBC + # include +diff -up diffutils-3.7/src/ifdef.c.me diffutils-3.7/src/ifdef.c +--- diffutils-3.7/src/ifdef.c.me 2021-03-24 18:10:43.265671781 +0100 ++++ diffutils-3.7/src/ifdef.c 2021-03-24 18:08:39.843320920 +0100 +@@ -362,7 +362,7 @@ do_printf_spec (FILE *out, char const *s + printint print_value = value; + size_t spec_prefix_len = f - spec - 2; + size_t pI_len = sizeof pI - 1; +-#if 0 ++#if HAVE_C_VARARRAYS + char format[spec_prefix_len + pI_len + 2]; + #else + char *format = xmalloc (spec_prefix_len + pI_len + 2); diff --git a/diffutils-3.7-false-positive.patch b/diffutils-3.7-false-positive.patch new file mode 100644 index 0000000..ce789b1 --- /dev/null +++ b/diffutils-3.7-false-positive.patch @@ -0,0 +1,73 @@ +diff -up diffutils-3.7/lib/freopen-safer.c.me diffutils-3.7/lib/freopen-safer.c +--- diffutils-3.7/lib/freopen-safer.c.me 2021-03-24 15:38:27.785170510 +0100 ++++ diffutils-3.7/lib/freopen-safer.c 2021-03-24 15:39:56.389523872 +0100 +@@ -49,6 +49,7 @@ protect_fd (int fd) + } + return false; + } ++ /* coverity[leaked_handle : FALSE] */ + return true; + } + +diff -up diffutils-3.7/lib/regex_internal.c.me diffutils-3.7/lib/regex_internal.c +--- diffutils-3.7/lib/regex_internal.c.me 2021-03-24 15:45:12.934308141 +0100 ++++ diffutils-3.7/lib/regex_internal.c 2021-03-24 15:48:06.165592478 +0100 +@@ -1724,6 +1724,7 @@ create_cd_newstate (const re_dfa_t *dfa, + } + if (re_node_set_init_copy (newstate->entrance_nodes, nodes) + != REG_NOERROR) ++ /* coverity[leaked_storage : FALSE] */ + return NULL; + nctx_nodes = 0; + newstate->has_constraint = 1; +diff -up diffutils-3.7/src/analyze.c.me diffutils-3.7/src/analyze.c +--- diffutils-3.7/src/analyze.c.me 2021-03-24 17:16:35.560137760 +0100 ++++ diffutils-3.7/src/analyze.c 2021-03-24 17:18:02.298846273 +0100 +@@ -688,6 +688,7 @@ diff_2_files (struct comparison *cmp) + for (f = 0; f < 2; f++) + { + free (cmp->file[f].equivs); ++ /* coverity[offset_free : FALSE] */ + free (cmp->file[f].linbuf + cmp->file[f].linbuf_base); + } + +diff -up diffutils-3.7/src/diff3.c.me diffutils-3.7/src/diff3.c +--- diffutils-3.7/src/diff3.c.me 2021-03-24 17:18:21.317231331 +0100 ++++ diffutils-3.7/src/diff3.c 2021-03-24 17:22:54.217398657 +0100 +@@ -795,6 +795,7 @@ using_to_diff3_block (struct diff_block + D_LINEARRAY (result, FILEC) + result_offset, + D_LENARRAY (result, FILEC) + result_offset, + D_NUMLINES (ptr, FC))) ++ /* coverity[leaked_storage : FALSE] */ + return 0; + } + +@@ -824,6 +825,7 @@ using_to_diff3_block (struct diff_block + D_LINEARRAY (result, FILE0 + d) + result_offset, + D_LENARRAY (result, FILE0 + d) + result_offset, + D_NUMLINES (ptr, FO))) ++ /* coverity[leaked_storage : FALSE] */ + return 0; + + /* Catch the lines between here and the next diff */ +diff -up diffutils-3.7/src/sdiff.c.me diffutils-3.7/src/sdiff.c +--- diffutils-3.7/src/sdiff.c.me 2021-03-24 17:24:37.022988328 +0100 ++++ diffutils-3.7/src/sdiff.c 2021-03-24 17:25:39.145495628 +0100 +@@ -1169,5 +1169,6 @@ temporary_file (void) + fd = mkstemp (buf); + if (0 <= fd) + tmpname = buf; ++ /* coverity[leaked_storage : FALSE] */ + return fd; + } +diff -up diffutils-3.7/src/util.c.me diffutils-3.7/src/util.c +--- diffutils-3.7/src/util.c.me 2021-03-24 17:25:51.419067091 +0100 ++++ diffutils-3.7/src/util.c 2021-03-24 17:36:28.882404028 +0100 +@@ -699,6 +699,7 @@ parse_diff_color (void) + } + colors_enabled = false; + } ++/* coverity[leaked_storage : FALSE] */ + } + + static void diff --git a/diffutils.spec b/diffutils.spec index 6eb2f9b..d420b51 100644 --- a/diffutils.spec +++ b/diffutils.spec @@ -1,12 +1,14 @@ Summary: GNU collection of diff utilities Name: diffutils Version: 3.7 -Release: 8%{?dist} +Release: 9%{?dist} URL: https://www.gnu.org/software/diffutils/diffutils.html Source: https://ftp.gnu.org/gnu/diffutils/diffutils-%{version}.tar.xz Patch1: diffutils-cmp-s-empty.patch Patch2: diffutils-i18n.patch Patch3: diffutils-fix-gnulib-tests.patch +Patch4: diffutils-3.7-coverity.patch +Patch5: diffutils-3.7-false-positive.patch License: GPLv3+ Provides: bundled(gnulib) BuildRequires: gcc @@ -28,19 +30,13 @@ to merge two files interactively. Install diffutils if you need to compare text files. %prep -%setup -q -# For 'cmp -s', compare file sizes only if both non-zero (bug #563618). -%patch1 -p1 -b .cmp-s-empty - -%patch2 -p1 -b .i18n - -# Fix from gnulib upstream, commit 175e0bc (bug #1863423). -%patch3 -p1 -b .fix-gnulib-tests +%autosetup -p1 # Run autoreconf for aarch64 support (bug #925256). autoreconf %build +%global optflags %{optflags} -Dlint %configure make PR_PROGRAM=%{_bindir}/pr @@ -63,6 +59,9 @@ make check %{_infodir}/diffutils.info* %changelog +* Wed Mar 24 2021 Than Ngo - 3.7-9 +- Fix coverity issues + * Tue Jan 26 2021 Fedora Release Engineering - 3.7-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild