summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2022-07-19 15:58:35 +1000
committerTony Cook <tony@develop-help.com>2022-11-08 10:12:46 +1100
commit545d49904504b40413906fbf113de96011815266 (patch)
tree522c3c9281780c6e9aec140fdfc1e2aba1125885
parent36667169c25b9ddadd6e06a4c620730fbe42a294 (diff)
downloadperl-545d49904504b40413906fbf113de96011815266.tar.gz
improve error reporting by store_hook() on an unknown type
This produced an opaque message when it was asked to freeze an object of an unsupported type. Changes: - replace the opaque internal object type number with the typical perl name of the type ("GLOB" instead of "8") - include the class of the object being frozen to identify which class needs work - include name of the function we're trying to call to do the freeze, if possible
-rw-r--r--dist/Storable/Storable.xs20
-rw-r--r--dist/Storable/t/blessed.t24
2 files changed, 38 insertions, 6 deletions
diff --git a/dist/Storable/Storable.xs b/dist/Storable/Storable.xs
index 682a78e912..67ebba8afb 100644
--- a/dist/Storable/Storable.xs
+++ b/dist/Storable/Storable.xs
@@ -3583,7 +3583,10 @@ static int store_hook(
int need_large_oids = 0;
#endif
- TRACEME(("store_hook, classname \"%s\", tagged #%d", HvNAME_get(pkg), (int)cxt->tagnum));
+ classname = HvNAME_get(pkg);
+ len = strlen(classname);
+
+ TRACEME(("store_hook, classname \"%s\", tagged #%d", classname, (int)cxt->tagnum));
/*
* Determine object type on 2 bits.
@@ -3631,13 +3634,20 @@ static int store_hook(
}
break;
default:
- CROAK(("Unexpected object type (%d) in store_hook()", type));
+ {
+ /* pkg_can() always returns a ref to a CV on success */
+ CV *cv = (CV*)SvRV(hook);
+ const GV * const gv = CvGV(cv);
+ const char *gvname = GvNAME(gv);
+ const HV * const stash = GvSTASH(gv);
+ const char *hvname = stash ? HvNAME(stash) : NULL;
+
+ CROAK(("Unexpected object type (%s) of class '%s' in store_hook() calling %s::%s",
+ sv_reftype(sv, FALSE), classname, hvname, gvname));
+ }
}
flags = SHF_NEED_RECURSE | obj_type;
- classname = HvNAME_get(pkg);
- len = strlen(classname);
-
/*
* To call the hook, we need to fake a call like:
*
diff --git a/dist/Storable/t/blessed.t b/dist/Storable/t/blessed.t
index d9a77b3723..398f21f80e 100644
--- a/dist/Storable/t/blessed.t
+++ b/dist/Storable/t/blessed.t
@@ -44,7 +44,7 @@ use Storable qw(freeze thaw store retrieve fd_retrieve);
'long VSTRING' => \(my $lvstring = eval "v" . 0 x 300),
LVALUE => \(my $substr = substr((my $str = "foo"), 0, 3)));
-my $test = 13;
+my $test = 14;
my $tests = $test + 41 + (2 * 6 * keys %::immortals) + (3 * keys %::weird_refs);
plan(tests => $tests);
@@ -414,3 +414,25 @@ is(ref $t, 'STRESS_THE_STACK');
unlink("store$$");
}
+
+{
+ # trying to freeze a glob via STORABLE_freeze
+ {
+ package GlobHookedBase;
+
+ sub STORABLE_freeze {
+ return \1;
+ }
+
+ package GlobHooked;
+ our @ISA = "GlobHookedBase";
+ }
+ use Symbol ();
+ my $glob = bless Symbol::gensym(), "GlobHooked";
+ eval {
+ my $data = freeze($glob);
+ };
+ my $msg = $@;
+ like($msg, qr/Unexpected object type \(GLOB\) of class 'GlobHooked' in store_hook\(\) calling GlobHookedBase::STORABLE_freeze/,
+ "check we get the verbose message");
+}