[[[
Enhance platform support of hook script check-mime-type.pl
Adopted from contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
(r1295006) [1]

* contrib/hook-scripts/check-mime-type.pl:
  (tmp_dir) Cross Platform: sane temp dir creation via File::Temp
function tempdir()
  (sub safe_read_from_pipe) Windows/DOS: does not support openfork and
files/paths with spaces have to be put in quotes

Patch by: Matthias Bücher <m...@maddes.net>

Tested with Subversion 1.6 to 1.8
for 1.8.5+ you also need Leo Davis' patch [4] (although I personally
kept chdir to temp dir)

[1]
http://svn.apache.org/viewvc/subversion/trunk/contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
[2] http://perldoc.perl.org/perlport.html#Interprocess-Communication-(IPC)
[3] http://perldoc.perl.org/perlport.html#PLATFORMS
[4]
http://mail-archives.apache.org/mod_mbox/subversion-dev/201403.mbox/%3c1576503.m6xb7ud...@hurry.speechfxinc.com%3E

]]]

Index: contrib/hook-scripts/check-mime-type.pl
===================================================================
--- contrib/hook-scripts/check-mime-type.pl     (revision 1583207)
+++ contrib/hook-scripts/check-mime-type.pl     (working copy)
@@ -1,18 +1,41 @@
 #!/usr/bin/env perl
 
+# [[[
+# Enhance platform support of hook script check-mime-type.pl
+# Adopted from contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in 
(r1295006) [1]
+#
+# * contrib/hook-scripts/check-mime-type.pl:
+#   (tmp_dir) Cross Platform: sane temp dir creation via File::Temp
+#             function tempdir()
+#   (sub safe_read_from_pipe) Windows/DOS: does not support openfork and
+#                             files/paths with spaces have to be put in quotes
+#
+# Patch by: Matthias Bücher <m...@maddes.net>
+#
+# Tested with Subversion 1.6 to 1.8
+# for 1.8.5+ you also need Leo Davis' patch [4] (although I personally kept 
chdir to temp dir)
+#
+# [1] 
http://svn.apache.org/viewvc/subversion/trunk/contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
+# [2] http://perldoc.perl.org/perlport.html#Interprocess-Communication-(IPC)
+# [3] http://perldoc.perl.org/perlport.html#PLATFORMS
+# [4] 
http://mail-archives.apache.org/mod_mbox/subversion-dev/201403.mbox/%3c1576503.m6xb7ud...@hurry.speechfxinc.com%3E
+#
+# ]]]
+
 # ====================================================================
-# commit-mime-type-check.pl: check that every added file has the
-# svn:mime-type property set and every added file with a mime-type
-# matching text/* also has svn:eol-style set. If any file fails this
-# test the user is sent a verbose error message suggesting solutions and
-# the commit is aborted.
+# check-mime-type.pl: check that every added file has the
+# svn:mime-type property set and files with a mime-type
+# matching text/* also have svn:eol-style set. If any file fails these
+# tests the user is sent a verbose error message suggesting solutions
+# and the commit is aborted.
 #
-# Usage: commit-mime-type-check.pl REPOS TXN-NAME
+# Usage: check-mime-type.pl REPOS TXN-NAME
 # ====================================================================
-# Most of commit-mime-type-check.pl was taken from
+# Most of check-mime-type.pl was taken from
 # commit-access-control.pl, Revision 9986, 2004-06-14 16:29:22 -0400.
 # ====================================================================
 # Copyright (c) 2000-2004 CollabNet.  All rights reserved.
+# Copyright (c) 2014 Apache Software Foundation (ASF).
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution.  The terms
@@ -25,6 +48,15 @@
 # history and logs, available at http://subversion.tigris.org/.
 # ====================================================================
 
+use strict;
+use Carp;
+use Cwd;
+use File::Temp  qw(tempdir tempfile);
+
+my $old_dir;
+my $os_windows = $^O eq 'MSWin32';
+my $os_dos = $^O eq 'dos';
+
 # Turn on warnings the best way depending on the Perl version.
 BEGIN {
   if ( $] >= 5.006_000)
@@ -31,10 +63,13 @@ BEGIN {
     { require warnings; import warnings; }
   else
     { $^W = 1; }
+
+  $old_dir = getcwd;
 }
 
-use strict;
-use Carp;
+END {
+  chdir($old_dir);
+}
 
 
 ######################################################################
@@ -94,9 +129,9 @@ sub ACCESS_READ_WRITE () { 'read-write' }
 ######################################################################
 # Harvest data using svnlook.
 
-# Change into /tmp so that svnlook diff can create its .svnlook
+# Change into temp dir so that svnlook diff can create its .svnlook
 # directory.
-my $tmp_dir = '/tmp';
+my $tmp_dir = tempdir( TMPDIR => 1, CLEANUP => 1 );
 chdir($tmp_dir)
   or die "$0: cannot chdir `$tmp_dir': $!\n";
 
@@ -180,6 +215,7 @@ sub usage
   die "usage: $0 REPOS TXN-NAME\n";
 }
 
+# Start a child process safely without using /bin/sh.
 sub safe_read_from_pipe
 {
   unless (@_)
@@ -186,19 +222,68 @@ sub safe_read_from_pipe
     {
       croak "$0: safe_read_from_pipe passed no arguments.\n";
     }
-  print "Running @_\n";
-  my $pid = open(SAFE_READ, '-|', @_);
-  unless (defined $pid)
+
+  my $openfork_available = !($os_windows || $os_dos);
+  if ($openfork_available)
     {
-      die "$0: cannot fork: $!\n";
+      print "Running @_\n";
+      my $pid = open(SAFE_READ, '-|', @_);
+      unless (defined $pid)
+        {
+          die "$0: cannot fork: $!\n";
+        }
+      unless ($pid)
+        {
+          # child
+          open(STDERR, ">&STDOUT")
+            or die "$0: cannot dup STDOUT: $!\n";
+          exec(@_)
+            or die "$0: cannot exec `@_': $!\n";
+        }
     }
-  unless ($pid)
+  else
     {
-      open(STDERR, ">&STDOUT")
-        or die "$0: cannot dup STDOUT: $!\n";
-      exec(@_)
-        or die "$0: cannot exec `@_': $!\n";
+      # Redirect the comment into a temp file and use that to work around
+      # Windoze's (non-)handling of multi-line commands.
+      my @commandline = ();
+      my $command;
+      my $comment;
+
+      while ($command = shift)
+        {
+          if ("-m" eq $command)
+            {
+              $comment = shift;
+              my ($handle, $tmpfile) = tempfile( DIR => $tmp_dir);
+              print $handle $comment;
+              close($handle);
+
+              push(@commandline, "--file");
+              push(@commandline, $tmpfile);
+            }
+          else
+            {
+              # Munge the command to protect it from the command line
+              $command =~ s/\"/\\\"/g;
+              if ($command =~ m"\s") { $command = "\"$command\""; }
+              if ($command eq "") { $command = "\"\""; }
+              if ($command =~ m"\n")
+                {
+                  warn "$0: carriage return detected in command - may not 
work\n";
+                }
+              push(@commandline, $command);
+            }
+        }
+
+      print "Running @commandline\n";
+      if ( $comment ) { print $comment; }
+
+      # Now do the pipe.
+      open(SAFE_READ, "@commandline |")
+        or die "$0: cannot pipe to command: $!\n";
     }
+
+  # parent
   my @output;
   while (<SAFE_READ>)
     {
@@ -224,6 +309,8 @@ sub safe_read_from_pipe
     }
 }
 
+# Use safe_read_from_pipe to start a child process safely and exit the
+# script if the child failed for whatever reason.
 sub read_from_process
   {
   unless (@_)

Reply via email to