From 88d911dbc717494febee4b0ebc790808054fefff Mon Sep 17 00:00:00 2001 From: Jim Meyering
Date: Sat, 13 Aug 2016 19:40:20 -0700 Subject: [PATCH 1/4] build: ignore texinfo build artifacts * .gitignore: Ignore texinfo artifacts in doc/. --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bf11312..3fecace 100644 --- a/.gitignore +++ b/.gitignore @@ -15,10 +15,14 @@ /config.log /config.status /configure -/diffutils-*.tar.gz /diffutils-*.tar.xz /doc/.gitignore +/doc/diffutils.aux +/doc/diffutils.cp +/doc/diffutils.cps /doc/diffutils.info +/doc/diffutils.log +/doc/diffutils.toc /doc/stamp-vti /doc/version.texi /gnulib-tests -- 2.7.4 From 1a0df4396ebe3b9a58b882bb976cfce3f50d3cac Mon Sep 17 00:00:00 2001 From: Bastian Beischer Date: Sat, 13 Aug 2016 18:53:36 -0700 Subject: [PATCH 2/4] diff3: fix heap use-after-free; add minimal diff3 test coverage Commit v3.3-42-g3b74a90, "FIXME: src/diff3: plug a leak" added an invalid use of free, leading to use-after-free in nearly any invocation of diff3. Revert that commit. * NEWS (Bug fixes): Mention it. * tests/diff3: New file, to add minimal test coverage. * tests/Makefile.am (TESTS): Add it. Reported by Bastian Beischer in http://bugs.gnu.org/24210 --- NEWS | 3 +++ src/diff3.c | 1 - tests/Makefile.am | 1 + tests/diff3 | 30 ++++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/diff3 diff --git a/NEWS b/NEWS index 9a8d2e1..73ff83b 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ GNU diffutils NEWS -*- outline -*- ** Bug fixes + diff3 no longer malfunctions due to use-after-free + [bug introduced in 3.4] + diff --color no longer colorizes when TERM=dumb diff --git a/src/diff3.c b/src/diff3.c index 6ef90f4..0eb643e 100644 --- a/src/diff3.c +++ b/src/diff3.c @@ -1039,7 +1039,6 @@ process_diff (char const *filea, *block_list_end = NULL; *last_block = bptr; - free (diff_contents); return block_list; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 77d9fc3..66e25a5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ TESTS = \ binary \ brief-vs-stat-zero-kernel-lies \ colliding-file-names \ + diff3 \ excess-slash \ help-version \ function-line-vs-leading-space \ diff --git a/tests/diff3 b/tests/diff3 new file mode 100644 index 0000000..a1fc287 --- /dev/null +++ b/tests/diff3 @@ -0,0 +1,30 @@ +#!/bin/sh +# This would malfunction in diff-3.4 + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +echo a > a || framework_failure_ +echo b > b || framework_failure_ +echo c > c || framework_failure_ +cat <<'EOF' > exp || framework_failure_ +==== +1:1c + a +2:1c + b +3:1c + c +EOF + +fail=0 + +diff3 a b c > out 2> err || fail=1 +compare exp out || fail=1 +compare /dev/null err || fail=1 + +# Repeat, but with all three files the same: +diff3 a a a > out 2> err || fail=1 +compare /dev/null out || fail=1 +compare /dev/null err || fail=1 + +Exit $fail -- 2.7.4 From b3def738f3b435cbe6f2a8406bae5a71175a0b80 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 12 Aug 2016 11:17:26 -0700 Subject: [PATCH 3/4] maint: require that commit messages be of a certain form * bootstrap.conf (bootstrap_epilogue): Merge from coreutils, so that a local commit hook will now help enforce consistent commit messages. * Makefile.am (check-git-hook-script-sync): New rule, largely copied from coreutils. * scripts/git-hooks/commit-msg: New file, from coreutils, but with adapted list of program names. * scripts/git-hooks/applypatch-msg: New file, from git. * scripts/git-hooks/pre-applypatch: Likewise. * scripts/git-hooks/pre-commit: Likewise. --- Makefile.am | 14 ++++ bootstrap.conf | 25 +++++++ scripts/git-hooks/applypatch-msg | 15 ++++ scripts/git-hooks/commit-msg | 153 +++++++++++++++++++++++++++++++++++++++ scripts/git-hooks/pre-applypatch | 14 ++++ scripts/git-hooks/pre-commit | 49 +++++++++++++ 6 files changed, 270 insertions(+) create mode 100755 scripts/git-hooks/applypatch-msg create mode 100755 scripts/git-hooks/commit-msg create mode 100755 scripts/git-hooks/pre-applypatch create mode 100755 scripts/git-hooks/pre-commit diff --git a/Makefile.am b/Makefile.am index 244024e..edee5fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,3 +42,17 @@ gen-ChangeLog: ALL_RECURSIVE_TARGETS += distcheck-hook distcheck-hook: $(MAKE) my-distcheck + +# Some of our git hook scripts are supposed to be identical to git's samples. +# See if they are still in sync. +.PHONY: check-git-hook-script-sync +check-git-hook-script-sync: + @fail=0; \ + t=$$(mktemp -d) \ + && cd $$t && git init -q && cd .git/hooks \ + && for i in pre-commit pre-applypatch applypatch-msg; do \ + diff -u $(abs_top_srcdir)/scripts/git-hooks/$$i $$i.sample \ + || fail=1; \ + done; \ + rm -rf $$t; \ + test $$fail = 0 diff --git a/bootstrap.conf b/bootstrap.conf index 828ffef..ac3c278 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -129,4 +129,29 @@ bootstrap_post_import_hook() bootstrap_epilogue() { perl -pi -e "s/address@hidden@/$package/g" README-release + + # Since this is a "GNU" package, replace this line + # if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null \ + # | grep -v 'libtool:' >/dev/null; then + # with this: + # if true; then + # Why? That pipeline searches all files in $(top_srcdir), and if you + # happen to have large files (or apparently large sparse files), the + # first grep may well run out of memory. + perl -pi -e 's/if LC_ALL=C grep .GNU .PACKAGE.*; then/if true; then/' \ + po/Makefile.in.in + + # Install our git hooks, as long as "cp" accepts the --backup option, + # so that we can back up any existing files. + case $(cp --help) in *--backup*) backup=1;; *) backup=0;; esac + if test $backup = 1; then + hooks=$(cd scripts/git-hooks && git ls-files) + for f in $hooks; do + # If it is identical, skip it. + cmp scripts/git-hooks/$f .git/hooks/$f > /dev/null \ + && continue + cp --backup=numbered scripts/git-hooks/$f .git/hooks + chmod a-w .git/hooks/$f + done + fi } diff --git a/scripts/git-hooks/applypatch-msg b/scripts/git-hooks/applypatch-msg new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/scripts/git-hooks/applypatch-msg @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/scripts/git-hooks/commit-msg b/scripts/git-hooks/commit-msg new file mode 100755 index 0000000..888b83b --- /dev/null +++ b/scripts/git-hooks/commit-msg @@ -0,0 +1,153 @@ +eval '(exit $?0)' && eval 'exec perl -w "$0" ${1+"$@"}' + & eval 'exec perl -w "$0" $argv:q' + if 0; + +use strict; +use warnings; +(my $ME = $0) =~ s|.*/||; + +# Emulate Git's choice of the editor for the commit message. +chomp (my $editor = `git var GIT_EDITOR`); +# And have a sane, minimal fallback in case of weird failures. +$editor = "vi" if $? != 0 or $editor =~ /^\s*\z/; + +# Keywords allowed before the colon on the first line of a commit message: +# program names and a few general category names. +my @valid = qw( + diff diff3 cmp sdiff + + gnulib tests maint doc build scripts + ); +my $v_or = join '|', @valid; +my $valid_regex = qr/^(?:$v_or)$/; + +# Rewrite the $LOG_FILE (old contents in @$LINE_REF) with an additional +# a commented diagnostic "# $ERR" line at the top. +sub rewrite($$$) +{ + my ($log_file, $err, $line_ref) = @_; + local *LOG; + open LOG, '>', $log_file + or die "$ME: $log_file: failed to open for writing: $!"; + print LOG "# $err"; + print LOG @$line_ref; + close LOG + or die "$ME: $log_file: failed to rewrite: $!\n"; +} + +sub re_edit($) +{ + my ($log_file) = @_; + + warn "Interrupt (Ctrl-C) to abort...\n"; + + system 'sh', '-c', "$editor $log_file"; + ($? & 127) || ($? >> 8) + and die "$ME: $log_file: the editor ($editor) failed, aborting\n"; +} + +sub bad_first_line($) +{ + my ($line) = @_; + + $line =~ /^[Vv]ersion \d/ + and return ''; + + $line =~ /:/ + or return 'missing colon on first line of log message'; + + $line =~ /\.$/ + and return 'do not use a period "." at the end of the first line'; + + # The token(s) before the colon on the first line must be on our list + # Tokens may be space- or comma-separated. + (my $pre_colon = $line) =~ s/:.*//; + my @word = split (/[ ,]/, $pre_colon); + my @bad = grep !/$valid_regex/, @word; + @bad + and return 'invalid first word(s) of summary line: ' . join (', ', @bad); + + return ''; +} + +# Given a $LOG_FILE name and a address@hidden buffer, +# read the contents of the file into the buffer and analyze it. +# If the log message passes muster, return the empty string. +# If not, return a diagnostic. +sub check_msg($$) +{ + my ($log_file, $line_ref) = @_; + + local *LOG; + open LOG, '<', $log_file + or return "failed to open for reading: $!"; + @$line_ref =