diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-11-04 16:53:20 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-11-04 21:58:36 +0100 |
commit | f1c790ca3613a43dac84e2a9b6a99d1338176325 (patch) | |
tree | af26a6ac72c62860e513cdc577f7675ea3d2fcd0 /sot | |
parent | 969531f53696417c80f9823e89eda2d5d594898e (diff) |
ofz short read considered as a successful full block read
i.e StgDataStrm::Read takes the bool of no error and
multiplies it by the block size to report the length
read. A short read isn't an error so full buffer is
considered valid.
To keep #i73846# working and get deterministic fuzzing
results, zero out the trailing space of a successful but
short read. Changing this to return the truthful
number of bytes read makes #i73846# stop working.
There's wonderful nonsense here calculating nPg2,
determining nBytes to read derived from this,
reading nBytes into the buffer and then considering
it an error if nPg2 is not 1 after the presumably
potentially fatal buffer overflow if nPg2 wasn't initially
1, but this doesn't seem possible in practice
Change-Id: I2bac6066deb8a2902677e04696367ba2c351b325
Reviewed-on: https://gerrit.libreoffice.org/44310
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sot')
-rw-r--r-- | sot/source/sdstor/stgcache.cxx | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/sot/source/sdstor/stgcache.cxx b/sot/source/sdstor/stgcache.cxx index 8387f0290765..8f77abdbc345 100644 --- a/sot/source/sdstor/stgcache.cxx +++ b/sot/source/sdstor/stgcache.cxx @@ -319,6 +319,7 @@ void StgCache::Close() bool StgCache::Read( sal_Int32 nPage, void* pBuf ) { + sal_uInt32 nRead = 0, nBytes = m_nPageSize; if( Good() ) { /* #i73846# real life: a storage may refer to a page one-behind the @@ -329,28 +330,40 @@ bool StgCache::Read( sal_Int32 nPage, void* pBuf ) SetError( SVSTREAM_READ_ERROR ); else if ( nPage < m_nPages ) { - sal_uInt32 nPos = Page2Pos( nPage ); - sal_Int32 nPg2 = ( ( nPage + 1 ) > m_nPages ) ? m_nPages - nPage : 1; - sal_uInt32 nBytes = nPg2 * m_nPageSize; + sal_uInt32 nPos; + sal_Int32 nPg2; // fixed address and size for the header if( nPage == -1 ) { nPos = 0; - nBytes = 512; nPg2 = 1; + nBytes = 512; } - if( m_pStrm->Tell() != nPos ) + else { - m_pStrm->Seek(nPos); + nPos = Page2Pos(nPage); + nPg2 = ((nPage + 1) > m_nPages) ? m_nPages - nPage : 1; } - m_pStrm->ReadBytes( pBuf, nBytes ); - if ( 1 != nPg2 ) - SetError( SVSTREAM_READ_ERROR ); + + if (m_pStrm->Tell() != nPos) + m_pStrm->Seek(nPos); + + if (nPg2 != 1) + SetError(SVSTREAM_READ_ERROR); else - SetError( m_pStrm->GetError() ); + { + nRead = m_pStrm->ReadBytes(pBuf, nBytes); + SetError(m_pStrm->GetError()); + } } } - return Good(); + + if (!Good()) + return false; + + if (nRead != nBytes) + memset(static_cast<sal_uInt8*>(pBuf) + nRead, 0, nBytes - nRead); + return true; } bool StgCache::Write( sal_Int32 nPage, void const * pBuf ) |