From 906573c97a006d4e734d24ce2a1ed493b4961497 Mon Sep 17 00:00:00 2001 From: Kamila Szewczyk Date: Sun, 9 Aug 2026 23:34:32 +0200 Subject: [PATCH] dist: fix bugs #81558 and #81557. From https://bugs.gnu.org/81558 and https://bugs.gnu.org/81557 (Bruno Haible). The filter for overly long file names had as many dots as the maximum, so it rejected names of exactly that length; it needs one more. 99 characters is the v7 limit, not a portable limit for tarballs in general; ustar, the default since 1.18, stores longer names. The manual said otherwise. * bin/automake.in (handle_dist): one dot more than the maximum. * lib/am/distdir.am (distdir-am): name the option in the diagnostic. * doc/automake.texi (List of Automake options): rewrite the filename-length-max entry; the limit depends on the archive format, and the length counted includes the $(distdir)/ prefix. * t/filename-length-max.sh: new test. * t/list-of-tests.mk (handwritten_TESTS): add it. * NEWS: mention both. --- NEWS | 9 +++++++ bin/automake.in | 2 +- doc/automake.texi | 30 ++++++++++++++++----- lib/am/distdir.am | 5 +++- t/filename-length-max.sh | 58 ++++++++++++++++++++++++++++++++++++++++ t/list-of-tests.mk | 1 + 6 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 t/filename-length-max.sh diff --git a/NEWS b/NEWS index 372ea46f3..3a401a373 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,15 @@ New in 1.18.2 (????-??-??): - `make dist' now fails when tar fails, instead of exiting successfully with a truncated archive. + - The filename-length-max=N option no longer rejects file names of + exactly N characters; as documented, only longer ones are. + (bug#81558) + + - The manual no longer presents 99 characters as the portable limit + for file names in any archive format: it is the limit of the v7 + format, whereas ustar, the default since Automake 1.18, stores + longer names. (bug#81557) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New in 1.18.1 (2025-06-25): diff --git a/bin/automake.in b/bin/automake.in index f7e84ebcc..1035dae62 100644 --- a/bin/automake.in +++ b/bin/automake.in @@ -3970,7 +3970,7 @@ sub handle_dist () $transform{'DIST-TARGETS'} = join (' ', @dist_targets); my $flm = option ('filename-length-max'); - my $filename_filter = $flm ? '.' x $flm->[1] : ''; + my $filename_filter = $flm ? '.' x (1 + $flm->[1]) : ''; $output_rules .= file_contents ('distdir', new Automake::Location, diff --git a/doc/automake.texi b/doc/automake.texi index 868002453..c81b0897f 100644 --- a/doc/automake.texi +++ b/doc/automake.texi @@ -11310,13 +11310,29 @@ is deprecated, as the @samp{compress} program is obsolete. Support for it will be removed altogether in Automake 2.0. @trindex dist-tarZ -@item @option{filename-length-max=99} -@cindex Option, @option{filename-length-max=99} -@opindex filename-length-max=99 -Abort if file names longer than 99 characters are found during -@samp{make dist}. Such long file names are generally considered not to -be portable in tarballs. See the @option{tar-v7} and @option{tar-ustar} -options below. This option should be used in the top-level +@item @option{filename-length-max=@var{max}} +@cindex Option, @option{filename-length-max=@var{max}} +@opindex filename-length-max=@var{max} +Abort @samp{make dist} if the distribution contains file names longer +than @var{max} characters; names of exactly @var{max} characters are +accepted. What is measured is the name under which @command{tar} will +store the file, so it includes the @file{@var{package}-@var{version}/} +prefix. + +How long a file name may be depends on the archive format in use +(@pxref{tar-formats}). The @option{tar-v7} format supports at most 99 +characters, hence the customary @option{filename-length-max=99}. The +@option{tar-ustar} format, the default since Automake 1.18, stores file +names of up to 256 characters, provided they can be split at a directory +separator into a prefix of at most 155 characters and a remainder of at +most 100; any name of at most 100 characters therefore fits, and +@option{filename-length-max=155} is a safe choice as long as no single +component of a file name exceeds 100 characters. The @option{tar-pax} +format does not limit file name lengths at all. So, unless you also +distribute a V7 archive, @option{filename-length-max=99} is stricter +than necessary. + +This option should be used in the top-level @file{Makefile.am} or as an argument of @code{AM_INIT_AUTOMAKE} in @file{configure.ac}; it will be ignored otherwise. It will also be ignored in sub-packages of nested packages (@pxref{Subpackages}). diff --git a/lib/am/distdir.am b/lib/am/distdir.am index ceb78c8d9..b817779ad 100644 --- a/lib/am/distdir.am +++ b/lib/am/distdir.am @@ -291,9 +291,12 @@ if %?TOPDIR_P% ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" if %?FILENAME_FILTER% +## %FILENAME_FILTER% is one dot longer than the requested maximum, so +## that it matches only the file names that exceed it. @if test -z "$(am__skip_length_check)" && find "$(distdir)" -type f -print | \ grep '^%FILENAME_FILTER%' 1>&2; then \ - echo 'error: the above filenames are too long' 1>&2; \ + echo 'error: the above filenames are too long' \ + '(see the filename-length-max option)' 1>&2; \ exit 1; \ else :; fi endif %?FILENAME_FILTER% diff --git a/t/filename-length-max.sh b/t/filename-length-max.sh new file mode 100644 index 000000000..4c94ec712 --- /dev/null +++ b/t/filename-length-max.sh @@ -0,0 +1,58 @@ +#! /bin/sh +# Copyright (C) 2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# The filename-length-max=N option must accept file names of exactly N +# characters, and reject only the longer ones. See automake bug#81558. + +. test-init.sh + +echo AC_OUTPUT >> configure.ac + +# Long enough to be the longest file name of the distribution. +long=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +mkdir dir +: > dir/$long + +# The maximum we ask for is the length of the name under which tar would +# store that file, that is, including the "$distdir/" prefix. Word +# splitting gets rid of the padding some 'wc' implementations write. +set -- $(printf '%s' "$distdir/dir/$long" | wc -c) +max=$1 +echo "maximum file name length: $max" # For debugging. + +cat > Makefile.am << END +AUTOMAKE_OPTIONS = filename-length-max=$max +EXTRA_DIST = dir +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE +./configure + +# A file name of exactly $max characters is not too long. +$MAKE dist +test -f $distdir.tar.gz + +# One character more, and it is. +: > dir/a$long +run_make -E -e FAIL dist +grep 'filenames are too long' stderr +# And only that file gets reported. +test 1 -eq $(grep -c "$long" stderr) + +: diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk index cd9b6bc55..e56d257bc 100644 --- a/t/list-of-tests.mk +++ b/t/list-of-tests.mk @@ -494,6 +494,7 @@ t/extra-sources-no-spurious.sh \ t/extra-sources.sh \ t/extra.sh \ t/f90only.sh \ +t/filename-length-max.sh \ t/flavor.sh \ t/flibs.sh \ t/fn99.sh \ -- 2.47.3