From: Keith Marshall Date: Sat, 23 Jan 2010 17:01:53 +0000 (+0000) Subject: Avoid segmentation faults when processing invalid data streams. X-Git-Tag: r0-6-0-beta-20130904-1~208 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=d17c3e6d1094321def273315939a955f3dcf2cfa;p=mingw%2Fmingw-get.git Avoid segmentation faults when processing invalid data streams. --- diff --git a/ChangeLog b/ChangeLog index 5242b0a..f69d0f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2010-01-23 Keith Marshall + 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 + Require liblzma >= liblzma-4.999.9beta_20091209-3-mingw32-dev * src/pkgstrm.h (LZMA_API_STATIC): Remove definition and associated diff --git a/src/pkginet.cpp b/src/pkginet.cpp index 0b9fce5..8698489 100644 --- a/src/pkginet.cpp +++ b/src/pkginet.cpp @@ -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 ) { diff --git a/src/pkgstrm.cpp b/src/pkgstrm.cpp index 0829dc7..a7649e9 100644 --- a/src/pkgstrm.cpp +++ b/src/pkgstrm.cpp @@ -4,7 +4,7 @@ * $Id$ * * Written by Keith Marshall - * 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". */ diff --git a/src/pkgstrm.h b/src/pkgstrm.h index 141cb72..b732bc7 100644 --- a/src/pkgstrm.h +++ b/src/pkgstrm.h @@ -5,7 +5,7 @@ * $Id$ * * Written by Keith Marshall - * 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 ); };