Hi Tye,
While it's true that SvPV_nolen is safer for reading, SvPVX and SvPV_nolen are equally dangerous with regards to the write operation that TheDauthi wants to deploy. In both cases, it is absolutely necessary to...
The SvPV_nolen macro first checks the SV's private SVf_POK flag to see whether it contains a string. If it does, then it returns the pointer to the string, via SvPVX(SV*). If it doesn't, it calls sv_2pv_flags, which spits out a Use of uninitialized value warning, upgrades the sv, and returns (char*)"". That's safe to read from, but if you try to write to it... kaboom.
Here's a demo app...
#!/usr/bin/perl use strict; use warnings; use Inline C => <<'END_C'; void POKe() { SV *good_sv, *bad_sv; char *good_ptr, *bad_ptr; good_sv = newSV(83); bad_sv = newSV(83); SvPOK_on(good_sv); /* !!!! */ good_ptr = SvPV_nolen(good_sv); Copy("Joy!", good_ptr, 4, char); SvCUR_set(good_sv, 4); fprintf(stderr, "%s\n", SvPVX(good_sv)); bad_ptr = SvPV_nolen(bad_sv); fprintf(stderr, "wait for it...\n"); Copy("DEATH!", bad_ptr, 6, char); fprintf(stderr, "in heaven, everything is fine..."); } END_C POKe();
... and here's the output on my system...
slothbear:~/perltest marvin$ perl sv_poke.plx Joy! Use of uninitialized value in subroutine entry at sv_poke.plx line 33. wait for it... Bus error slothbear:~/perltest marvin$
In reply to Re^4: XS efficient copy (SvCUR_set)
by creamygoodness
in thread XS efficient copy
by TheDauthi
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |