There's no reason for set_pv to create a new buffer whose length is based on the old string buffer's length.
Except that, with earlier perls, the new buffer is the same length as the old buffer - so this is a change in behaviour, and one that I did not expect.
Let's say there's another XSub to which I want to subsequently pass that buffer, and it's an XSub that requires the buffer to have at least (say) 50 bytes available. For example:
void bar(unsigned char * buffer) {
buffer[49] = 65;
}
On perl 5.40.0 I could re-use that PV that I created in the demo and pass it to
bar(), because its SvLEN is still guaranteed to be at least 60.
But on perl-5.42.0, SvLEN has been reduced to 16, so passing that PV to
bar() will result in the buffer being overflowed.
At least, that's the way it looks to me. (And I'm assuming that such buffer overflow is something to be avoided.)
Nothing that can't be dealt with, of course - but nonetheless surprising.
Here's a second script that demonstrates that change in behaviour:
use strict;
use warnings;
use Devel::Peek;
use Inline C =><<'EOC';
void foo(SV * buffer) {
char *data = "Hello there";
sv_setpv(buffer, data);
}
void bar(unsigned char * buffer) {
buffer[49] = 65;
}
void _set_CUR(SV * buffer, int bytes) {
SvCUR_set(buffer, bytes);
}
EOC
my $buffer = 'z' x 60;
Dump $buffer;
foo($buffer);
Dump $buffer;
bar($buffer);
_set_CUR($buffer, 60); # Ensure that Devel::Peek::Dump will display al
+l 60 bytes.
Dump $buffer;
On perl-5.40.0 and earlier, the final Devel::Peek::Dump reveals exactly what I expect:
SV = PV(0x254ba8dbf08) at 0x254ba920660
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x254bce10dc8 "Hello there\x00zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
+zzzzAzzzzzzzzzz"\0
CUR = 60
LEN = 62
On perl-5.42.0, the final Dump appears as:
SV = PV(0x224fe4c0aa0) at 0x224fe4f4cd0
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x22480c0e170 "Hello there\x00\x00\x00\x00\x00\x00\x00\x00\x00\
+x00\x00\x00\x00\r\x8B7\xBC\x00\xF8\x00\x88\xC0\x82\x9F\x80$\x02\x00\x
+00\x00\x00\x00\x00\x00\x00\x00\x00\x10A\x8D\x80$\x02\x00\x00\x00\xB5K
+\xFE"
CUR = 60
LEN = 16
(The 'A' at index 49 can be seen if you look closely.)
However, no-one else has been bothered by this - so I guess I just deal with it appropriately.
I do have a working solution to my issue that avoids
sv_setpv and avoids re-using the same PV. (I might try improving it, but I think it's good enough as it already stands. And it's probably the same as the solution I would have used even if this change of behaviour in 5.42.0 did not exist.)
Thank
you for all of the detail, BTW - much appreciated.
In fact, thank you to
all respondents.
Cheers,
Rob
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.