Skip Menu |

This queue is for tickets about the Socket CPAN distribution.

Report information
The Basics
Id: 79557
Status: resolved
Priority: 0/
Queue: Socket

People
Owner: Nobody in particular
Requestors: dolmen [...] cpan.org
IKEGAMI [...] cpan.org
tlhackque [...] yahoo.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.006
Fixed in: 2.018



Subject: Spurrious "addr is not a string" error
This problem caused me quite some headaches, but I understand if you don't care... On a system still running 5.8.8 / 2.6.17-1.2142_FC4 (and yes, it is scheduled to upgrade, but...), I installed Socket 2.006 for some IPV6 work. A small chunk of code calls getnameinfo with the output of getaddrinfo. It works standalone, but fails under apache httpd. The very same inputs. This is quite strange. In Socket.xs, we have: if(!SvPOK(addr)) croak("addr is not a string"); I have no clue why we hit this croak. I put a fair bit of diagnostic code into the xs, and tested for refs, arrays, hashs - in fact everything. addr wasn't any of those. I dumped addr from the perl side and verified that yes, what was being passed is in fact a valid adddress string. I tried various things: passing the string in a scalar, introducing a subroutine. Nothing worked. BUT, remember that the same code works stand-alone... Finally, I simply commented-out the test, and everything "works" - in that the correct data is returned for a few hundred test cases. I know 5.8.8 is old, but worry that the issue may appear under more recent versions. I'm not an XS expert, but it has the feel of an incorrect reference count or some such. So I thought I should report it. Here is the code. It is passed an IP address (V4 or V6) as a string. It returns the corresponding host name, or an empty string. The eval is only to catch this error (since Socket is supplying and consuming the data, it "shouldn't happen".) One other thing - what's supposed to happen with an address that has multiple names? getnameinfo doesn't seem to suppor this. gethostbyaddr did - and it's not uncommon for one address to have multiple PTR records in IPV4... Thanks. #!/usr/bin/perl -d use strict; use warnings; use Socket qw( :addrinfo inet_ntoa inet_aton SOCK_RAW PF_INET PF_INET6 ); sub getHostFromAddr($) { my $addr = shift; my( $error, @addrs ) = getaddrinfo( $addr, 0, { flags => AI_NUMERICHOST } ); return '' if( $error ); my $name; eval { ($error, $name, undef) = getnameinfo( $addrs[0]->{addr}, NI_NAMEREQD, NIx_NOSERV ); }; return '' if( $@ ); return '' if( $error ); return $name; } my $x = '192.168.148.108'; print getHostFromAddr($x);
Subject: getnameinfo fails in taint mode (data from getaddrinfo)
From: tlhackque [...] yahoo.com
I have finally tracked this down. It still exists in V2.007, and with Perl Version 5.14.3. And this time I think everyone shoud care. The problem arises when getaddrinfo is passed a tainted name. When this happens, the @results[n]->{addr} data is tainted. getnameinfo checks this argument, and finds (as previously reported, but not understood) that SvPOK is false. It croaks with the highly misleading "addr is not a string". This is confirmed with the diagnostic code shown below, which reports the data as tainted. And the croak disappears if the data is untainted going in to getaddrinfo. Issues: * I did not find mention in the documentation that tainted data causes SvPOK to be turned off. SvPOK is documented to mean "variable contains a string. Tainted or not, it does contain a string... * It's not obvious (or documented) that either function is sensitive to taint mode. At a minimum, this needs to be documented. * Since getnameinfo doesn't eval or do anything dangerous with the string, why not allow this call to succeed? Tainting the output would be acceptable. * If it is deemed desirable to disallow tainted input, please incorporate something like the diagnostic code shown below. "Insecure dependency" or "Argument is tainted" are the conventional flags - and that would have saved me many, many hours of debugging. (Yes, it's obvious in hindsight...) I have updated the reproducer to make it clear that it runs -T and that the input comes from a CGI. My diagnostic patch follows. Thanks. --- Socket.xs~ 2012-12-16 13:24:00.000000000 -0500 +++ Socket.xs 2012-12-19 13:12:07.124222787 -0500 @@ -529,13 +529,16 @@ xflags = SvIV(ST(2)); want_host = !(xflags & NIx_NOHOST); want_serv = !(xflags & NIx_NOSERV); - if(!SvPOK(addr)) - croak("addr is not a string"); - + if(!SvPOK(addr)) { + if( SvTAINTED(addr) ) + croak( "Insecure dependency: addr is tainted." ); + else + croak("addr is not a string"); + } addr_len = SvCUR(addr); /* We need to ensure the sockaddr is aligned, because a random SvPV might * not be due to SvOOK */ Newx(sa, addr_len, char); On Mon Sep 10 17:21:56 2012, tlhackque wrote: Show quoted text
> This problem caused me quite some headaches, but I understand if you > don't care... > > On a system still running 5.8.8 / 2.6.17-1.2142_FC4 (and yes, it is > scheduled to upgrade, but...), I installed Socket 2.006 for some IPV6 > work. > > A small chunk of code calls getnameinfo with the output of
getaddrinfo. Show quoted text
> > It works standalone, but fails under apache httpd. The very same > inputs. This is quite strange. > > In Socket.xs, we have: > if(!SvPOK(addr)) > croak("addr is not a string"); > > I have no clue why we hit this croak. I put a fair bit of diagnostic > code into the xs, and tested for refs, arrays, hashs - in fact > everything. addr wasn't any of those. I dumped addr from the perl > side and verified that yes, what was being passed is in fact a valid > adddress string. I tried various things: passing the string in a > scalar, introducing a subroutine. Nothing worked. BUT, remember that > the same code works stand-alone... > > Finally, I simply commented-out the test, and everything "works" - in > that the correct data is returned for a few hundred test cases. > > I know 5.8.8 is old, but worry that the issue may appear under more > recent versions. I'm not an XS expert, but it has the feel of an > incorrect reference count or some such. So I thought I should report > it. > > Here is the code. It is passed an IP address (V4 or V6) as a string. > It returns the corresponding host name, or an empty string. > > The eval is only to catch this error (since Socket is supplying and > consuming the data, it "shouldn't happen".) > > One other thing - what's supposed to happen with an address that has > multiple names? getnameinfo doesn't seem to suppor this. > gethostbyaddr did - and it's not uncommon for one address to have > multiple PTR records in IPV4... > > Thanks. > > #!/usr/bin/perl -dT > use strict; > use warnings; > use Socket qw( :addrinfo inet_ntoa inet_aton SOCK_RAW PF_INET > PF_INET6 ); > > sub getHostFromAddr($) { > my $addr = shift; > > my( $error, @addrs ) = getaddrinfo( $addr, 0, { flags => > AI_NUMERICHOST } ); > return '' if( $error ); > > my $name; > eval { > ($error, $name, undef) = getnameinfo( $addrs[0]->{addr}, > NI_NAMEREQD, NIx_NOSERV ); > }; return '' if( $@ ); > return '' if( $error ); > > return $name; > } > > my $x = $query->param('address'); # Value eq '192.168.148.108'; > print getHostFromAddr($x);
On Wed Dec 19 13:21:04 2012, tlhackque wrote: Show quoted text
> I have finally tracked this down. It still exists in V2.007, and with > Perl Version 5.14.3. And this time I think everyone shoud care. > > The problem arises when getaddrinfo is passed a tainted name. > > When this happens, the @results[n]->{addr} data is tainted. > > getnameinfo checks this argument, and finds (as previously reported, > but not understood) that SvPOK is false. It croaks with the highly > misleading "addr is not a string".
This still sounds like a weird cornercase. I can't reproduce it though - it appears to obey taint mode just fine for me: $ perl -T taint.pl gethostbyaddr(untaint) => untaint getnameinfo(untaint) => untaint gethostbyaddr(TAINT) => TAINT getnameinfo(TAINT) => TAINT [find attached] See if it works for you. -- Paul Evans
Subject: taint.pl
#!/usr/bin/perl -T use Socket qw( pack_sockaddr_in inet_aton getnameinfo ); use Taint::Util qw( taint tainted ); sub taintstr { tainted($_[0]) ? "TAINT" : "untaint" } foreach my $taint ( 0, 1 ) { my $addr = pack_sockaddr_in 0, inet_aton("192.168.42.2"); my $taddr = $addr; taint $taddr if $taint; my $host = gethostbyaddr $taddr, Socket::AF_INET; printf "gethostbyaddr(%s) => %s\n", taintstr($taddr), taintstr($host); my ( $err, $hname ) = getnameinfo( $taddr ); die $err if $err; printf "getnameinfo(%s) => %s\n", taintstr($taddr), taintstr($hname); }
Subject: Re: [rt.cpan.org #79557] Spurrious "addr is not a string" error
Date: Wed, 12 Feb 2014 11:28:24 -0500
To: bug-Socket [...] rt.cpan.org
From: tlhackque <tlhackque [...] yahoo.com>
On 12-Feb-14 10:00, Paul Evans via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=79557 > > > On Wed Dec 19 13:21:04 2012, tlhackque wrote:
>> I have finally tracked this down. It still exists in V2.007, and with >> Perl Version 5.14.3. And this time I think everyone shoud care. >> >> The problem arises when getaddrinfo is passed a tainted name. >> >> When this happens, the @results[n]->{addr} data is tainted. >> >> getnameinfo checks this argument, and finds (as previously reported, >> but not understood) that SvPOK is false. It croaks with the highly >> misleading "addr is not a string".
> This still sounds like a weird cornercase. I can't reproduce it though - it appears to obey taint mode just fine for me: > > $ perl -T taint.pl > gethostbyaddr(untaint) => untaint > getnameinfo(untaint) => untaint > gethostbyaddr(TAINT) => TAINT > getnameinfo(TAINT) => TAINT > > [find attached] > > See if it works for you. >
Thanks for looking at this. Your test case fails for me. Here's what I get: |perl -T taint.pl||| |||gethostbyaddr(untaint) => untaint||| |||getnameinfo(untaint) => untaint||| |||gethostbyaddr(TAINT) => TAINT||| |||addr is not a string at taint.pl line 18.||| |||| |||perl --version||| |||| |||This is perl 5, version 14, subversion 3 (v5.14.3) built for x86_64-linux-thread-multi||| |||| |||cat /proc/sys/kernel/osrelease||| |||3.7.3-101.fc17.x86_64||| cat /etc/redhat-release Fedora release 17 (Beefy Miracle) perl -MSocket -e'print $Socket::VERSION' 2.001 || I then made a slight change to your code, replacing lines 18/19 with: | my( $err, $hname ); eval { ( $err, $hname ) = getnameinfo( $taddr ); die "ERROR:$err" if $err; }; if( $@ ) { print "EXCEPTION: $@"; exit; } ./taint.pl gethostbyaddr(untaint) => untaint getnameinfo(untaint) => untaint gethostbyaddr(TAINT) => TAINT EXCEPTION: addr is not a string at ./taint.pl line 20.| This reconfirms that the error is coming from inside getnameinfo, and being reported as an exception, not your die. I upgraded to Socket 2.013 from cpan, no change. When I last looked into this issue, I patched Socket to debug this and discovered that SvPOK was returning false for the failing case. It was rather painful. I don't know enough Perl internals to understand why SvPOK is behaving this way. I've learned to untaint arguments to avoid the issue, but this isn't the right fix. Below is the list of installed packages on the system I just tested. Anything else I can do to help? |yum list installed | grep -P '^perl'||| |||perl.x86_64 4:5.14.3-219.fc17 @updates|| pperl-AnyEvent.noarch 5.27-7.fc17 @anaconda-0||| |||perl-AnyEvent-AIO.noarch 1.1-8.fc17 @anaconda-0||| |||perl-AnyEvent-BDB.noarch 1.1-7.fc17 @anaconda-0||| |||perl-Async-MergePoint.noarch 0.03-7.fc17 @anaconda-0||| |||perl-BDB.x86_64 1.88-5.fc17 @anaconda-0||| |||perl-BSD-Resource.x86_64 1.29.04-9.fc17 @anaconda-0||| |||perl-CGI.noarch 3.52-218.fc17 @updates||| |||perl-CPAN.noarch 1.9600.01-219.fc17 @updates||| |||perl-Carp.noarch 1.22-2.fc17 @anaconda-0||| |||perl-Class-ISA.noarch 0.36-1007.fc17 @anaconda-0||| |||perl-Compress-Raw-Bzip2.x86_64 2.052-1.fc17 @anaconda-0||| |||perl-Compress-Raw-Zlib.x86_64 2.052-1.fc17 @anaconda-0||| |||perl-Coro.x86_64 6.07-3.fc17 @anaconda-0||| |||perl-Curses.x86_64 1.28-5.fc17 @anaconda-0||| |||perl-DBD-SQLite.x86_64 1.35-2.fc17 @fedora||| |||perl-DBI.x86_64 1.617-1.fc17 @anaconda-0||| |||perl-Date-Manip.noarch 6.30-1.fc17 @anaconda-0||| |||perl-Digest.noarch 1.17-2.fc17 @anaconda-0||| |||perl-Digest-MD5.x86_64 2.51-219.fc17 @updates||| |||perl-Digest-SHA.x86_64 1:5.61-219.fc17 @updates||| |||perl-EV.x86_64 4.03-8.fc17 @anaconda-0||| |||perl-Encode-Locale.noarch 1.02-5.fc17 @anaconda-0||| |||perl-Error.noarch 1:0.17016-7.fc17 @anaconda-0||| |||perl-Event.x86_64 1.20-1.fc17 @anaconda-0||| |||perl-Event-Lib.x86_64 1.03-16.fc17 @anaconda-0||| |||perl-ExtUtils-Install.noarch 1.56-219.fc17 @updates||| |||perl-ExtUtils-MakeMaker.noarch 6.62-2.fc17 @anaconda-0||| |||perl-ExtUtils-Manifest.noarch 1.60-1.fc17 @anaconda-0||| |||perl-ExtUtils-ParseXS.noarch 1:2.2210-219.fc17 @updates||| |||perl-FCGI.x86_64 1:0.74-2.fc17 @anaconda-0||| |||perl-File-Listing.noarch 6.03-2.fc17 @anaconda-0||| |||perl-Git.noarch 1.7.11.7-2.fc17 @updates||| |||perl-Glib.x86_64 1.241-2.fc17 @anaconda-0||| |||perl-Guard.x86_64 1.022-1.fc17 @anaconda-0||| |||perl-HTML-Parser.x86_64 3.69-3.fc17 @anaconda-0||| |||perl-HTML-Tagset.noarch 3.20-10.fc17 @anaconda-0||| |||perl-HTTP-Cookies.noarch 6.00-4.fc17 @anaconda-0||| |||perl-HTTP-Daemon.noarch 6.00-4.fc17 @anaconda-0||| |||perl-HTTP-Date.noarch 6.00-3.fc17 @anaconda-0||| |||perl-HTTP-Message.noarch 6.03-1.fc17 @anaconda-0||| |||perl-HTTP-Negotiate.noarch 6.00-4.fc17 @anaconda-0||| |||perl-HTTP-Tiny.noarch 0.012-219.fc17 @updates||| |||perl-Heap.noarch 0.80-10.fc17 @anaconda-0||| |||perl-IO-AIO.x86_64 4.15-1.fc17 @anaconda-0||| |||perl-IO-Async.noarch 0.29-7.fc17 @anaconda-0||| |||perl-IO-Compress.noarch 2.052-1.fc17 @anaconda-0||| |||perl-IO-Socket-INET6.noarch 2.69-1.fc17 @fedora||| |||perl-IO-Socket-IP.noarch 0.14-1.fc17 @updates||| |||perl-IO-Socket-SSL.noarch 1.66-1.fc17 @anaconda-0||| |||perl-IO-Tty.x86_64 1.10-8.fc17 @updates||| |||perl-LWP-MediaTypes.noarch 6.01-4.fc17 @anaconda-0||| |||perl-Linux-Pid.x86_64 0.04-14.fc17 @anaconda-0||| |||perl-Locale-Codes.noarch 3.24-1.fc17 @updates||| |||perl-Module-Pluggable.noarch 1:3.90-219.fc17 @updates||| |||perl-Net-HTTP.noarch 6.02-2.fc17 @anaconda-0||| |||perl-Net-LibIDN.x86_64 0.12-8.fc17 @anaconda-0||| |||perl-Net-SSLeay.x86_64 1.48-1.fc17 @anaconda-0||| |||perl-Newt.x86_64 1.08-31.fc17 @anaconda-0||| |||perl-POE.noarch 1.350-2.fc17 @anaconda-0||| |||perl-PathTools.x86_64 3.33-219.fc17 @updates||| |||perl-PathTools-debuginfo.x86_64 3.33-5.fc17 @fedora-debuginfo||| |||perl-Pod-Escapes.noarch 1:1.04-219.fc17 @updates||| |||perl-Pod-Perldoc.noarch 3.17-2.fc17 @updates||| |||perl-Pod-Plainer.noarch 1.03-1.fc17 @anaconda-0||| |||perl-Pod-Simple.noarch 1:3.16-219.fc17 @updates||| |||perl-SGMLSpm.noarch 1.03ii-27.fc17 @anaconda-0||| |||perl-Scalar-List-Utils.x86_64 1.25-1.fc17 @anaconda-0||| |||perl-Scalar-List-Utils-debuginfo.x86_64||| |||perl-Socket.x86_64 2.001-1.fc17 @fedora||| |||perl-Socket-GetAddrInfo.x86_64 0.19-1.fc17 @anaconda-0||| |||perl-Socket6.x86_64 0.23-8.fc17 @anaconda-0||| |||perl-Sys-CPU.x86_64 0.51-8.fc17 @anaconda-0||| |||perl-Sys-MemInfo.x86_64 0.91-1.fc17 @anaconda-0||| |||perl-TermReadKey.x86_64 2.30-14.fc17 @anaconda-0||| |||perl-TermReadKey-debuginfo.x86_64 2.30-14.fc17 @fedora-debuginfo||| |||perl-Test-Harness.noarch 3.23-219.fc17 @updates||| |||perl-Test-Simple.noarch 0.98-219.fc17 @updates||| |||perl-TimeDate.noarch 1:1.20-6.fc17 @anaconda-0||| |||perl-URI.noarch 1.60-1.fc17 @anaconda-0||| |||perl-WWW-RobotRules.noarch 6.01-4.fc17 @anaconda-0||| |||perl-XML-Parser.x86_64 2.41-4.fc17 @anaconda-0||| |||perl-YAML.noarch 0.81-2.fc17 @fedora||| |||perl-YAML-Syck.x86_64 1.17-4.fc17 @fedora||| |||perl-common-sense.noarch 3.5-1.fc17 @anaconda-0||| |||perl-debuginfo.x86_64 4:5.14.3-219.fc17 @updates-debuginfo||| |||perl-devel.x86_64 4:5.14.3-219.fc17 @updates||| |||perl-libs.x86_64 4:5.14.3-219.fc17 @updates||| |||perl-libwww-perl.noarch 6.03-2.fc17 @anaconda-0||| |||perl-macros.x86_64 4:5.14.3-219.fc17 @updates||| |||perl-parent.noarch 1:0.225-219.fc17 @updates||| |||perl-threads.x86_64 1.86-2.fc17 @anaconda-0||| |||perl-threads-shared.x86_64 1.40-2.fc17 @anaconda-0||| || |cpan[1]> i Socket||| |||Database was generated on Mon, 10 Feb 2014 22:25:01 GMT||| |||Module id = Socket||| ||| DESCRIPTION Defines socket-related constants||| ||| CPAN_USERID PEVANS (Paul Evans <leonerd@leonerd.org.uk>)||| ||| CPAN_VERSION 2.013||| ||| CPAN_FILE P/PE/PEVANS/Socket-2.013.tar.gz||| ||| DSLIP_STATUS Smcfp (standard,mailing-list,C,functions,Standard-Perl)||| ||| MANPAGE C<Socket> - networking constants and support functions||| ||| INST_FILE /usr/lib64/perl5/vendor_perl/Socket.pm||| ||| INST_VERSION 2.001||| ||||(I installed 2.013 and retested.) || -- This communication may not represent my employer's views, if any, on the matters discussed.

Message body is not shown because it is too large.

On Mon Sep 10 17:21:56 2012, tlhackque wrote: Show quoted text
> In Socket.xs, we have: > if(!SvPOK(addr)) > croak("addr is not a string"); > > I have no clue why we hit this croak.
Socket.xs forgot to account for magic. addr = ST(0); should be addr = ST(0); SvGETMAGIC(addr) Demo: $ perl -E' use strict; use warnings; use IO::Socket::IP qw( ); use Socket qw( getnameinfo ); sub _chomp { my ($s) = @_; chomp($s); $s } my $socket = IO::Socket::IP->new( PeerHost => "www.google.com:80" ) or die $@; my ($err, $hostname, $servicename) = eval { getnameinfo($socket->peername) }; say $err || _chomp($@) || $hostname; $socket->peername =~ /(.*)/s; ($err, $hostname, $servicename) = eval { getnameinfo($1) }; say $err || _chomp($@) || $hostname; { no warnings "void"; "$1"; } ($err, $hostname, $servicename) = eval { getnameinfo($1) }; say $err || _chomp($@) || $hostname; ' sea15s02-in-f4.1e100.net addr is not a string at -e line 18. sea15s02-in-f4.1e100.net
On Wed Jan 28 16:48:30 2015, ikegami wrote: Show quoted text
> On Mon Sep 10 17:21:56 2012, tlhackque wrote:
> > In Socket.xs, we have: > > if(!SvPOK(addr)) > > croak("addr is not a string"); > > > > I have no clue why we hit this croak.
> > Socket.xs forgot to account for magic. > > addr = ST(0); > > should be > > addr = ST(0); > SvGETMAGIC(addr)
I don't use taint -- just boring use of LWP::UserAgent -- and I intermittently suffer from this problem. As I previously shown, the fix is dead simple (just add "SvGETMAGIC(addr)"). I look forward to a release with this fix.
Fixed with test. -- Paul Evans
Subject: rt79557.patch
=== modified file 'Socket.xs' --- Socket.xs 2014-05-31 17:17:43 +0000 +++ Socket.xs 2015-02-10 12:03:49 +0000 @@ -530,6 +530,7 @@ SP -= items; addr = ST(0); + SvGETMAGIC(addr); if(items < 2) flags = 0; === modified file 't/getnameinfo.t' --- t/getnameinfo.t 2014-10-08 20:43:15 +0000 +++ t/getnameinfo.t 2015-02-10 12:03:49 +0000 @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 12; +use Test::More tests => 13; use Socket qw(:addrinfo AF_INET pack_sockaddr_in inet_aton); @@ -32,3 +32,8 @@ cmp_ok( $err, "==", 0, '$err == 0 for {family=AF_INET,port=80,sinaddr=127.0.0.1}/NI_NUMERICHOST' ); ok( length $service, '$service is nonzero length for NH' ); + +# RT79557 +pack_sockaddr_in( 80, inet_aton( "127.0.0.1" ) ) =~ m/^(.*)$/s; +( $err, $host, $service ) = getnameinfo( $1, NI_NUMERICHOST|NI_NUMERICSERV ); +cmp_ok( $err, "==", 0, '$err == 0 for $1' ) or diag( '$err was: ' . $err );
Thanks :)
Seems this isn't working. The test now fails on all perls 5.16 and earlier, but works fine on 5.18+ -- Paul Evans
On Wed Feb 11 07:34:42 2015, PEVANS wrote: Show quoted text
> Seems this isn't working. The test now fails on all perls 5.16 and > earlier, but works fine on 5.18+
Will look at it today
On Wed Feb 11 13:34:58 2015, ikegami wrote: Show quoted text
> On Wed Feb 11 07:34:42 2015, PEVANS wrote:
> > Seems this isn't working. The test now fails on all perls 5.16 and > > earlier, but works fine on 5.18+
> > Will look at it today
The test fails with and without SvGETMAGIC because only pPOK is set, not POK. Before SvGETMAGIC (5.16.3): SV = PVMG(0xb2f170) at 0xbcf670 REFCNT = 1 FLAGS = (GMG,SMG,pPOK) IV = 0 NV = 0 PV = 0xa85600 "$"\0 CUR = 1 LEN = 16 MAGIC = 0xbde710 MG_VIRTUAL = &PL_vtbl_sv MG_TYPE = PERL_MAGIC_sv(\0) MG_OBJ = 0xbcf658 MG_LEN = 1 MG_PTR = 0xbde340 "1" After SvGETMAGIC (5.16.3): SV = PVMG(0xb2f170) at 0xbcf670 REFCNT = 1 FLAGS = (GMG,SMG,pPOK) IV = 0 NV = 0 PV = 0xa85600 "\2\0\0P\177\0\0\1\0\0\0\0\0\0\0\0"\0 CUR = 16 LEN = 24 MAGIC = 0xbde710 MG_VIRTUAL = &PL_vtbl_sv MG_TYPE = PERL_MAGIC_sv(\0) MG_OBJ = 0xbcf658 MG_LEN = 1 MG_PTR = 0xbde340 "1" Before SvGETMAGIC (5.20.1): SV = PVMG(0x13b6240) at 0x1487228 REFCNT = 1 FLAGS = (GMG,SMG,POK,pPOK) IV = 0 NV = 0 PV = 0x12d07f0 "$"\0 CUR = 1 LEN = 10 MAGIC = 0x1498230 MG_VIRTUAL = &PL_vtbl_sv MG_TYPE = PERL_MAGIC_sv(\0) MG_OBJ = 0x1487210 MG_LEN = 1 After SvGETMAGIC (5.20.1): SV = PVMG(0x13b6240) at 0x1487228 REFCNT = 1 FLAGS = (GMG,SMG,POK,pPOK) IV = 0 NV = 0 PV = 0x12d07f0 "\2\0\0P\177\0\0\1\0\0\0\0\0\0\0\0"\0 CUR = 16 LEN = 24 MAGIC = 0x1498230 MG_VIRTUAL = &PL_vtbl_sv MG_TYPE = PERL_MAGIC_sv(\0) MG_OBJ = 0x1487210 MG_LEN = 1 Looks like the correct check is SvPOKp rather than SvPOK. Tested.
On Wed Feb 11 15:42:43 2015, ikegami wrote: Show quoted text
> Looks like the correct check is SvPOKp rather than SvPOK. Tested.
What I would actually use: SV* addr; char* addr_pv; STRLEN addr_len; addr = ST(0); SvGETMAGIC(addr); addr_pv = SvPVbyte(addr, addr_len); if (addr_len != sizeof(struct sockaddr)) croak("Incorrect value for addr"); Newx(sa, addr_len, char); Copy(addr_pv, sa, addr_len, char);
Fixed in 2.018 by using SvPOKp() -- Paul Evans