|Subject:||workaround for 5.15.<0-6> hash bug|
|Date:||Tue, 18 Jul 2017 22:15:23 +0100|
|To:||bug-namespace-clean [...] rt.cpan.org|
|From:||Zefram <zefram [...] fysh.org>|
There's a hash bug in some old versions of the Perl core that namespace::clean could helpfully work around. The attached patch does so. The bug is concerned with the timing of the freeing of a value deleted from a hash when hv_delete_ent() is passed the G_DISCARD flag. From Perl version 5.15.0 to 5.15.6 inclusive, the value would have its refcount decreased before actually being removed from the hash, so if the value has a destructor and that causes some operation on the hash then it sees the hash in an inconsistent state and mayhem can ensue. The bug doesn't manifest for me in namespace-clean's test suite, but shows up in namespace-autoclean's test suite. The bug actually arises from the deletion of a glob via ->remove_glob provided by either version of Package::Stash. I've proposed a patch for Package-Stash-XS in [rt.cpan.org #122525], but that hasn't had a release in ages, so as a temporary measure it seems worth working around it in namespace-clean. Package::Stash::XS doesn't give the caller any choice about whether it'll pass the G_DISCARD flag, but Package::Stash::PP does, through the context in which ->remove_glob is called. The patch therefore, on the affected Perl versions, has namespace::clean use Package::Stash::PP and put the ->remove_glob call into scalar context. Behaviour on other Perl versions is unaffected. The patch also adds a test, derived from namespace::autoclean's failing test, by minimisation and the incorporation of the relevant parts of namespace::autoclean. Of course, the affected Perl versions are only development versions, and are nominally obsolete, so the impact of this problem is limited. But it is useful to test modules against old dev versions, especially when a module has version-dependent problems, in which case seeing which dev versions are affected is very revealing. I therefore like to keep as much infrastructure as possible working on those old versions that aren't total lemons. Quite a few modules these days use namespace::autoclean, and testing those on old versions is how I ran into this problem. -zefram
Message body is not shown because sender requested not to inline it.