diff --git a/lib/utf8.t b/lib/utf8.t index d35110baee07..fa69fcbb8862 100644 --- a/lib/utf8.t +++ b/lib/utf8.t @@ -669,6 +669,9 @@ for(__PACKAGE__) { eval { utf8::upgrade($_) }; is $@, "", 'no error with utf8::upgrade on read-only COW'; } + +is(utf8::upgrade(undef), undef, "Returns undef for undef input"); # GH #20419 + # This one croaks, but not because the scalar is read-only eval "package \x{100};\n" . <<'END' for(__PACKAGE__) { diff --git a/universal.c b/universal.c index 119117e818a4..20a36fae8517 100644 --- a/universal.c +++ b/universal.c @@ -593,11 +593,21 @@ XS(XS_utf8_upgrade) croak_xs_usage(cv, "sv"); else { SV * const sv = ST(0); - STRLEN RETVAL; + STRLEN RETVAL = 0; dXSTARG; - RETVAL = sv_utf8_upgrade(sv); - XSprePUSH; PUSHi((IV)RETVAL); + XSprePUSH; + if (UNLIKELY(! sv)) { + XSRETURN_UNDEF; + } + + SvGETMAGIC(sv); + if (UNLIKELY(! SvOK(sv))) { + XSRETURN_UNDEF; + } + + RETVAL = sv_utf8_upgrade_nomg(sv); + PUSHi( (IV) RETVAL); } XSRETURN(1); }