Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-PAR-Packer for openSUSE:Factory 
checked in at 2022-12-14 14:11:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-PAR-Packer (Old)
 and      /work/SRC/openSUSE:Factory/.perl-PAR-Packer.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-PAR-Packer"

Wed Dec 14 14:11:08 2022 rev:23 rq:1042831 version:1.057

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-PAR-Packer/perl-PAR-Packer.changes  
2022-09-12 19:08:47.826628898 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-PAR-Packer.new.1835/perl-PAR-Packer.changes    
    2022-12-14 14:11:21.907606468 +0100
@@ -1,0 +2,21 @@
+Wed Nov 30 03:07:14 UTC 2022 - Tina Müller <[email protected]>
+
+- updated to 1.057
+   see /usr/share/doc/packages/perl-PAR-Packer/Changes
+
+  1.057  2022-11029
+  - use a different method to mark executable built from "pp --clean ..."
+    - scripts/par.pl: don't patch the string "__PASS_PAR_CLEAN__               
\0" in the
+      "boot" section of the executable and ...
+    - myldr/boot.c: ... stop looking for the patched string
+    - scripts/par.pl: add "\0CLEAN" in lieu of "\0CACHE" (and drop the 40-byte
+      cache name below that) in the "trailer" section when generating a packed
+      executable when META.yml indicates "--clean" was specified)
+    - myldr/mktmpdir.c: allow "\0CLEAN" as an alternative to "\0CACHE"
+      and set PAR_CLEAN=1 in that case
+    - myldr/mktmpdir.c: implement find_par_magic() akin the one in 
script/par.pl
+  - better CLT detection in MacOS (#70) [plk <[email protected]>]
+  - use Getopt::ArgvFile with resolveEnvVars=1
+    suggested by Johan Vromans (@sciurius on GitHub)
+
+-------------------------------------------------------------------

Old:
----
  PAR-Packer-1.056.tar.gz

New:
----
  PAR-Packer-1.057.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-PAR-Packer.spec ++++++
--- /var/tmp/diff_new_pack.j1MN5j/_old  2022-12-14 14:11:22.395608978 +0100
+++ /var/tmp/diff_new_pack.j1MN5j/_new  2022-12-14 14:11:22.399608998 +0100
@@ -18,7 +18,7 @@
 
 %define cpan_name PAR-Packer
 Name:           perl-PAR-Packer
-Version:        1.056
+Version:        1.057
 Release:        0
 License:        Artistic-1.0 OR GPL-1.0-or-later
 Summary:        PAR Packager

++++++ PAR-Packer-1.056.tar.gz -> PAR-Packer-1.057.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/Changes new/PAR-Packer-1.057/Changes
--- old/PAR-Packer-1.056/Changes        2022-09-05 12:09:30.000000000 +0200
+++ new/PAR-Packer-1.057/Changes        2022-11-29 12:30:20.000000000 +0100
@@ -1,3 +1,22 @@
+1.057  2022-11029
+
+- use a different method to mark executable built from "pp --clean ..."
+  
+  - scripts/par.pl: don't patch the string "__PASS_PAR_CLEAN__               
\0" in the
+    "boot" section of the executable and ...
+  - myldr/boot.c: ... stop looking for the patched string
+  - scripts/par.pl: add "\0CLEAN" in lieu of "\0CACHE" (and drop the 40-byte
+    cache name below that) in the "trailer" section when generating a packed
+    executable when META.yml indicates "--clean" was specified)
+  - myldr/mktmpdir.c: allow "\0CLEAN" as an alternative to "\0CACHE"
+    and set PAR_CLEAN=1 in that case
+  - myldr/mktmpdir.c: implement find_par_magic() akin the one in script/par.pl
+
+- better CLT detection in MacOS (#70) [plk <[email protected]>]
+
+- use Getopt::ArgvFile with resolveEnvVars=1 
+  suggested by Johan Vromans (@sciurius on GitHub)
+
 1.056  2022-09-05
 
 - Fix #66: patch myldr/boot for "pp --clean ..." without side effects
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/META.json 
new/PAR-Packer-1.057/META.json
--- old/PAR-Packer-1.056/META.json      2022-09-05 12:10:06.000000000 +0200
+++ new/PAR-Packer-1.057/META.json      2022-11-29 12:32:01.000000000 +0100
@@ -4,7 +4,7 @@
       "Audrey Tang <[email protected]>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter 
version 2.150010",
+   "generated_by" : "ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter 
version 2.150010",
    "license" : [
       "perl_5"
    ],
@@ -78,6 +78,6 @@
       },
       "x_MailingList" : "mailto:[email protected]";
    },
-   "version" : "1.056",
-   "x_serialization_backend" : "JSON::PP version 4.11"
+   "version" : "1.057",
+   "x_serialization_backend" : "JSON::PP version 4.12"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/META.yml 
new/PAR-Packer-1.057/META.yml
--- old/PAR-Packer-1.056/META.yml       2022-09-05 12:10:06.000000000 +0200
+++ new/PAR-Packer-1.057/META.yml       2022-11-29 12:32:01.000000000 +0100
@@ -14,7 +14,7 @@
   File::Glob: '0'
   File::Spec::Functions: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 
2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 
2.150010'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -48,5 +48,5 @@
   MailingList: mailto:[email protected]
   bugtracker: https://github.com/rschupp/PAR-Packer/issues
   repository: git://github.com/rschupp/PAR-Packer.git
-version: '1.056'
+version: '1.057'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/lib/PAR/Packer.pm 
new/PAR-Packer-1.057/lib/PAR/Packer.pm
--- old/PAR-Packer-1.056/lib/PAR/Packer.pm      2022-09-05 11:13:07.000000000 
+0200
+++ new/PAR-Packer-1.057/lib/PAR/Packer.pm      2022-11-29 12:29:04.000000000 
+0100
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-our $VERSION = '1.056';
+our $VERSION = '1.057';
 
 =head1 NAME
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/lib/pp.pm 
new/PAR-Packer-1.057/lib/pp.pm
--- old/PAR-Packer-1.056/lib/pp.pm      2021-01-13 15:17:12.000000000 +0100
+++ new/PAR-Packer-1.057/lib/pp.pm      2022-11-18 12:11:28.000000000 +0100
@@ -14,7 +14,7 @@
 use PAR ();
 use Module::ScanDeps ();
 use App::Packer::PAR ();
-use Getopt::ArgvFile default=>1;
+use Getopt::ArgvFile default=>1, resolveEnvVars=>1;
 use Getopt::Long qw(:config no_ignore_case);
 
 
@@ -156,7 +156,7 @@
 
 A GUI interface is also available as the F<tkpp> command.
 
-It does not provide the compilation-step acceleration provided by
+It does B<not> provide the compilation-step acceleration provided by
 F<perlcc> (however, see B<-f> below for byte-compiled, source-hiding
 techniques), but makes up for it with better reliability, smaller
 executable size, and full retrieval of original source code.
@@ -183,6 +183,9 @@
 interpreted as a file to read options from. Mixing ordinary options
 and C<@file> options is possible. This is implemented using the
 L<Getopt::ArgvFile> module, so read its documentation for advanced usage.
+Note that L<Getopt::ArgvFile> is used here with parameter C<resolveEnvVars=1>,
+i.e. substrings of the form C<${>I<FOO>C<}> in the contents of C<@file> are 
replaced
+with the value of environment variable I<FOO>.
 
 =over 4
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/myldr/boot.c 
new/PAR-Packer-1.057/myldr/boot.c
--- old/PAR-Packer-1.056/myldr/boot.c   2022-09-05 11:40:44.000000000 +0200
+++ new/PAR-Packer-1.057/myldr/boot.c   2022-11-22 16:10:09.000000000 +0100
@@ -49,18 +49,17 @@
     int fd;
     chunk_t *chunk;
     struct stat statbuf;
-    int len = strlen(stmpdir) + 1 + strlen(ext_name);
     char *tmp_path;
 
-    *ext_path = malloc(len + 1);
+    *ext_path = malloc(strlen(stmpdir) + 1 + strlen(ext_name) + 1);
     sprintf(*ext_path, "%s/%s", stmpdir, ext_name);
 
     if (par_lstat(*ext_path, &statbuf) == 0 && statbuf.st_size == 
emb_file->size )
         return EXTRACT_ALREADY; /* file already exists and has the expected 
size */
 
-    tmp_path = malloc(len + 1 + 20 + 1); /* 20 decimal digits should be enough 
to hold up to 2^64-1 */
+    tmp_path = malloc(strlen(*ext_path) + 1 + 20 + 1); 
+                                /* 20 decimal digits should be enough to hold 
up to 2^64-1 */
     sprintf(tmp_path, "%s.%lu", *ext_path, (unsigned long)getpid());
-
     fd = open(tmp_path, O_CREAT | O_WRONLY | OPEN_O_BINARY, 0755);
     if ( fd == -1 ) 
         return EXTRACT_FAIL;
@@ -208,7 +207,6 @@
 /* the contents of this string (in the executable myldr/boot)
  * will be patched by script/par.pl if option "--clean" is used with pp
  */
-static char pass_par_clean[] = "__PASS_PAR_CLEAN__               \0";
 
 int main ( int argc, char **argv, char **env )
 {
@@ -230,15 +228,6 @@
 
     par_init_env();
 
-    /* check for patched content of pass_par_clean */
-    {
-        char *equals = strchr(pass_par_clean, '=');
-        if (equals != NULL) {
-            equals[2] = '\0';    /* trim value to one byte */
-            par_setenv("PAR_CLEAN", equals + 1);
-        }
-    }
-
     stmpdir = par_mktmpdir( argv );
     if ( !stmpdir ) die("");        /* error message has already been printed 
*/
 
@@ -277,14 +266,15 @@
             char *arch = malloc(size);
             sysctlbyname("hw.machine", arch, &size, NULL, 0);
 
-            /* Detect if lipo exists, if not die */
+            /* Detect if CLT are installed, if not, die */
+            int x = system("/usr/bin/xcode-select -p 1>/dev/null 2>/dev/null");
+            if (x != 0) 
+              die("%s: Command Line Tools are not installed - "
+                  "run 'xcode-select --install' to install (errno=%i)\n", 
+                  argv[0], errno);
+
+            int exist;
             struct stat buffer;
-            int exist = stat("/usr/bin/lipo", &buffer);
-            if (exist == -1)
-                die("%s: cannot find /usr/bin/lipo to unpack universal binary 
- "
-                    "do you need install Developer Tools? (errno=%i)\n", 
-                    argv[0], errno);
-          
             char *archthinbin = malloc(strlen(ftmpdir) + 1 + 
strlen(par_basename(my_prog)) + 1);
             sprintf(archthinbin, "%s/%s", ftmpdir, par_basename(my_prog));
             char* lipo_argv[] = { "lipo", "-extract_family", arch, "-output", 
archthinbin, my_prog, NULL };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/myldr/internals.c 
new/PAR-Packer-1.057/myldr/internals.c
--- old/PAR-Packer-1.056/myldr/internals.c      2020-08-27 10:35:01.000000000 
+0200
+++ new/PAR-Packer-1.057/myldr/internals.c      2022-11-24 15:40:03.000000000 
+0100
@@ -45,25 +45,6 @@
 #endif
 #endif
         }
-#if (PERL_REVISION == 5 && PERL_VERSION == 8 \
-        && ( PERL_SUBVERSION >= 1 && PERL_SUBVERSION <= 5)) || \
-    (PERL_REVISION == 5 && PERL_VERSION == 9 && PERL_SUBVERSION <= 1)
-        /* 5.8.1 through 5.8.5, as well as 5.9.0 does not copy fakeargv, sigh 
*/
-        {
-            char *p;
-            STRLEN len = strlen( fakeargv[0] );
-            New( 42, p, len+1, char );
-            Copy( fakeargv[0], p, len, char );
-            SvSETMAGIC(GvSV(tmpgv));
-            Copy( p, fakeargv[0], len, char );
-            fakeargv[0][len] = '\0';
-            Safefree( p );
-        }
-        /*
-#else
-        SvSETMAGIC(GvSV(tmpgv));
-        */
-#endif
     }
 
     /* PAR::Packer isn't included in a packed executable, but we provide
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/myldr/mktmpdir.c 
new/PAR-Packer-1.057/myldr/mktmpdir.c
--- old/PAR-Packer-1.056/myldr/mktmpdir.c       2022-09-05 12:07:25.000000000 
+0200
+++ new/PAR-Packer-1.057/myldr/mktmpdir.c       2022-11-26 22:08:27.000000000 
+0100
@@ -1,8 +1,6 @@
 #include "mktmpdir.h"
 #include "sha1.h"
 
-#define PAR_TEMP "PAR_TEMP"
-
 #ifdef O_BINARY
 #  define OPEN_O_BINARY O_BINARY
 #else
@@ -23,6 +21,18 @@
 #define Stat_t struct stat
 #endif
 
+static char PAR_MAGIC[] = "\nPAR.pm\n";
+#define magic_size 8
+
+/* "\0CACHE" or "\0CLEAN" */
+#define cache_marker_size 6
+
+/* size of a pack("N") number */
+#define FILE_offset_size 4
+
+#define cache_name_size 40
+
+
 static int isWritableDir(const char* val)
 {
     Stat_t statbuf;
@@ -69,6 +79,40 @@
     }
 }
 
+static void *par_memrmem(void* haystack, size_t haystacklen, void* needle, 
size_t needlelen)
+{
+    char *hs = haystack;
+    char *p;
+    if (haystacklen < needlelen)
+        return NULL;
+    for (p = hs + haystacklen - needlelen; p >= hs; p--)
+        if (memcmp(p, needle, needlelen) == 0)
+            return p;
+    return NULL;
+}
+
+static off_t find_par_magic(int fd)
+{
+#define CHUNK_SIZE (64 * 1024)
+    char buf[CHUNK_SIZE + magic_size];
+    off_t pos;
+    int len;
+    char *p;
+    off_t file_size = lseek(fd, 0, 2);
+
+    for (pos = (file_size-1) - (file_size-1) % CHUNK_SIZE; 
+         pos >= 0; 
+         pos -= CHUNK_SIZE) {
+        lseek(fd, pos, 0);
+        len = read(fd, buf, CHUNK_SIZE + magic_size);
+        p = par_memrmem(buf, len, PAR_MAGIC, magic_size);
+        if (p)
+            return pos + (p - buf);
+    }
+    return -1;
+#undef CHUNK_SIZE
+}
+
 char *par_mktmpdir ( char **argv ) {
     int i;
     const char *tmpdir = NULL;
@@ -91,12 +135,9 @@
     char *progname = NULL, *username = NULL;
     char *stmpdir = NULL, *top_tmpdir = NULL;
     int f, j, k, stmp_len = 0;
-    char sha1[41];
-    SHA_INFO *sha_info;
-    unsigned char buf[32768];
-    unsigned char sha_data[20];
+    char sha1[cache_name_size + 1];
 
-    if ( (val = par_getenv(PAR_TEMP)) && strlen(val) ) {
+    if ( (val = par_getenv("PAR_TEMP")) && strlen(val) ) {
         par_setup_libpath(val);
         return strdup(val);
     }
@@ -141,12 +182,12 @@
 #ifdef WIN32
     /* Try the windows temp directory */
     if ( tmpdir == NULL && (val = par_getenv("WinDir")) && strlen(val) ) {
-        char* buf = malloc(strlen(val) + 5 + 1);
-        sprintf(buf, "%s\\temp", val);
-        if (isWritableDir(buf)) {
-            tmpdir = buf;
+        char* p = malloc(strlen(val) + 5 + 1);
+        sprintf(p, "%s\\temp", val);
+        if (isWritableDir(p)) {
+            tmpdir = p;
         } else {
-            free(buf);
+            free(p);
         }
     }
 #endif
@@ -221,56 +262,39 @@
 #undef STREQ
     }
 
+    int use_cache = 0;
     if ( !par_env_clean() && (f = open( progname, O_RDONLY | OPEN_O_BINARY ))) 
{
-        /* TODO The following should implement the full search for the PAR 
magic 
-         * string ("\nPAR.pm\n") as implemented in find_par_magic() in 
script/par.pl
-         * and then use that position to look for "\0CACHE".
-         * E.g. signed pp-packed executables don't have "\0CACHE" in position 
18 bytes
-         * from the end of the executables.
-         * But in this case the code below will just resort to compute the 
SHA1 of the 
-         * executable on the fly and thus provide a stable cache directory path
-         * (though perhaps a little less efficient).
-         */
-        lseek(f, -18, 2);
-        read(f, buf, 6);
-        if(buf[0] == 0 && buf[1] == 'C' && buf[2] == 'A' && buf[3] == 'C' && 
buf[4] == 'H' && buf[5] == 'E') {
-            /* pre-computed cache_name in this file */
-            /* "$TEMP/par-$USER/cache-$cache_name" */
-            lseek(f, -58, 2);
-            read(f, buf, 41);
-            sprintf(
-                stmpdir,
-                "%s%scache-%s%s",
-                top_tmpdir, dir_sep, buf, subdirbuf_suffix
-            );
-        }
-        else {
-            /* "$TEMP/par-$USER/cache-$SHA1" */
-           lseek(f, 0, 0);
-            sha_info = sha_init();
-            while( ( j = read( f, buf, sizeof( buf ) ) ) > 0 )
-            {
-                sha_update( sha_info, buf, j );
+        off_t pos = find_par_magic(f);
+        char buf[cache_marker_size];
+
+        if (pos >= 0) {                 
+            /* back up over pack(N) number and "\0CACHE" (or "\0CLEAN") */
+            pos -= FILE_offset_size + cache_marker_size;                  
+            lseek(f, pos, 0); 
+            read(f, buf, cache_marker_size);
+            if (memcmp(buf, "\0CACHE", cache_marker_size) == 0) {
+                use_cache = 1;
+                /* back up over pre-computed cache_name */
+                pos -= cache_name_size;
+                lseek(f, pos, 0);
+                read(f, sha1, cache_name_size);
+                sha1[cache_name_size] = '\0';
             }
-            close( f );
-            sha_final( sha_data, sha_info );
-            for( k = 0; k < 20; k++ )
-            {
-                sprintf( sha1+k*2, "%02x", sha_data[k] );
+            else if (memcmp(buf, "\0CLEAN", cache_marker_size) == 0) {
+                use_cache = 0;
             }
-            sha1[40] = '\0';
-            sprintf(
-                stmpdir,
-                "%s%scache-%s%s",
-                top_tmpdir, dir_sep, sha1, subdirbuf_suffix
-            );
         }
     }
+    if (use_cache) {
+        /* "$TEMP/par-$USER/cache-$SHA1" */
+        sprintf(
+            stmpdir,
+            "%s%scache-%s%s",
+            top_tmpdir, dir_sep, sha1, subdirbuf_suffix
+        );
+    }
     else {
-        int i = 0;
-
         /* "$TEMP/par-$USER/temp-$PID" */
-
         par_setenv("PAR_CLEAN", "1");
         sprintf(
             stmpdir,
@@ -283,7 +307,7 @@
            "$TEMP/par-$USER/temp-$PID-$i". This will guard against cases where
            a prior invocation crashed leaving garbage in a temp directory that
            might interfere. */
-
+        int i = 0;
         while (my_mkdir(stmpdir, 0700) == -1 && errno == EEXIST) {
             sprintf(
                 stmpdir,
@@ -296,7 +320,7 @@
     free(top_tmpdir);
 
     /* set dynamic loading path */
-    par_setenv(PAR_TEMP, stmpdir);
+    par_setenv("PAR_TEMP", stmpdir);
 
     par_setup_libpath( stmpdir );
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/myldr/utils.c 
new/PAR-Packer-1.057/myldr/utils.c
--- old/PAR-Packer-1.056/myldr/utils.c  2022-09-05 11:40:44.000000000 +0200
+++ new/PAR-Packer-1.057/myldr/utils.c  2022-11-26 09:54:33.000000000 +0100
@@ -226,12 +226,8 @@
 }
 
 int par_env_clean () {
-    static int rv = -1;
-
-    if (rv == -1) {
-        char *buf = par_getenv("PAR_CLEAN");
-        rv = ( ((buf == NULL) || (*buf == '\0') || (*buf == '0')) ? 0 : 1);
-    }
-
-    return rv;
+    char *val = par_getenv("PAR_CLEAN");
+    if (val == NULL || *val == '\0' || *val == '0')
+        return 0;
+    return 1;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PAR-Packer-1.056/script/par.pl 
new/PAR-Packer-1.057/script/par.pl
--- old/PAR-Packer-1.056/script/par.pl  2022-09-05 12:07:25.000000000 +0200
+++ new/PAR-Packer-1.057/script/par.pl  2022-11-24 13:52:27.000000000 +0100
@@ -154,13 +154,13 @@
 
 =cut
 
-my ($PAR_MAGIC, $FILE_offset_size, $CACHE_marker, $cache_name_size);
+my ($PAR_MAGIC, $FILE_offset_size, $cache_name_size);
 # NOTE: must initialize them in BEGIN as they are used in BEGIN below
 BEGIN {
     $PAR_MAGIC = "\nPAR.pm\n";
     $FILE_offset_size = 4;   # pack("N")
-    $cache_marker = "\0CACHE";
     $cache_name_size = 40;
+    $PKZIP_MAGIC = "PK\003\004";
 }
 
 
@@ -173,13 +173,12 @@
     my $buf;
     my $size = -s $fh;
 
-    my $pos = $size - $size % $chunk_size;      # NOTE: $pos is a multiple of 
$chunk_size
+    my $pos = ($size-1) - ($size-1) % $chunk_size;      # NOTE: $pos is a 
multiple of $chunk_size
     while ($pos >= 0) {
         seek $fh, $pos, 0;
         read $fh, $buf, $chunk_size + length($PAR_MAGIC);
         if ((my $i = rindex($buf, $PAR_MAGIC)) >= 0) {
-            $pos += $i;
-            return $pos;
+            return $pos + $i;
         }
         $pos -= $chunk_size;
     }
@@ -259,7 +258,7 @@
 outs(qq[\$ENV{PAR_TEMP} = "$ENV{PAR_TEMP}"]);
 
 # Magic string checking and extracting bundled modules {{{
-my ($start_pos, $data_pos);
+my ($start_pos, $start_of_FILE_section);
 MAGIC: {
     local $SIG{__WARN__} = sub {};
 
@@ -277,6 +276,15 @@
     }
     outs("Found PAR magic at position $magic_pos");
 
+    # Check for "\0CACHE" 4 bytes below the signature
+    seek _FH, $magic_pos - $FILE_offset_size - length("\0CACHE"), 0;
+    read _FH, $buf, length("\0CACHE");
+    if ($buf ne "\0CACHE" && $buf ne "\0CLEAN") {
+        outs("No cache marker found");
+        last MAGIC;
+    }
+    outs(qq[Cache marker "$buf" found]);
+
     # Seek 4 bytes backward from the signature to get the offset of the
     # first embedded FILE, then seek to it
     seek _FH, $magic_pos - $FILE_offset_size, 0;
@@ -284,7 +292,7 @@
     my $offset = unpack("N", $buf);
     outs("Offset from start of FILEs is $offset");
     seek _FH, $magic_pos - $FILE_offset_size - $offset, 0;
-    $data_pos = tell _FH;
+    $start_of_FILE_section = tell _FH;
 
     # }}}
 
@@ -384,7 +392,7 @@
 
     # }}}
 
-    unless ($buf eq "PK\003\004") {
+    if ($buf ne $PKZIP_MAGIC) {
         outs(qq[No zip found after FILE section in file "$progname"]);
         last MAGIC ;
     }
@@ -508,7 +516,7 @@
         open my $ph, '<:raw', $par or die qq[Can't read par file "$par": $!];
         my $buf;
         read $ph, $buf, 4;
-        die qq["$par" is not a par file] unless $buf eq "PK\003\004";
+        die qq["$par" is not a par file] unless $buf eq $PKZIP_MAGIC;
         close $ph;
     }
 
@@ -516,7 +524,7 @@
 
     my $fh = IO::File->new(
         $out,
-        IO::File::O_CREAT() | IO::File::O_WRONLY() | IO::File::O_TRUNC(),
+        IO::File::O_CREAT() | IO::File::O_RDWR() | IO::File::O_TRUNC(),
         0777,
     ) or die qq[Can't create file "$out": $!];
     $fh->binmode();
@@ -524,8 +532,8 @@
     seek _FH, 0, 0;
 
     my $loader;
-    if (defined $data_pos) {
-        read _FH, $loader, $data_pos;
+    if (defined $start_of_FILE_section) {
+        read _FH, $loader, $start_of_FILE_section;
     } else {
         local $/ = undef;
         $loader = <_FH>;
@@ -536,18 +544,6 @@
         PAR::Filter::PodStrip->apply(\$loader, $0);
     }
 
-    # Patch a certain string in $loader
-    if ($meta_par{clean}) {
-        my $par_clean = "=1";
-        my $pass_par_clean = uc "__pass_par_clean__";
-        # NOTE: we avoid to mention the contents of pass_par_clean so that
-        # this file doesn't contain it **at all**
-
-        $loader =~ s{(?<=${pass_par_clean})( +)}
-                    {$par_clean . (" " x (length($1) - length($par_clean)))}eg;
-                    # NOTE: the replacement must be the same number of bytes 
as the match
-    }
-
     $fh->print($loader)
         or die qq[Error writing loader to "$out": $!];
     # }}}
@@ -648,24 +644,30 @@
             or die qq[Error writing zip part of "$out"];
     }
 
-    $cache_name = substr $cache_name, 0, $cache_name_size;
-    if (!$cache_name and my $mtime = (stat($out))[9]) {
-        my $ctx = Digest::SHA->new(1);
-        open my $th, "<:raw", $out;
-        $ctx->addfile($th);
-        close $th;
-
-        $cache_name = $ctx->hexdigest;
-    }
-    $cache_name .= "\0" x ($cache_name_size - length $cache_name);
-    $cache_name .= $cache_marker;
-    # compute the offset from the end of $loader to end of "...\0CACHE"
-    my $offset = $fh->tell + length($cache_name) - length($loader);
-    $fh->print($cache_name, 
-               pack('N', $offset),
-               $PAR_MAGIC)
-    && $fh->close
-        or die qq[Error writing trailer of "$out": $!];
+    if ($meta_par{clean}) {
+        $fh->print("\0CLEAN");
+    }
+    else {
+        if (!defined $cache_name) {
+            my $ctx = Digest::SHA->new(1);
+            seek $fh, 0, 0;
+            $ctx->addfile($fh);
+            seek $fh, 0, 2;
+            $cache_name = $ctx->hexdigest;
+        }
+        # truncate $cache_name to 40 byes and fill with NULs if necessary
+        $cache_name = substr $cache_name, 0, $cache_name_size;
+        $cache_name .= "\0" x ($cache_name_size - length $cache_name);
+        $fh->print($cache_name, 
+                   "\0CACHE");
+    }
+
+    # compute the offset from the end of $loader to end of "...\0CACHE" or 
"\0CLEAN"
+    my $offset = $fh->tell - length($loader);
+    $fh->print(pack('N', $offset),
+               $PAR_MAGIC);
+
+    $fh->close or die qq[Error writing trailer of "$out": $!];
     chmod 0755, $out;
     # }}}
 
@@ -833,13 +835,13 @@
             if ((my $magic_pos = find_par_magic($fh)) >= 0) {
                 seek $fh, $magic_pos 
                           - $FILE_offset_size 
-                          - length($cache_marker), 0;
+                          - length("\0CACHE"), 0;
                 my $buf;
-                read $fh, $buf, length($cache_marker);
-                if ($buf eq $cache_marker) {
+                read $fh, $buf, length("\0CACHE");
+                if ($buf eq "\0CACHE") {
                     seek $fh, $magic_pos 
                               - $FILE_offset_size 
-                              - length($cache_marker) 
+                              - length("\0CACHE") 
                               - $cache_name_size, 0;
                     read $fh, $buf, $cache_name_size;
                     $buf =~ s/\0//g;

Reply via email to