always properly check if SeekI() calls succeded; this makes CanRead() functions of animation decoders return false for non-seekable streams (which is a wanted side-effect)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58080 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-13 19:16:08 +00:00
parent 2bc566539b
commit b81e450659
7 changed files with 110 additions and 64 deletions

View File

@@ -127,7 +127,8 @@ bool wxANIDecoder::CanRead(wxInputStream& stream) const
wxInt32 anih32; wxInt32 anih32;
memcpy( &anih32, "anih", 4 ); memcpy( &anih32, "anih", 4 );
stream.SeekI(0); if ( stream.SeekI(0) == wxInvalidOffset )
return false;
if ( !stream.Read(&FCC1, 4) ) if ( !stream.Read(&FCC1, 4) )
return false; return false;
@@ -154,7 +155,8 @@ bool wxANIDecoder::CanRead(wxInputStream& stream) const
} }
else else
{ {
stream.SeekI(stream.TellI() + datalen); if ( stream.SeekI(stream.TellI() + datalen) == wxInvalidOffset )
return false;
} }
// try to read next data chunk: // try to read next data chunk:
@@ -220,8 +222,10 @@ bool wxANIDecoder::Load( wxInputStream& stream )
wxInt32 seq32; wxInt32 seq32;
memcpy( &seq32, "seq ", 4 ); memcpy( &seq32, "seq ", 4 );
stream.SeekI(0); if ( stream.SeekI(0) == wxInvalidOffset)
stream.Read(&FCC1, 4); return false;
if ( !stream.Read(&FCC1, 4) )
return false;
if ( FCC1 != riff32 ) if ( FCC1 != riff32 )
return false; return false;
@@ -309,11 +313,13 @@ bool wxANIDecoder::Load( wxInputStream& stream )
} }
else else
{ {
stream.SeekI(stream.TellI() + datalen); if ( stream.SeekI(stream.TellI() + datalen) == wxInvalidOffset )
return false;
} }
// try to read next data chunk: // try to read next data chunk:
stream.Read(&FCC1, 4); if ( !stream.Read(&FCC1, 4) )
return false;
} }
if (m_nFrames==0) if (m_nFrames==0)

View File

@@ -580,7 +580,8 @@ bool wxGIFDecoder::CanRead(wxInputStream &stream) const
if ( !stream.Read(buf, WXSIZEOF(buf)) ) if ( !stream.Read(buf, WXSIZEOF(buf)) )
return false; return false;
stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent); if (stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent) == wxInvalidOffset)
return false; // this happens e.g. for non-seekable streams
return memcmp(buf, "GIF", WXSIZEOF(buf)) == 0; return memcmp(buf, "GIF", WXSIZEOF(buf)) == 0;
} }
@@ -720,12 +721,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
{ {
while ((i = (unsigned char)stream.GetC()) != 0) while ((i = (unsigned char)stream.GetC()) != 0)
{ {
if (stream.Eof() || (stream.LastRead() == 0)) if (stream.Eof() || (stream.LastRead() == 0) ||
stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
{ {
done = true; done = true;
break; break;
} }
stream.SeekI(i, wxFromCurrent);
} }
} }
} }
@@ -834,12 +835,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
// skip all data // skip all data
while ((i = (unsigned char)stream.GetC()) != 0) while ((i = (unsigned char)stream.GetC()) != 0)
{ {
if (stream.Eof() || (stream.LastRead() == 0)) if (stream.Eof() || (stream.LastRead() == 0) ||
stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
{ {
Destroy(); Destroy();
return wxGIF_INVFORMAT; return wxGIF_INVFORMAT;
} }
stream.SeekI(i, wxFromCurrent);
} }
} }
else if (type == 0x2C) else if (type == 0x2C)
@@ -858,7 +859,11 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
{ {
unsigned int local_ncolors = 2 << (buf[8] & 0x07); unsigned int local_ncolors = 2 << (buf[8] & 0x07);
wxFileOffset numBytes = 3 * local_ncolors; wxFileOffset numBytes = 3 * local_ncolors;
stream.SeekI(numBytes, wxFromCurrent); if (stream.SeekI(numBytes, wxFromCurrent) == wxInvalidOffset)
{
Destroy();
return wxGIF_INVFORMAT;
}
} }
// initial code size // initial code size
@@ -872,12 +877,12 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
// skip all data // skip all data
while ((i = (unsigned char)stream.GetC()) != 0) while ((i = (unsigned char)stream.GetC()) != 0)
{ {
if (stream.Eof() || (stream.LastRead() == 0)) if (stream.Eof() || (stream.LastRead() == 0) ||
stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
{ {
Destroy(); Destroy();
return wxGIF_INVFORMAT; return wxGIF_INVFORMAT;
} }
stream.SeekI(i, wxFromCurrent);
} }
} }
else if ((type != 0x3B) && (type != 00)) // testing else if ((type != 0x3B) && (type != 00)) // testing

View File

@@ -640,7 +640,11 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
* Reading the image data * Reading the image data
*/ */
if ( IsBmp ) if ( IsBmp )
stream.SeekI(bmpOffset); // else icon, just carry on {
if (stream.SeekI(bmpOffset) == wxInvalidOffset)
return false;
//else: icon, just carry on
}
unsigned char *data = ptr; unsigned char *data = ptr;
@@ -1255,7 +1259,8 @@ bool wxICOHandler::SaveFile(wxImage *image,
bool wxICOHandler::LoadFile(wxImage *image, wxInputStream& stream, bool wxICOHandler::LoadFile(wxImage *image, wxInputStream& stream,
bool verbose, int index) bool verbose, int index)
{ {
stream.SeekI(0); if (stream.SeekI(0) == wxInvalidOffset)
return false;
return DoLoadFile(image, stream, verbose, index); return DoLoadFile(image, stream, verbose, index);
} }
@@ -1315,7 +1320,8 @@ bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream,
{ {
// seek to selected icon: // seek to selected icon:
pCurrentEntry = pIconDirEntry + iSel; pCurrentEntry = pIconDirEntry + iSel;
stream.SeekI(iPos + wxUINT32_SWAP_ON_BE(pCurrentEntry->dwImageOffset), wxFromStart); if (stream.SeekI(iPos + wxUINT32_SWAP_ON_BE(pCurrentEntry->dwImageOffset), wxFromStart) == wxInvalidOffset)
return false;
bResult = LoadDib(image, stream, true, IsBmp); bResult = LoadDib(image, stream, true, IsBmp);
bool bIsCursorType = (this->GetType() == wxBITMAP_TYPE_CUR) || (this->GetType() == wxBITMAP_TYPE_ANI); bool bIsCursorType = (this->GetType() == wxBITMAP_TYPE_CUR) || (this->GetType() == wxBITMAP_TYPE_ANI);
if ( bResult && bIsCursorType && nType == 2 ) if ( bResult && bIsCursorType && nType == 2 )
@@ -1333,16 +1339,20 @@ int wxICOHandler::GetImageCount(wxInputStream& stream)
{ {
ICONDIR IconDir; ICONDIR IconDir;
wxFileOffset iPos = stream.TellI(); wxFileOffset iPos = stream.TellI();
stream.SeekI(0); if (stream.SeekI(0) == wxInvalidOffset)
stream.Read(&IconDir, sizeof(IconDir)); return 0;
if (stream.Read(&IconDir, sizeof(IconDir)).LastRead() != sizeof(IconDir))
return 0;
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount); wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
stream.SeekI(iPos); if (stream.SeekI(iPos) == wxInvalidOffset)
return 0;
return (int)nIcons; return (int)nIcons;
} }
bool wxICOHandler::DoCanRead(wxInputStream& stream) bool wxICOHandler::DoCanRead(wxInputStream& stream)
{ {
stream.SeekI(0); if (stream.SeekI(0) == wxInvalidOffset)
return false;
unsigned char hdr[4]; unsigned char hdr[4];
if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
return false; return false;
@@ -1364,7 +1374,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxCURHandler, wxICOHandler)
bool wxCURHandler::DoCanRead(wxInputStream& stream) bool wxCURHandler::DoCanRead(wxInputStream& stream)
{ {
stream.SeekI(0); if (stream.SeekI(0) == wxInvalidOffset)
return false;
unsigned char hdr[4]; unsigned char hdr[4];
if ( !stream.Read(hdr, WXSIZEOF(hdr)) ) if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
return false; return false;

View File

@@ -234,7 +234,8 @@ bool wxIFFDecoder::CanRead()
if ( !m_f->Read(buf, WXSIZEOF(buf)) ) if ( !m_f->Read(buf, WXSIZEOF(buf)) )
return false; return false;
m_f->SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent); if ( m_f->SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent) == wxInvalidOffset )
return false;
return (memcmp(buf, "FORM", 4) == 0) && (memcmp(buf+8, "ILBM", 4) == 0); return (memcmp(buf, "FORM", 4) == 0) && (memcmp(buf+8, "ILBM", 4) == 0);
} }
@@ -248,13 +249,13 @@ typedef unsigned char byte;
#define IFFDEBUG 0 #define IFFDEBUG 0
/************************************************************************* /*************************************************************************
void decomprle(source, destination, source length, buffer size) void decomprle(source, destination, source length, buffer size)
Decompress run-length encoded data from source to destination. Terminates Decompress run-length encoded data from source to destination. Terminates
when source is decoded completely or destination buffer is full. when source is decoded completely or destination buffer is full.
The decruncher is as optimized as I could make it, without risking The decruncher is as optimized as I could make it, without risking
safety in case of corrupt BODY chunks. safety in case of corrupt BODY chunks.
**************************************************************************/ **************************************************************************/
static void decomprle(const byte *sptr, byte *dptr, long slen, long dlen) static void decomprle(const byte *sptr, byte *dptr, long slen, long dlen)
@@ -335,9 +336,16 @@ int wxIFFDecoder::ReadIFF()
// compute file length // compute file length
wxFileOffset currentPos = m_f->TellI(); wxFileOffset currentPos = m_f->TellI();
m_f->SeekI(0, wxFromEnd); if (m_f->SeekI(0, wxFromEnd) == wxInvalidOffset) {
Destroy();
return wxIFF_MEMERR;
}
long filesize = m_f->TellI(); long filesize = m_f->TellI();
m_f->SeekI(currentPos, wxFromStart); if (m_f->SeekI(currentPos, wxFromStart) == wxInvalidOffset) {
Destroy();
return wxIFF_MEMERR;
}
// allocate memory for complete file // allocate memory for complete file
if ((databuf = new byte[filesize]) == 0) { if ((databuf = new byte[filesize]) == 0) {

View File

@@ -211,7 +211,8 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
} }
// Seek from the offset we got from the TGA header. // Seek from the offset we got from the TGA header.
stream.SeekI(offset, wxFromStart); if (stream.SeekI(offset, wxFromStart) == wxInvalidOffset)
return wxTGA_INVFORMAT;
// Load a palette if we have one. // Load a palette if we have one.
if (colorType == wxTGA_MAPPED) if (colorType == wxTGA_MAPPED)

View File

@@ -122,7 +122,8 @@ bool wxXPMDecoder::CanRead(wxInputStream& stream)
if ( !stream.Read(buf, WXSIZEOF(buf)) ) if ( !stream.Read(buf, WXSIZEOF(buf)) )
return false; return false;
stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent); if (stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent) == wxInvalidOffset)
return false;
return memcmp(buf, "/* XPM */", WXSIZEOF(buf)) == 0; return memcmp(buf, "/* XPM */", WXSIZEOF(buf)) == 0;
} }

View File

@@ -487,15 +487,29 @@ size_t wxChmInputStream::OnSysRead(void *buffer, size_t bufsize)
m_lasterror = wxSTREAM_NO_ERROR; m_lasterror = wxSTREAM_NO_ERROR;
// If the rest to read from the stream is less // If the rest to read from the stream is less
// than the buffer size, than only read the rest // than the buffer size, then only read the rest
if ( m_pos + bufsize > m_size ) if ( m_pos + bufsize > m_size )
bufsize = m_size - m_pos; bufsize = m_size - m_pos;
m_contentStream->SeekI(m_pos); if (m_contentStream->SeekI(m_pos) == wxInvalidOffset)
m_contentStream->Read(buffer, bufsize); {
m_pos +=bufsize; m_lasterror = wxSTREAM_EOF;
m_contentStream->SeekI(m_pos); return 0;
return bufsize; }
size_t read = m_contentStream->Read(buffer, bufsize).LastRead();
m_pos += read;
if (m_contentStream->SeekI(m_pos) == wxInvalidOffset)
{
m_lasterror = wxSTREAM_READ_ERROR;
return 0;
}
if (read != bufsize)
m_lasterror = m_contentStream->GetLastError();
return read;
} }