OSDN Git Service

Avoid segmentation faults when processing invalid data streams.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Sat, 23 Jan 2010 17:01:53 +0000 (17:01 +0000)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Sat, 23 Jan 2010 17:01:53 +0000 (17:01 +0000)
ChangeLog
src/pkginet.cpp
src/pkgstrm.cpp
src/pkgstrm.h

index 5242b0a..f69d0f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2010-01-23  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
+       Avoid segmentation faults when processing invalid data streams.
+
+       * src/pkgstrm.h: Update copyright notice.
+       (pkgArchiveStream::IsReady): New pure virtual method.
+       (pkgRawArchiveStream::IsReady): Provide inline implementation.
+       (pkgGzipArchiveStream::IsReady): Likewise.
+       (pkgBzipArchiveStream::IsReady): Likewise.
+       (pkgLzmaArchiveStream::IsReady): Likewise.
+       (pkgXzArchiveStream::IsReady): Likewise.
+
+       * src/pkgstrm.cpp: Update copyright notice.
+       (pkgLzmaArchiveStream, pkgXzArchiveStream) [fd == -1]: Decline to
+       perform any form of read or decode processing.
+
+       * src/pkginet.cpp (pkgInternetLzmaStreamingAgent): Use `fd = -2' as
+       pseudo-descriptor for the pkgLzmaArchiveStream derived component of
+       this internet data streaming class.
+
+2010-01-23  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
        Require liblzma >= liblzma-4.999.9beta_20091209-3-mingw32-dev
 
        * src/pkgstrm.h (LZMA_API_STATIC): Remove definition and associated
index 0b9fce5..8698489 100644 (file)
@@ -374,7 +374,17 @@ public pkgInternetStreamingAgent, public pkgLzmaArchiveStream
 pkgInternetLzmaStreamingAgent::pkgInternetLzmaStreamingAgent
 ( const char *local_name, const char *dest_specification ):
 pkgInternetStreamingAgent( local_name, dest_specification ),
-pkgLzmaArchiveStream( -1 ){}
+/*
+ * Note that, when we come to initialise the lzma streaming component
+ * of this derived class, we will be streaming directly from the internet,
+ * rather than from a file stream, so we don't require a file descriptor
+ * for the input stream; however, the class semantics still expect one.
+ * To avoid accidental association with an existing file stream, we
+ * use a negative value, (which is never a valid file descriptor);
+ * however, we must not choose -1, since the class implementation
+ * will decline to process the stream; hence, we choose -2.
+ */
+pkgLzmaArchiveStream( -2 ){}
 
 int pkgInternetLzmaStreamingAgent::GetRawData( int fd, uint8_t *buf, size_t max )
 {
index 0829dc7..a7649e9 100644 (file)
@@ -4,7 +4,7 @@
  * $Id$
  *
  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, MinGW Project
+ * Copyright (C) 2009, 2010, MinGW Project
  *
  *
  * Implementation of the streaming data filters, which will be used
@@ -241,8 +241,11 @@ pkgLzmaArchiveStream::pkgLzmaArchiveStream( int fileno ):fd( fileno )
   /* ...then set up the lzma decoder, in appropriately
    * initialised state...
    */
-  lzma_stream_initialise( &stream );
-  status = lzma_alone_decoder( &stream, memlimit() );
+  if( fd != -1 )
+  {
+    lzma_stream_initialise( &stream );
+    status = lzma_alone_decoder( &stream, memlimit() );
+  }
 }
 
 pkgLzmaArchiveStream::~pkgLzmaArchiveStream()
@@ -255,15 +258,26 @@ pkgLzmaArchiveStream::~pkgLzmaArchiveStream()
    * ignore any such residual data; (it is likely to be garbage anyway).
    * Should we handle it any more explicitly?
    */
-  lzma_end( &stream );
-  close( fd );
+  if( fd != -1 )
+  {
+    lzma_end( &stream );
+    close( fd );
+  }
 }
 
 int pkgLzmaArchiveStream::Read( char *buf, size_t max )
 {
   /* Read an lzma compressed data stream; store up to "max" bytes of
    * decompressed data into "buf".
-   * 
+   */
+  if( fd == -1 )
+    /*
+     * We cannot read from a stream with an invalid descriptor;
+     * in this circumstance, just say "nothing was read"...
+     */
+    return fd;
+
+  /* Otherwise the stream is ready to read...
    * Start by directing the decoder to use "buf", initially marking it 
    * as "empty".
    */
@@ -344,15 +358,26 @@ pkgXzArchiveStream::~pkgXzArchiveStream()
    * case of the lzma_alone_decoder, the lzma_stream_decoder guarantees
    * that there is no trailing garbage remaining from the input stream.
    */
-  lzma_end( &stream );
-  close( fd );
+  if( fd != -1 )
+  {
+    lzma_end( &stream );
+    close( fd );
+  }
 }
 
 int pkgXzArchiveStream::Read( char *buf, size_t max )
 {
   /* Read an xz compressed data stream; store up to "max" bytes of
    * decompressed data into "buf".
-   * 
+   */
+  if( fd == -1 )
+    /*
+     * We cannot read from a stream with an invalid descriptor;
+     * in this circumstance, just say "nothing was read"...
+     */
+    return fd;
+
+  /* Otherwise the stream is ready to read...
    * Start by directing the decoder to use "buf", initially marking it 
    * as "empty".
    */
index 141cb72..b732bc7 100644 (file)
@@ -5,7 +5,7 @@
  * $Id$
  *
  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, MinGW Project
+ * Copyright (C) 2009, 2010, MinGW Project
  *
  *
  * Declaration of the streaming API, for reading package archives.
@@ -36,6 +36,7 @@ class pkgArchiveStream
    */
   public:
     pkgArchiveStream(){}
+    virtual bool IsReady() = 0;
     virtual int Read( char*, size_t ) = 0;
     virtual ~pkgArchiveStream(){}
 
@@ -63,6 +64,7 @@ class pkgRawArchiveStream : public pkgArchiveStream
     pkgRawArchiveStream( const char* );
     virtual ~pkgRawArchiveStream();
 
+    inline bool IsReady(){ return fd != -1; }
     virtual int Read( char*, size_t );
 };
 
@@ -84,6 +86,7 @@ class pkgGzipArchiveStream : public pkgArchiveStream
     pkgGzipArchiveStream( const char* );
     virtual ~pkgGzipArchiveStream();
 
+    inline bool IsReady(){ return stream != NULL; }
     virtual int Read( char*, size_t );
 };
 
@@ -100,6 +103,7 @@ class pkgBzipArchiveStream : public pkgArchiveStream
     pkgBzipArchiveStream( const char* );
     virtual ~pkgBzipArchiveStream();
 
+    inline bool IsReady(){ return stream != NULL; }
     virtual int Read( char*, size_t );
 };
 
@@ -118,6 +122,7 @@ class pkgLzmaArchiveStream : public pkgArchiveStream
     pkgLzmaArchiveStream( const char* );
     virtual ~pkgLzmaArchiveStream();
 
+    inline bool IsReady(){ return fd != -1; }
     virtual int Read( char*, size_t );
 };
 
@@ -137,6 +142,7 @@ class pkgXzArchiveStream : public pkgArchiveStream
     pkgXzArchiveStream( const char* );
     virtual ~pkgXzArchiveStream();
 
+    inline bool IsReady(){ return fd != -1; }
     virtual int Read( char*, size_t );
 };