diff options
Diffstat (limited to 'src/pl/plperl/plperl_helpers.h')
-rw-r--r-- | src/pl/plperl/plperl_helpers.h | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/pl/plperl/plperl_helpers.h b/src/pl/plperl/plperl_helpers.h index 800a408ac4c..35e1257457f 100644 --- a/src/pl/plperl/plperl_helpers.h +++ b/src/pl/plperl/plperl_helpers.h @@ -47,28 +47,35 @@ sv2cstr(SV *sv) { char *val, *res; STRLEN len; - SV *nsv; /* * get a utf8 encoded char * out of perl. *note* it may not be valid utf8! * * SvPVutf8() croaks nastily on certain things, like typeglobs and * readonly objects such as $^V. That's a perl bug - it's not supposed to - * happen. To avoid crashing the backend, we make a copy of the - * sv before passing it to SvPVutf8(). The copy is garbage collected + * happen. To avoid crashing the backend, we make a copy of the sv before + * passing it to SvPVutf8(). The copy is garbage collected * when we're done with it. */ - nsv = newSVsv(sv); - val = SvPVutf8(nsv, len); + if (SvREADONLY(sv) || + isGV_with_GP(sv) || + (SvTYPE(sv) > SVt_PVLV && SvTYPE(sv) != SVt_PVFM)) + sv = newSVsv(sv); + else + /* increase the reference count so we cant just SvREFCNT_dec() it when + * we are done */ + SvREFCNT_inc(sv); + + val = SvPVutf8(sv, len); /* * we use perl's length in the event we had an embedded null byte to ensure * we error out properly */ - res = utf_u2e(val, len); + res = utf_u2e(val, len); /* safe now to garbage collect the new SV */ - SvREFCNT_dec(nsv); + SvREFCNT_dec(sv); return res; } |