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:
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:
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: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 checkPortable/Config.pm
beforeConfig.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: