@@ -6159,8 +6159,23 @@ Rconnection R_GetConnection(SEXP sConn) {
61596159/* ------------------- (de)compression functions --------------------- */
61606160
61616161/* Code for gzcon connections is modelled on gzio.c from zlib 1.2.3 */
6162+ static int gzcon_byte (Rgzconn priv )
6163+ {
6164+ Rconnection icon = priv -> con ;
61626165
6163- #define get_byte () (icon->read(&ccc, 1, 1, icon), ccc)
6166+ if (priv -> z_eof ) return EOF ;
6167+ if (priv -> s .avail_in == 0 ) {
6168+ priv -> s .avail_in = (uInt ) icon -> read (priv -> buffer , 1 , Z_BUFSIZE , icon );
6169+ if (priv -> s .avail_in == 0 ) {
6170+ priv -> z_eof = 1 ;
6171+ return EOF ;
6172+ } else if ((int )priv -> s .avail_in < 0 )
6173+ error ("error reading from the connection" );
6174+ priv -> s .next_in = priv -> buffer ;
6175+ }
6176+ priv -> s .avail_in -- ;
6177+ return * (priv -> s .next_in )++ ;
6178+ }
61646179
61656180static Rboolean gzcon_open (Rconnection con )
61666181{
@@ -6185,44 +6200,53 @@ static Rboolean gzcon_open(Rconnection con)
61856200
61866201 if (con -> canread ) {
61876202 /* read header */
6188- char c , ccc , method , flags , dummy [ 6 ] ;
6203+ char c , method , flags ;
61896204 unsigned char head [2 ];
61906205 uInt len ;
61916206
6192- icon -> read (head , 1 , 2 , icon );
6193- if (head [0 ] != gz_magic [0 ] || head [1 ] != gz_magic [1 ]) {
6207+ len = (uInt ) icon -> read (head , 1 , 2 , icon );
6208+ if ((int )len < 0 )
6209+ error ("error reading from the connection" );
6210+ if (len < 2 || head [0 ] != gz_magic [0 ] || head [1 ] != gz_magic [1 ]) {
61946211 if (!priv -> allow ) {
61956212 warning (_ ("file stream does not have gzip magic number" ));
61966213 return FALSE;
61976214 }
6198- priv -> nsaved = 2 ;
6199- priv -> saved [0 ] = head [0 ];
6200- priv -> saved [1 ] = head [1 ];
6215+ priv -> nsaved = 0 ;
6216+ if (len >= 1 ) {
6217+ priv -> nsaved ++ ;
6218+ priv -> saved [0 ] = head [0 ];
6219+ }
6220+ if (len == 2 ) {
6221+ priv -> nsaved ++ ;
6222+ priv -> saved [1 ] = head [1 ];
6223+ }
62016224 return TRUE;
62026225 }
6203- icon -> read ( & method , 1 , 1 , icon );
6204- icon -> read ( & flags , 1 , 1 , icon );
6226+ method = gzcon_byte ( priv );
6227+ flags = gzcon_byte ( priv );
62056228 if (method != Z_DEFLATED || (flags & RESERVED ) != 0 ) {
62066229 warning (_ ("file stream does not have valid gzip header" ));
62076230 return FALSE;
62086231 }
6209- icon -> read (dummy , 1 , 6 , icon );
6232+ /* Discard time, xflags and OS code: */
6233+ for (len = 0 ; len < 6 ; len ++ ) (void ) gzcon_byte (priv );
6234+
62106235 if ((flags & EXTRA_FIELD ) != 0 ) { /* skip the extra field */
6211- len = (uInt ) get_byte ( );
6212- len += ((uInt ) get_byte ( )) << 8 ;
6236+ len = (uInt ) gzcon_byte ( priv );
6237+ len += ((uInt ) gzcon_byte ( priv )) << 8 ;
62136238 /* len is garbage if EOF but the loop below will quit anyway */
6214- while (len -- != 0 && get_byte ( ) != EOF ) ;
6239+ while (len -- != 0 && gzcon_byte ( priv ) != EOF ) ;
62156240 }
62166241 if ((flags & ORIG_NAME ) != 0 ) { /* skip the original file name */
6217- while ((c = get_byte ( )) != 0 && c != EOF ) ;
6242+ while ((c = gzcon_byte ( priv )) != 0 && c != EOF ) ;
62186243 }
62196244 if ((flags & COMMENT ) != 0 ) { /* skip the .gz file comment */
6220- while ((c = get_byte ( )) != 0 && c != EOF ) ;
6245+ while ((c = gzcon_byte ( priv )) != 0 && c != EOF ) ;
62216246 }
62226247 if ((flags & HEAD_CRC ) != 0 ) { /* skip the header crc */
6223- for (len = 0 ; len < 2 ; len ++ ) (void ) get_byte ( );
6248+ for (len = 0 ; len < 2 ; len ++ ) (void ) gzcon_byte ( priv );
62246249 }
6225- priv -> s .next_in = priv -> buffer ;
62266250 inflateInit2 (& (priv -> s ), - MAX_WBITS );
62276251 } else {
62286252 /* write a header */
@@ -6293,23 +6317,6 @@ static void gzcon_close(Rconnection con)
62936317 con -> isopen = FALSE;
62946318}
62956319
6296- static int gzcon_byte (Rgzconn priv )
6297- {
6298- Rconnection icon = priv -> con ;
6299-
6300- if (priv -> z_eof ) return EOF ;
6301- if (priv -> s .avail_in == 0 ) {
6302- priv -> s .avail_in = (uInt ) icon -> read (priv -> buffer , 1 , Z_BUFSIZE , icon );
6303- if (priv -> s .avail_in == 0 ) {
6304- priv -> z_eof = 1 ;
6305- return EOF ;
6306- }
6307- priv -> s .next_in = priv -> buffer ;
6308- }
6309- priv -> s .avail_in -- ;
6310- return * (priv -> s .next_in )++ ;
6311- }
6312-
63136320
63146321static size_t gzcon_read (void * ptr , size_t size , size_t nitems ,
63156322 Rconnection con )
@@ -6319,6 +6326,7 @@ static size_t gzcon_read(void *ptr, size_t size, size_t nitems,
63196326 Bytef * start = (Bytef * ) ptr ;
63206327 uLong crc ;
63216328 int n ;
6329+ size_t icread ;
63226330
63236331 if (priv -> z_err == Z_STREAM_END ) return 0 ; /* EOF */
63246332
@@ -6333,8 +6341,12 @@ static size_t gzcon_read(void *ptr, size_t size, size_t nitems,
63336341 for (i = 0 ; i < priv -> nsaved ; i ++ )
63346342 ((char * )ptr )[i ] = priv -> saved [i ];
63356343 priv -> nsaved = 0 ;
6336- return (nsaved + icon -> read ((char * ) ptr + nsaved , 1 , len - nsaved ,
6337- icon ))/size ;
6344+ icread = icon -> read ((char * ) ptr + nsaved , 1 , len - nsaved ,
6345+ icon )/size ;
6346+ if ((int )icread < 0 )
6347+ return icread ;
6348+ else
6349+ return nsaved + icread ;
63386350 }
63396351 if (len == 1 ) { /* size must be one */
63406352 if (nsaved > 0 ) {
@@ -6354,6 +6366,8 @@ static size_t gzcon_read(void *ptr, size_t size, size_t nitems,
63546366 if (priv -> s .avail_in == 0 && !priv -> z_eof ) {
63556367 priv -> s .avail_in = (uInt )icon -> read (priv -> buffer , 1 , Z_BUFSIZE , icon );
63566368 if (priv -> s .avail_in == 0 ) priv -> z_eof = 1 ;
6369+ if ((int )priv -> s .avail_in < 0 )
6370+ return priv -> s .avail_in ;
63576371 priv -> s .next_in = priv -> buffer ;
63586372 }
63596373 priv -> z_err = inflate (& (priv -> s ), Z_NO_FLUSH );
0 commit comments