Fix assertion when calling IO::Poll::_poll() with an empty fd array
authorDagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Fri, 16 Oct 2015 16:20:04 +0000 (17:20 +0100)
committerTony Cook <tony@develop-help.com>
Mon, 19 Oct 2015 02:14:04 +0000 (13:14 +1100)
  perl: IO.xs:322: XS_IO__Poll__poll: Assertion
  `PL_valid_types_PVX[((svtype)((_svpvx)->sv_flags & 0xff)) & 0xf]'
  failed.

This is because NEWSV(…, 0) returns undef, with a grabage pointer in
the PV slot.  This doesn't seem to matter in practice, since nothing
actually dereferences the pointer when nfds is zero, but to be safe we
should pass in _some_ valid pointer, so just use the SV* itself;

dist/IO/IO.pm
dist/IO/IO.xs

index 2762958..de3e991 100644 (file)
@@ -7,7 +7,7 @@ use Carp;
 use strict;
 use warnings;
 
-our $VERSION = "1.35";
+our $VERSION = "1.36";
 XSLoader::load 'IO', $VERSION;
 
 sub import {
index 1f546b9..fe749a6 100644 (file)
@@ -319,7 +319,10 @@ PPCODE:
 #ifdef HAS_POLL
     const int nfd = (items - 1) / 2;
     SV *tmpsv = NEWSV(999,nfd * sizeof(struct pollfd));
-    struct pollfd *fds = (struct pollfd *)SvPVX(tmpsv);
+    /* We should pass _some_ valid pointer even if nfd is zero, but it
+     * doesn't matter what it is, since we're telling it to not check any fds.
+     */
+    struct pollfd *fds = nfd ? (struct pollfd *)SvPVX(tmpsv) : (struct pollfd *)tmpsv;
     int i,j,ret;
     for(i=1, j=0  ; j < nfd ; j++) {
        fds[j].fd = SvIV(ST(i));