This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid wraparound when casting unsigned size_t to signed ssize_t.
authorAndy Dougherty <doughera@lafayette.edu>
Wed, 16 Jan 2013 17:30:43 +0000 (12:30 -0500)
committerRicardo Signes <rjbs@cpan.org>
Mon, 4 Mar 2013 15:16:34 +0000 (10:16 -0500)
Practically, this only affects a perl compiled with 64-bit IVs on a 32-bit
system.  In that instance a value of count >= 2**31 would turn negative
when cast to (ssize_t).

perlio.c

index 7782728..cccfdcd 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -2164,7 +2164,7 @@ PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
            SSize_t avail = PerlIO_get_cnt(f);
            SSize_t take = 0;
            if (avail > 0)
-               take = ((SSize_t)count < avail) ? (SSize_t)count : avail;
+               take = (((SSize_t) count >= 0) && ((SSize_t)count < avail)) ? (SSize_t)count : avail;
            if (take > 0) {
                STDCHAR *ptr = PerlIO_get_ptr(f);
                Copy(ptr, buf, take, STDCHAR);
@@ -4098,7 +4098,7 @@ PerlIOBuf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
             */
            b->posn -= b->bufsiz;
        }
-       if (avail > (SSize_t) count) {
+       if ((SSize_t) count >= 0 && avail > (SSize_t) count) {
            /*
             * If we have space for more than count, just move count
             */
@@ -4148,7 +4148,7 @@ PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
     }
     while (count > 0) {
        SSize_t avail = b->bufsiz - (b->ptr - b->buf);
-       if ((SSize_t) count < avail)
+       if ((SSize_t) count >= 0 && (SSize_t) count < avail)
            avail = count;
        if (flushptr > buf && flushptr <= buf + avail)
            avail = flushptr - buf;
@@ -4423,7 +4423,7 @@ PerlIOPending_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
 {
     SSize_t avail = PerlIO_get_cnt(f);
     SSize_t got = 0;
-    if ((SSize_t)count < avail)
+    if ((SSize_t) count >= 0 && (SSize_t)count < avail)
        avail = count;
     if (avail > 0)
        got = PerlIOBuf_read(aTHX_ f, vbuf, avail);