rschupp / PAR-Packer

(perl) Generate stand-alone executables, perl scripts and PAR files https://metacpan.org/pod/PAR::Packer
Other
48 stars 13 forks source link

`par.exe -b` failure with Portable::Config #13

Closed puetzk closed 5 years ago

puetzk commented 5 years ago

When building PAR with strawberryperl portable, parldyn (par.exe -B -Oparldyn.exe packs both lib/Config.pm and vendor/lib/Portable/Config.pm. par.exe -b -Oparltiny.exe packs only vendor/lib/Portable/Config.pm. This is the desired behavior. However, when launching, things go wrong in parltiny:

Global symbol "%Config" requires explicit package name (did you forget to declare "my %Config"?) at C:/.../perl/lib/Errno.pm line 12. Global symbol "%Config" requires explicit package name (did you forget to declare "my %Config"?) at C:/.../perl/lib/Errno.pm line 12. Execution of C:/.conan/a84e8d/1/perl/lib/Errno.pm aborted due to compilation errors. Compilation failed in require at C:/.../perl/lib/File/Temp.pm line 152. BEGIN failed--compilation aborted at C:/.../perl/lib/File/Temp.pm line 152. Compilation failed in require at C:/.../perl/vendor/lib/Archive/Zip.pm line 11. BEGIN failed--compilation aborted at C:/.../perl/vendor/lib/Archive/Zip.pm line 11. Compilation failed in require at -e line 141.

This seems to behappening because the function added to @INC is only checking a suffix match on the path:

https://github.com/rschupp/PAR-Packer/blob/5a98e29745d4f6dcae748787fcd0d47db77c76e9/script/par.pl#L304-L307

So when use Config; gets resolved to a call looking with $module equal to 'Config.pm', it thinks 'Portable/Config.pm' is a match, and returns the wrong file's body. So the wrong thing gets loaded, and %Config isn't defined (and then things go downhill from there, of course, given how central Config.pm is).

As far as I can tell, there was at least a risk of this happening in the parldyn case too, since the order of keys in foreach (keys %require_list) is not specified. If it had happened to check Portable/Config.pm before Config.pm, it could have picked the wrong thing for parldyn (where both were in %require_list) too.

There doesn't seem to be any prefix on the files here, so I'm not sure why this is a regex suffix match instead of just equality:


@@ -304,4 +304,4 @@
             foreach (keys %require_list) {
-                next unless /\Q$module\E$/;
+                next unless $_ eq $module;
                 $key = $_; last;
             }
rschupp commented 5 years ago

I can't figure out what the do block was meant to achieve (I didn't write this code), so I just removed it. Can you retry with HEAD?