[Libreoffice-commits] core.git: emfio/source filter/qa filter/source include/tools lotuswordpro/inc lotuswordpro/source sc/qa sc/source sd/qa sd/source sot/source sw/qa sw/source tools/qa tools/source unotest/source vcl/qa vcl/source
Noel (via logerrit)
logerrit at kemper.freedesktop.org
Fri Dec 18 05:54:45 UTC 2020
emfio/source/reader/wmfreader.cxx | 2
filter/source/graphicfilter/ios2met/ios2met.cxx | 3
filter/source/graphicfilter/itiff/itiff.cxx | 4
filter/source/msfilter/dffrecordheader.cxx | 33
filter/source/msfilter/msdffimp.cxx | 10
include/tools/stream.hxx | 10
lotuswordpro/inc/lwpsvstream.hxx | 1
lotuswordpro/source/filter/lwpobjhdr.cxx | 3
lotuswordpro/source/filter/lwpsvstream.cxx | 2
sc/qa/unit/data/qpro/pass/.gitignore | 2
sc/source/filter/excel/xltoolbar.cxx | 9
sc/source/filter/lotus/lotread.cxx | 17
sc/source/filter/qpro/qpro.cxx | 10
sd/source/filter/ppt/pptin.cxx | 15
sot/source/sdstor/stg.cxx | 13
sw/source/filter/html/htmlreqifreader.cxx | 89 -
sw/source/filter/ww8/ww8scan.cxx | 3
tools/qa/cppunit/test_stream.cxx | 12
tools/source/stream/stream.cxx | 34
unotest/source/cpp/filters-test.cxx | 2
vcl/source/filter/graphicfilter.cxx | 9
vcl/source/filter/graphicfilter2.cxx | 1229 ++++++++++++------------
vcl/source/filter/png/pngread.cxx | 2
vcl/source/gdi/TypeSerializer.cxx | 13
vcl/source/gdi/dibtools.cxx | 5
vcl/source/gdi/impgraph.cxx | 18
26 files changed, 875 insertions(+), 675 deletions(-)
New commits:
commit 8c9a4ff511a3b1d84a7a6d08a1b153c07f164abb
Author: Noel <noelgrandin at gmail.com>
AuthorDate: Mon Nov 16 15:58:10 2020 +0200
Commit: Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Dec 18 06:54:06 2020 +0100
throw exception in SvStream when reading past end of file
to avoid chasing weird problems where we read past the end
of file, which leads to random data in the variable we read into.
I expect a couple of possible regressions from this change
(1) memory leaks caused by non-exception-safe memory handling.
Of which there should not be much because we're pretty good
about using smart pointer classes these days.
(2) Broken files which used to load, will no longer do so.
These will have to be debugged by putting a breakpoint
on the SvStreamEOFException constructor, and examining
the backtrace to see where we should be catching and ignoring
the exception to make the code continue to handle such broken
files.
Change-Id: I351be031bb083a3484a9a1b650a58892700e6fb7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105936
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index 0022fe9b1cb6..123f1c06a731 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -1398,7 +1398,7 @@ namespace emfio
if( mnEndPos - mnStartPos )
{
bool bEMFAvailable = false;
- while( true )
+ while( !mpInputStream->eof() )
{
mpInputStream->ReadUInt32(mnRecSize).ReadUInt16( nFunction );
diff --git a/filter/qa/cppunit/data/met/pass/hang-2.met b/filter/qa/cppunit/data/met/fail/hang-3.met
similarity index 100%
rename from filter/qa/cppunit/data/met/pass/hang-2.met
rename to filter/qa/cppunit/data/met/fail/hang-3.met
diff --git a/filter/source/graphicfilter/ios2met/ios2met.cxx b/filter/source/graphicfilter/ios2met/ios2met.cxx
index cdf18abc66e4..3a7c6b7048ba 100644
--- a/filter/source/graphicfilter/ios2met/ios2met.cxx
+++ b/filter/source/graphicfilter/ios2met/ios2met.cxx
@@ -2806,6 +2806,9 @@ imeGraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
catch (const css::uno::Exception&)
{
}
+ catch(SvStreamEOFException&)
+ {
+ }
return bRet;
}
diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx
index e7c571111e38..f07e496bc347 100644
--- a/filter/source/graphicfilter/itiff/itiff.cxx
+++ b/filter/source/graphicfilter/itiff/itiff.cxx
@@ -1721,6 +1721,10 @@ itiGraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
{
return aTIFFReader.ReadTIFF(rStream, rGraphic);
}
+ catch (const SvStreamEOFException &)
+ {
+ return false;
+ }
catch (const std::bad_alloc &)
{
return false;
diff --git a/filter/source/msfilter/dffrecordheader.cxx b/filter/source/msfilter/dffrecordheader.cxx
index b1d4316b630b..2a8c91a89b1b 100644
--- a/filter/source/msfilter/dffrecordheader.cxx
+++ b/filter/source/msfilter/dffrecordheader.cxx
@@ -22,19 +22,28 @@
bool ReadDffRecordHeader(SvStream& rIn, DffRecordHeader& rRec)
{
rRec.nFilePos = rIn.Tell();
- sal_uInt16 nTmp(0);
- rIn.ReadUInt16(nTmp);
- rRec.nImpVerInst = nTmp;
- rRec.nRecVer = sal::static_int_cast<sal_uInt8>(nTmp & 0x000F);
- rRec.nRecInstance = nTmp >> 4;
- rIn.ReadUInt16(rRec.nRecType);
- rIn.ReadUInt32(rRec.nRecLen);
-
- // preserving overflow, optimally we would check
- // the record size against the parent header
- if (rRec.nRecLen > (SAL_MAX_UINT32 - rRec.nFilePos))
- rIn.SetError(SVSTREAM_FILEFORMAT_ERROR);
+ if (rIn.remainingSize() >= 8)
+ {
+ sal_uInt16 nTmp(0);
+ rIn.ReadUInt16(nTmp);
+ rRec.nImpVerInst = nTmp;
+ rRec.nRecVer = sal::static_int_cast<sal_uInt8>(nTmp & 0x000F);
+ rRec.nRecInstance = nTmp >> 4;
+ rIn.ReadUInt16(rRec.nRecType);
+ rIn.ReadUInt32(rRec.nRecLen);
+ // preserving overflow, optimally we would check
+ // the record size against the parent header
+ if (rRec.nRecLen > (SAL_MAX_UINT32 - rRec.nFilePos))
+ rIn.SetError(SVSTREAM_FILEFORMAT_ERROR);
+ }
+ else
+ {
+ rRec.nImpVerInst = 0;
+ rRec.nRecVer = 0;
+ rRec.nRecInstance = 0;
+ rIn.Seek(STREAM_SEEK_TO_END);
+ }
return rIn.good();
}
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index e2f5b2eac0a4..e3628be4411d 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -29,6 +29,7 @@
#include <o3tl/safeint.hxx>
#include <osl/file.hxx>
#include <tools/solar.h>
+#include <tools/diagnose_ex.h>
#include <sal/log.hxx>
#include <rtl/math.hxx>
@@ -5709,7 +5710,14 @@ SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
SetDefaultPropSet( rStCtrl, nOffsDgg );
// read control stream, if successful set nBLIPCount
- GetCtrlData( nOffsDgg );
+ try
+ {
+ GetCtrlData( nOffsDgg );
+ }
+ catch(SvStreamEOFException&)
+ {
+ TOOLS_WARN_EXCEPTION("filter.ms", "");
+ }
// check Text-Box-Story-Chain-Infos
CheckTxBxStoryChain();
diff --git a/include/tools/stream.hxx b/include/tools/stream.hxx
index 7e79516d8407..2032b30f1d74 100644
--- a/include/tools/stream.hxx
+++ b/include/tools/stream.hxx
@@ -16,8 +16,7 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef INCLUDED_TOOLS_STREAM_HXX
-#define INCLUDED_TOOLS_STREAM_HXX
+#pragma once
#include <tools/toolsdllapi.h>
#include <tools/lineend.hxx>
@@ -673,6 +672,11 @@ public:
virtual sal_uInt64 TellEnd() override { FlushBuffer(); return nEndOfData; }
};
-#endif
+/** thrown when reading past the end of file */
+class TOOLS_DLLPUBLIC SvStreamEOFException : public std::exception
+{
+public:
+ virtual const char * what() const throw() override;
+};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/lotuswordpro/inc/lwpsvstream.hxx b/lotuswordpro/inc/lwpsvstream.hxx
index 9a7271941f71..a962f6e599d6 100644
--- a/lotuswordpro/inc/lwpsvstream.hxx
+++ b/lotuswordpro/inc/lwpsvstream.hxx
@@ -72,6 +72,7 @@ public:
size_t Read(void* bytes, size_t nBytesToRead);
void SeekRel(sal_Int64 pos);
sal_Int64 Tell();
+ sal_uInt64 remainingSize();
sal_Int64 Seek(sal_Int64 pos);
bool CheckSeek(sal_Int64 pos);
diff --git a/lotuswordpro/source/filter/lwpobjhdr.cxx b/lotuswordpro/source/filter/lwpobjhdr.cxx
index 13ade159cd82..aeb5c895fc11 100644
--- a/lotuswordpro/source/filter/lwpobjhdr.cxx
+++ b/lotuswordpro/source/filter/lwpobjhdr.cxx
@@ -1,4 +1,3 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* The Contents of this file are made available subject to the terms of
@@ -105,6 +104,8 @@ bool LwpObjectHeader::Read(LwpSvStream& rStrm)
{
sal_uInt8 nFlagBits = 0;
sal_uInt16 VOType = 0;
+ if (rStrm.remainingSize() < 3)
+ return false;
rStrm.ReadUInt16(VOType);
rStrm.ReadUInt8(nFlagBits);
diff --git a/lotuswordpro/source/filter/lwpsvstream.cxx b/lotuswordpro/source/filter/lwpsvstream.cxx
index c95279a9f846..dfd18168a728 100644
--- a/lotuswordpro/source/filter/lwpsvstream.cxx
+++ b/lotuswordpro/source/filter/lwpsvstream.cxx
@@ -98,6 +98,8 @@ void LwpSvStream::SeekRel(sal_Int64 pos) { m_pStream->SeekRel(pos); }
* @descr Get the current position in stream
*/
sal_Int64 LwpSvStream::Tell() { return m_pStream->Tell(); }
+
+sal_uInt64 LwpSvStream::remainingSize() { return m_pStream->remainingSize(); }
/**
* @descr Seek to pos
*/
diff --git a/sc/qa/unit/data/qpro/pass/CVE-2007-5745-1.wb2 b/sc/qa/unit/data/qpro/fail/CVE-2007-5745-1.wb2
similarity index 100%
rename from sc/qa/unit/data/qpro/pass/CVE-2007-5745-1.wb2
rename to sc/qa/unit/data/qpro/fail/CVE-2007-5745-1.wb2
diff --git a/sc/qa/unit/data/qpro/pass/CVE-2007-5745-2.wb2 b/sc/qa/unit/data/qpro/fail/CVE-2007-5745-2.wb2
similarity index 100%
rename from sc/qa/unit/data/qpro/pass/CVE-2007-5745-2.wb2
rename to sc/qa/unit/data/qpro/fail/CVE-2007-5745-2.wb2
diff --git a/sc/qa/unit/data/qpro/pass/ofz14090-1.wb2 b/sc/qa/unit/data/qpro/fail/ofz14090-1.wb2
similarity index 100%
rename from sc/qa/unit/data/qpro/pass/ofz14090-1.wb2
rename to sc/qa/unit/data/qpro/fail/ofz14090-1.wb2
diff --git a/sc/qa/unit/data/qpro/pass/.gitignore b/sc/qa/unit/data/qpro/pass/.gitignore
new file mode 100644
index 000000000000..3d9caba05169
--- /dev/null
+++ b/sc/qa/unit/data/qpro/pass/.gitignore
@@ -0,0 +1,2 @@
+# only here so this directory exists in git
+# otherwise, the unit testing framework gets unhappy
\ No newline at end of file
diff --git a/sc/source/filter/excel/xltoolbar.cxx b/sc/source/filter/excel/xltoolbar.cxx
index 87f22f630843..d6b8dbac8704 100644
--- a/sc/source/filter/excel/xltoolbar.cxx
+++ b/sc/source/filter/excel/xltoolbar.cxx
@@ -341,8 +341,15 @@ ScCTBWrapper::Read( SvStream &rS)
{
SAL_INFO("sc.filter", "stream pos " << rS.Tell());
nOffSet = rS.Tell();
- if (!ctbSet.Read(rS))
+ try
+ {
+ if (!ctbSet.Read(rS))
+ return false;
+ }
+ catch(SvStreamEOFException&)
+ {
return false;
+ }
//ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
//and one 32bit number (4 bytes)
diff --git a/sc/source/filter/lotus/lotread.cxx b/sc/source/filter/lotus/lotread.cxx
index f28a783849fb..0fa8a1fb63d1 100644
--- a/sc/source/filter/lotus/lotread.cxx
+++ b/sc/source/filter/lotus/lotread.cxx
@@ -323,14 +323,21 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportWKS(SvStream& rStream)
LotusContext aContext(aDocument, RTL_TEXTENCODING_ASCII_US);
ImportLotus aLotusImport(aContext, rStream, RTL_TEXTENCODING_ASCII_US);
- ErrCode eRet = aLotusImport.parse();
- if (eRet == ErrCode(0xFFFFFFFF))
+ try
{
- rStream.Seek(0);
- eRet = ScImportLotus123old(aContext, rStream, RTL_TEXTENCODING_ASCII_US);
+ ErrCode eRet = aLotusImport.parse();
+ if (eRet == ErrCode(0xFFFFFFFF))
+ {
+ rStream.Seek(0);
+ eRet = ScImportLotus123old(aContext, rStream, RTL_TEXTENCODING_ASCII_US);
+ }
+ return eRet == ERRCODE_NONE;
+ }
+ catch(SvStreamEOFException&)
+ {
+ return false;
}
- return eRet == ERRCODE_NONE;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/qpro/qpro.cxx b/sc/source/filter/qpro/qpro.cxx
index 3e6756767eac..2b7641696644 100644
--- a/sc/source/filter/qpro/qpro.cxx
+++ b/sc/source/filter/qpro/qpro.cxx
@@ -227,7 +227,15 @@ ErrCode ScQProReader::parse(ScDocument& rDoc)
ErrCode ScQProReader::import( ScDocument& rDoc)
{
- ErrCode eRet = parse(rDoc);
+ ErrCode eRet;
+ try
+ {
+ eRet = parse(rDoc);
+ }
+ catch (SvStreamEOFException&)
+ {
+ eRet = SCERR_IMPORT_OPEN;
+ }
rDoc.CalcAfterLoad();
return eRet;
}
diff --git a/sd/qa/unit/data/ppt/pass/crash-1.ppt b/sd/qa/unit/data/ppt/fail/crash-1.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/crash-1.ppt
rename to sd/qa/unit/data/ppt/fail/crash-1.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-14.ppt b/sd/qa/unit/data/ppt/fail/hang-14.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-14.ppt
rename to sd/qa/unit/data/ppt/fail/hang-14.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-15.ppt b/sd/qa/unit/data/ppt/fail/hang-15.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-15.ppt
rename to sd/qa/unit/data/ppt/fail/hang-15.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-19.ppt b/sd/qa/unit/data/ppt/fail/hang-19.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-19.ppt
rename to sd/qa/unit/data/ppt/fail/hang-19.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-21.ppt b/sd/qa/unit/data/ppt/fail/hang-21.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-21.ppt
rename to sd/qa/unit/data/ppt/fail/hang-21.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-4.ppt b/sd/qa/unit/data/ppt/fail/hang-4.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-4.ppt
rename to sd/qa/unit/data/ppt/fail/hang-4.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-6.ppt b/sd/qa/unit/data/ppt/fail/hang-6.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-6.ppt
rename to sd/qa/unit/data/ppt/fail/hang-6.ppt
diff --git a/sd/qa/unit/data/ppt/pass/hang-8.ppt b/sd/qa/unit/data/ppt/fail/hang-8.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/hang-8.ppt
rename to sd/qa/unit/data/ppt/fail/hang-8.ppt
diff --git a/sd/qa/unit/data/ppt/pass/ofz14989-1.ppt b/sd/qa/unit/data/ppt/fail/ofz14989-1.ppt
similarity index 100%
rename from sd/qa/unit/data/ppt/pass/ofz14989-1.ppt
rename to sd/qa/unit/data/ppt/fail/ofz14989-1.ppt
diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx
index 02a2b544215d..254da0754bba 100644
--- a/sd/source/filter/ppt/pptin.cxx
+++ b/sd/source/filter/ppt/pptin.cxx
@@ -792,7 +792,8 @@ bool ImplSdPPTImport::Import()
while( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) )
{
DffRecordHeader aHd;
- ReadDffRecordHeader( rStCtrl, aHd );
+ if (!ReadDffRecordHeader( rStCtrl, aHd ))
+ break;
switch( aHd.nRecType )
{
case PPT_PST_PPDrawing :
@@ -2770,9 +2771,15 @@ ImplSdPPTImport::ReadFormControl( tools::SvRef<SotStorage>& rSrc1, css::uno::Ref
extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool ImportPPT(
SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium )
{
- std::unique_ptr<SdPPTImport> pImport( new SdPPTImport( pDocument, rDocStream, rStorage, rMedium ));
- bool bRet = pImport->Import();
- return bRet;
+ try
+ {
+ std::unique_ptr<SdPPTImport> pImport( new SdPPTImport( pDocument, rDocStream, rStorage, rMedium ));
+ return pImport->Import();
+ }
+ catch(SvStreamEOFException&)
+ {
+ return false;
+ }
}
extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportPPT(SvStream &rStream)
diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx
index 398e3fdb53d1..73a19719f86e 100644
--- a/sot/source/sdstor/stg.cxx
+++ b/sot/source/sdstor/stg.cxx
@@ -315,8 +315,17 @@ bool Storage::IsStorageFile( SvStream* pStream )
{
StgHeader aHdr;
sal_uInt64 nPos = pStream->Tell();
- bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
-
+ try
+ {
+ bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
+ }
+ catch(SvStreamEOFException&)
+ {
+ // It's not a stream error if it is too small for an OLE storage header
+ pStream->ResetError();
+ pStream->Seek( nPos );
+ return false;
+ }
// It's not a stream error if it is too small for an OLE storage header
if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
pStream->ResetError();
diff --git a/sw/qa/core/data/ww5/pass/crash-1.doc b/sw/qa/core/data/ww5/fail/crash-1.doc
similarity index 100%
rename from sw/qa/core/data/ww5/pass/crash-1.doc
rename to sw/qa/core/data/ww5/fail/crash-1.doc
diff --git a/sw/qa/core/data/ww5/pass/hang-1.doc b/sw/qa/core/data/ww5/fail/hang-1.doc
similarity index 100%
rename from sw/qa/core/data/ww5/pass/hang-1.doc
rename to sw/qa/core/data/ww5/fail/hang-1.doc
diff --git a/sw/qa/core/data/ww5/pass/hang-3.doc b/sw/qa/core/data/ww5/fail/hang-3.doc
similarity index 100%
rename from sw/qa/core/data/ww5/pass/hang-3.doc
rename to sw/qa/core/data/ww5/fail/hang-3.doc
diff --git a/sw/qa/core/data/ww6/pass/crash-2.doc b/sw/qa/core/data/ww6/fail/crash-2.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/crash-2.doc
rename to sw/qa/core/data/ww6/fail/crash-2.doc
diff --git a/sw/qa/core/data/ww6/pass/crash-3.doc b/sw/qa/core/data/ww6/fail/crash-3.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/crash-3.doc
rename to sw/qa/core/data/ww6/fail/crash-3.doc
diff --git a/sw/qa/core/data/ww6/pass/crash-4.doc b/sw/qa/core/data/ww6/fail/crash-4.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/crash-4.doc
rename to sw/qa/core/data/ww6/fail/crash-4.doc
diff --git a/sw/qa/core/data/ww6/pass/crash-5.doc b/sw/qa/core/data/ww6/fail/crash-5.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/crash-5.doc
rename to sw/qa/core/data/ww6/fail/crash-5.doc
diff --git a/sw/qa/core/data/ww6/pass/crash-6.doc b/sw/qa/core/data/ww6/fail/crash-6.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/crash-6.doc
rename to sw/qa/core/data/ww6/fail/crash-6.doc
diff --git a/sw/qa/core/data/ww6/pass/hang-1.doc b/sw/qa/core/data/ww6/fail/hang-1.doc
similarity index 100%
rename from sw/qa/core/data/ww6/pass/hang-1.doc
rename to sw/qa/core/data/ww6/fail/hang-1.doc
diff --git a/sw/qa/core/data/ww8/pass/CVE-2008-4841-1.doc b/sw/qa/core/data/ww8/fail/CVE-2008-4841-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/CVE-2008-4841-1.doc
rename to sw/qa/core/data/ww8/fail/CVE-2008-4841-1.doc
diff --git a/sw/qa/core/data/ww8/pass/CVE-2009-0259-1.doc b/sw/qa/core/data/ww8/fail/CVE-2009-0259-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/CVE-2009-0259-1.doc
rename to sw/qa/core/data/ww8/fail/CVE-2009-0259-1.doc
diff --git a/sw/qa/core/data/ww8/pass/CVE-2010-3454-1.doc b/sw/qa/core/data/ww8/fail/CVE-2010-3454-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/CVE-2010-3454-1.doc
rename to sw/qa/core/data/ww8/fail/CVE-2010-3454-1.doc
diff --git a/sw/qa/core/data/ww8/pass/CVE-2014-6356-1.doc b/sw/qa/core/data/ww8/fail/CVE-2014-6356-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/CVE-2014-6356-1.doc
rename to sw/qa/core/data/ww8/fail/CVE-2014-6356-1.doc
diff --git a/sw/qa/core/data/ww8/pass/CVE-2015-0064-1.doc b/sw/qa/core/data/ww8/fail/CVE-2015-0064-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/CVE-2015-0064-1.doc
rename to sw/qa/core/data/ww8/fail/CVE-2015-0064-1.doc
diff --git a/sw/qa/core/data/ww8/pass/EDB-14092-1.doc b/sw/qa/core/data/ww8/fail/EDB-14092-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/EDB-14092-1.doc
rename to sw/qa/core/data/ww8/fail/EDB-14092-1.doc
diff --git a/sw/qa/core/data/ww8/pass/hang-4.doc b/sw/qa/core/data/ww8/fail/hang-4.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/hang-4.doc
rename to sw/qa/core/data/ww8/fail/hang-4.doc
diff --git a/sw/qa/core/data/ww8/pass/ofz18534-1.doc b/sw/qa/core/data/ww8/fail/ofz18534-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/ofz18534-1.doc
rename to sw/qa/core/data/ww8/fail/ofz18534-1.doc
diff --git a/sw/qa/core/data/ww8/pass/ofz7322-1.doc b/sw/qa/core/data/ww8/fail/ofz7322-1.doc
similarity index 100%
rename from sw/qa/core/data/ww8/pass/ofz7322-1.doc
rename to sw/qa/core/data/ww8/fail/ofz7322-1.doc
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index e7b4dece4a41..36d8c6676b5d 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -99,49 +99,56 @@ bool ParseOLE2Presentation(SvStream& rOle2, sal_uInt32& nWidth, sal_uInt32& nHei
{
// See [MS-OLEDS] 2.3.4, OLEPresentationStream
rOle2.Seek(0);
- tools::SvRef<SotStorage> pStorage = new SotStorage(rOle2);
- tools::SvRef<SotStorageStream> xOle2Presentation
- = pStorage->OpenSotStream("\002OlePres000", StreamMode::STD_READ);
-
- // Read AnsiClipboardFormat.
- sal_uInt32 nMarkerOrLength = 0;
- xOle2Presentation->ReadUInt32(nMarkerOrLength);
- if (nMarkerOrLength != 0xffffffff)
- // FormatOrAnsiString is not present
- return false;
- sal_uInt32 nFormatOrAnsiLength = 0;
- xOle2Presentation->ReadUInt32(nFormatOrAnsiLength);
- if (nFormatOrAnsiLength != 0x00000003) // CF_METAFILEPICT
- return false;
-
- // Read TargetDeviceSize.
- sal_uInt32 nTargetDeviceSize = 0;
- xOle2Presentation->ReadUInt32(nTargetDeviceSize);
- if (nTargetDeviceSize != 0x00000004)
- // TargetDevice is present
- return false;
+ try
+ {
+ tools::SvRef<SotStorage> pStorage = new SotStorage(rOle2);
+ tools::SvRef<SotStorageStream> xOle2Presentation
+ = pStorage->OpenSotStream("\002OlePres000", StreamMode::STD_READ);
+
+ // Read AnsiClipboardFormat.
+ sal_uInt32 nMarkerOrLength = 0;
+ xOle2Presentation->ReadUInt32(nMarkerOrLength);
+ if (nMarkerOrLength != 0xffffffff)
+ // FormatOrAnsiString is not present
+ return false;
+ sal_uInt32 nFormatOrAnsiLength = 0;
+ xOle2Presentation->ReadUInt32(nFormatOrAnsiLength);
+ if (nFormatOrAnsiLength != 0x00000003) // CF_METAFILEPICT
+ return false;
+
+ // Read TargetDeviceSize.
+ sal_uInt32 nTargetDeviceSize = 0;
+ xOle2Presentation->ReadUInt32(nTargetDeviceSize);
+ if (nTargetDeviceSize != 0x00000004)
+ // TargetDevice is present
+ return false;
+
+ sal_uInt32 nAspect = 0;
+ xOle2Presentation->ReadUInt32(nAspect);
+ sal_uInt32 nLindex = 0;
+ xOle2Presentation->ReadUInt32(nLindex);
+ sal_uInt32 nAdvf = 0;
+ xOle2Presentation->ReadUInt32(nAdvf);
+ sal_uInt32 nReserved1 = 0;
+ xOle2Presentation->ReadUInt32(nReserved1);
+ xOle2Presentation->ReadUInt32(nWidth);
+ xOle2Presentation->ReadUInt32(nHeight);
+ sal_uInt32 nSize = 0;
+ xOle2Presentation->ReadUInt32(nSize);
+
+ // Read Data.
+ if (nSize > xOle2Presentation->remainingSize())
+ return false;
+ std::vector<char> aBuffer(nSize);
+ xOle2Presentation->ReadBytes(aBuffer.data(), aBuffer.size());
+ rPresentationData.WriteBytes(aBuffer.data(), aBuffer.size());
- sal_uInt32 nAspect = 0;
- xOle2Presentation->ReadUInt32(nAspect);
- sal_uInt32 nLindex = 0;
- xOle2Presentation->ReadUInt32(nLindex);
- sal_uInt32 nAdvf = 0;
- xOle2Presentation->ReadUInt32(nAdvf);
- sal_uInt32 nReserved1 = 0;
- xOle2Presentation->ReadUInt32(nReserved1);
- xOle2Presentation->ReadUInt32(nWidth);
- xOle2Presentation->ReadUInt32(nHeight);
- sal_uInt32 nSize = 0;
- xOle2Presentation->ReadUInt32(nSize);
-
- // Read Data.
- if (nSize > xOle2Presentation->remainingSize())
+ return true;
+ }
+ catch (SvStreamEOFException&)
+ {
return false;
- std::vector<char> aBuffer(nSize);
- xOle2Presentation->ReadBytes(aBuffer.data(), aBuffer.size());
- rPresentationData.WriteBytes(aBuffer.data(), aBuffer.size());
-
- return true;
+ }
}
/**
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 4a21a87b9a5c..01041ef4a02c 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -6962,6 +6962,9 @@ WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara)
// it will return a null pointer.
std::unique_ptr<WW8_STD> WW8Style::Read1STDFixed(sal_uInt16& rSkip)
{
+ if (m_rStream.remainingSize() < 2)
+ return nullptr;
+
std::unique_ptr<WW8_STD> pStd;
sal_uInt16 cbStd(0);
diff --git a/tools/qa/cppunit/test_stream.cxx b/tools/qa/cppunit/test_stream.cxx
index d8e4d1ef71e1..b58d1f07aaa5 100644
--- a/tools/qa/cppunit/test_stream.cxx
+++ b/tools/qa/cppunit/test_stream.cxx
@@ -84,18 +84,6 @@ namespace
//yet, the read didn't succeed
CPPUNIT_ASSERT(!aMemStream.good());
- //set things up so that there is only one byte available on an attempt
- //to read a two-byte sal_uInt16. The byte should be consumed, but the
- //operation should fail, and tools_b should remain unchanged,
- sal_uInt16 tools_b = 0x1122;
- aMemStream.SeekRel(-1);
- CPPUNIT_ASSERT(!aMemStream.eof());
- CPPUNIT_ASSERT(aMemStream.good());
- aMemStream.ReadUInt16( tools_b );
- CPPUNIT_ASSERT(!aMemStream.good());
- CPPUNIT_ASSERT(aMemStream.eof());
- CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(0x1122), tools_b);
-
iss.clear();
iss.seekg(0);
CPPUNIT_ASSERT(iss.good());
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index f807a56cf52f..0feae91ece83 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -527,6 +527,8 @@ bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
bool SvStream::ReadUniStringLine( OUString& rStr, sal_Int32 nMaxCodepointsToRead )
{
+ if (!good())
+ throw SvStreamEOFException();
sal_Unicode buf[256+1];
bool bEnd = false;
sal_uInt64 nOldFilePos = Tell();
@@ -819,6 +821,8 @@ sal_uInt64 SvStream::SeekRel(sal_Int64 const nPos)
SvStream& SvStream::ReadUInt16(sal_uInt16& r)
{
+ if (remainingSize() < 2)
+ throw SvStreamEOFException();
sal_uInt16 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -832,6 +836,8 @@ SvStream& SvStream::ReadUInt16(sal_uInt16& r)
SvStream& SvStream::ReadUInt32(sal_uInt32& r)
{
+ if (remainingSize() < 4)
+ throw SvStreamEOFException();
sal_uInt32 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -845,6 +851,8 @@ SvStream& SvStream::ReadUInt32(sal_uInt32& r)
SvStream& SvStream::ReadUInt64(sal_uInt64& r)
{
+ if (remainingSize() < 8)
+ throw SvStreamEOFException();
sal_uInt64 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -858,6 +866,8 @@ SvStream& SvStream::ReadUInt64(sal_uInt64& r)
SvStream& SvStream::ReadInt16(sal_Int16& r)
{
+ if (remainingSize() < 2)
+ throw SvStreamEOFException();
sal_Int16 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -871,6 +881,8 @@ SvStream& SvStream::ReadInt16(sal_Int16& r)
SvStream& SvStream::ReadInt32(sal_Int32& r)
{
+ if (remainingSize() < 4)
+ throw SvStreamEOFException();
sal_Int32 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -884,14 +896,13 @@ SvStream& SvStream::ReadInt32(sal_Int32& r)
SvStream& SvStream::ReadInt64(sal_Int64& r)
{
+ if (remainingSize() < 8)
+ throw SvStreamEOFException();
sal_Int64 n = 0;
readNumberWithoutSwap(n);
- if (good())
- {
- if (m_isSwap)
- SwapInt64(n);
- r = n;
- }
+ if (m_isSwap)
+ SwapInt64(n);
+ r = n;
return *this;
}
@@ -941,6 +952,8 @@ SvStream& SvStream::ReadUChar( unsigned char& r )
SvStream& SvStream::ReadUtf16(sal_Unicode& r)
{
+ if (remainingSize() < 2)
+ throw SvStreamEOFException();
sal_uInt16 n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -977,6 +990,8 @@ SvStream& SvStream::ReadCharAsBool( bool& r )
SvStream& SvStream::ReadFloat(float& r)
{
+ if (remainingSize() < 4)
+ throw SvStreamEOFException();
float n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -992,6 +1007,8 @@ SvStream& SvStream::ReadFloat(float& r)
SvStream& SvStream::ReadDouble(double& r)
{
+ if (remainingSize() < 8)
+ throw SvStreamEOFException();
double n = 0;
readNumberWithoutSwap(n);
if (good())
@@ -2132,4 +2149,9 @@ std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
return nWritten;
}
+const char * SvStreamEOFException::what() const throw()
+{
+ return "SvStreamEOFException";
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unotest/source/cpp/filters-test.cxx b/unotest/source/cpp/filters-test.cxx
index dc6dd5e3c33b..be5ee711b9be 100644
--- a/unotest/source/cpp/filters-test.cxx
+++ b/unotest/source/cpp/filters-test.cxx
@@ -61,7 +61,7 @@ void FiltersTest::recursiveScan(filterStatus nExpected,
{
osl::Directory aDir(rURL);
- CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, aDir.open());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUString("Failed to open directory " + rURL).toUtf8().getStr(), osl::FileBase::E_None, aDir.open());
osl::DirectoryItem aItem;
osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL|osl_FileStatus_Mask_Type);
std::set<OUString> dirs;
diff --git a/vcl/qa/cppunit/graphicfilter/data/png/pass/invalid-chunk.png b/vcl/qa/cppunit/graphicfilter/data/png/fail/invalid-chunk.png
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/png/pass/invalid-chunk.png
rename to vcl/qa/cppunit/graphicfilter/data/png/fail/invalid-chunk.png
diff --git a/vcl/qa/cppunit/graphicfilter/data/svm/pass/leak-1.svm b/vcl/qa/cppunit/graphicfilter/data/svm/fail/leak-1.svm
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/svm/pass/leak-1.svm
rename to vcl/qa/cppunit/graphicfilter/data/svm/fail/leak-1.svm
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index dd70545d3645..dd2a85ce142f 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -989,7 +989,14 @@ ErrCode GraphicFilter::ImportGraphic(
GraphicFilterImportFlags nImportFlags,
WmfExternal const *pExtHeader)
{
- return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
+ try
+ {
+ return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
+ }
+ catch (SvStreamEOFException&)
+ {
+ return ERRCODE_GRFILTER_FORMATERROR;
+ }
}
namespace {
diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx
index 3d71a6b3b96a..382ee0777d96 100644
--- a/vcl/source/filter/graphicfilter2.cxx
+++ b/vcl/source/filter/graphicfilter2.cxx
@@ -108,70 +108,75 @@ bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo )
sal_uInt16 nTemp16 = 0;
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
-
- rStm.SetEndian( SvStreamEndian::LITTLE );
- rStm.ReadUInt16( nTemp16 );
-
- // OS/2-BitmapArray
- if ( nTemp16 == 0x4142 )
+ try
{
- rStm.SeekRel( 0x0c );
+ rStm.SetEndian( SvStreamEndian::LITTLE );
rStm.ReadUInt16( nTemp16 );
- }
- // Bitmap
- if ( nTemp16 == 0x4d42 )
- {
- nFormat = GraphicFileFormat::BMP;
- bRet = true;
+ // OS/2-BitmapArray
+ if ( nTemp16 == 0x4142 )
+ {
+ rStm.SeekRel( 0x0c );
+ rStm.ReadUInt16( nTemp16 );
+ }
- if ( bExtendedInfo )
+ // Bitmap
+ if ( nTemp16 == 0x4d42 )
{
- sal_uInt32 nTemp32;
- sal_uInt32 nCompression;
+ nFormat = GraphicFileFormat::BMP;
+ bRet = true;
- // up to first info
- rStm.SeekRel( 0x10 );
+ if ( bExtendedInfo )
+ {
+ sal_uInt32 nTemp32;
+ sal_uInt32 nCompression;
- // Pixel width
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setWidth( nTemp32 );
+ // up to first info
+ rStm.SeekRel( 0x10 );
- // Pixel height
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setHeight( nTemp32 );
+ // Pixel width
+ rStm.ReadUInt32( nTemp32 );
+ aPixSize.setWidth( nTemp32 );
- // Planes
- rStm.ReadUInt16( nTemp16 );
- nPlanes = nTemp16;
+ // Pixel height
+ rStm.ReadUInt32( nTemp32 );
+ aPixSize.setHeight( nTemp32 );
- // BitCount
- rStm.ReadUInt16( nTemp16 );
- nBitsPerPixel = nTemp16;
+ // Planes
+ rStm.ReadUInt16( nTemp16 );
+ nPlanes = nTemp16;
- // Compression
- rStm.ReadUInt32( nTemp32 );
- nCompression = nTemp32;
+ // BitCount
+ rStm.ReadUInt16( nTemp16 );
+ nBitsPerPixel = nTemp16;
- // logical width
- rStm.SeekRel( 4 );
- rStm.ReadUInt32( nTemp32 );
- if ( nTemp32 )
- aLogSize.setWidth( ( aPixSize.Width() * 100000 ) / nTemp32 );
+ // Compression
+ rStm.ReadUInt32( nTemp32 );
+ nCompression = nTemp32;
- // logical height
- rStm.ReadUInt32( nTemp32 );
- if ( nTemp32 )
- aLogSize.setHeight( ( aPixSize.Height() * 100000 ) / nTemp32 );
+ // logical width
+ rStm.SeekRel( 4 );
+ rStm.ReadUInt32( nTemp32 );
+ if ( nTemp32 )
+ aLogSize.setWidth( ( aPixSize.Width() * 100000 ) / nTemp32 );
- // further validation, check for rational values
- if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
- {
- nFormat = GraphicFileFormat::NOT;
- bRet = false;
+ // logical height
+ rStm.ReadUInt32( nTemp32 );
+ if ( nTemp32 )
+ aLogSize.setHeight( ( aPixSize.Height() * 100000 ) / nTemp32 );
+
+ // further validation, check for rational values
+ if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
+ {
+ nFormat = GraphicFileFormat::NOT;
+ bRet = false;
+ }
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -183,36 +188,42 @@ bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, bool bExtendedInfo )
sal_Int32 nStmPos = rStm.Tell();
rStm.SetEndian( SvStreamEndian::LITTLE );
- rStm.ReadUInt32( n32 );
-
- if ( n32 == 0x38464947 )
+ try
{
- sal_uInt16 n16 = 0;
- rStm.ReadUInt16( n16 );
- if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
- {
- nFormat = GraphicFileFormat::GIF;
- bRet = true;
+ rStm.ReadUInt32( n32 );
- if ( bExtendedInfo )
+ if ( n32 == 0x38464947 )
+ {
+ sal_uInt16 n16 = 0;
+ rStm.ReadUInt16( n16 );
+ if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
{
- sal_uInt16 nTemp16 = 0;
- sal_uInt8 cByte = 0;
+ nFormat = GraphicFileFormat::GIF;
- // Pixel width
- rStm.ReadUInt16( nTemp16 );
- aPixSize.setWidth( nTemp16 );
+ if ( bExtendedInfo )
+ {
+ sal_uInt16 nTemp16 = 0;
+ sal_uInt8 cByte = 0;
- // Pixel height
- rStm.ReadUInt16( nTemp16 );
- aPixSize.setHeight( nTemp16 );
+ // Pixel width
+ rStm.ReadUInt16( nTemp16 );
+ aPixSize.setWidth( nTemp16 );
- // Bits/Pixel
- rStm.ReadUChar( cByte );
- nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
+ // Pixel height
+ rStm.ReadUInt16( nTemp16 );
+ aPixSize.setHeight( nTemp16 );
+
+ // Bits/Pixel
+ rStm.ReadUChar( cByte );
+ nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
+ }
+ bRet = true;
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -249,163 +260,169 @@ bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, bool bExtendedInfo )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
-
- rStm.SetEndian( SvStreamEndian::BIG );
- rStm.ReadUInt32( nTemp32 );
-
- // compare upper 24 bits
- if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
+ try
{
- nFormat = GraphicFileFormat::JPG;
- bRet = true;
- if ( bExtendedInfo )
+ rStm.SetEndian( SvStreamEndian::BIG );
+ rStm.ReadUInt32( nTemp32 );
+
+ // compare upper 24 bits
+ if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
{
- rStm.SeekRel( -2 );
+ nFormat = GraphicFileFormat::JPG;
+ bRet = true;
- ErrCode nError( rStm.GetError() );
+ if ( bExtendedInfo )
+ {
+ rStm.SeekRel( -2 );
- bool bScanFailure = false;
- bool bScanFinished = false;
- MapMode aMap;
+ ErrCode nError( rStm.GetError() );
- while (!bScanFailure && !bScanFinished && rStm.good())
- {
- sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
- switch( nMarker )
+ bool bScanFailure = false;
+ bool bScanFinished = false;
+ MapMode aMap;
+
+ while (!bScanFailure && !bScanFinished && rStm.good())
{
- // fixed size marker, not having a two byte length parameter
- case 0xd0 : // RST0
- case 0xd1 :
- case 0xd2 :
- case 0xd3 :
- case 0xd4 :
- case 0xd5 :
- case 0xd6 :
- case 0xd7 : // RST7
- case 0x01 : // TEM
- break;
-
- case 0xd8 : // SOI (has already been checked, there should not be a second one)
- case 0x00 : // marker is invalid, we should stop now
- bScanFailure = true;
- break;
-
- case 0xd9 : // EOI
- bScanFinished = true;
- break;
-
- // per default we assume marker segments containing a length parameter
- default :
+ sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
+ switch( nMarker )
{
- sal_uInt16 nLength = 0;
- rStm.ReadUInt16( nLength );
+ // fixed size marker, not having a two byte length parameter
+ case 0xd0 : // RST0
+ case 0xd1 :
+ case 0xd2 :
+ case 0xd3 :
+ case 0xd4 :
+ case 0xd5 :
+ case 0xd6 :
+ case 0xd7 : // RST7
+ case 0x01 : // TEM
+ break;
- if ( nLength < 2 )
+ case 0xd8 : // SOI (has already been checked, there should not be a second one)
+ case 0x00 : // marker is invalid, we should stop now
bScanFailure = true;
- else
+ break;
+
+ case 0xd9 : // EOI
+ bScanFinished = true;
+ break;
+
+ // per default we assume marker segments containing a length parameter
+ default :
{
- sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
- switch( nMarker )
+ sal_uInt16 nLength = 0;
+ rStm.ReadUInt16( nLength );
+
+ if ( nLength < 2 )
+ bScanFailure = true;
+ else
{
- case 0xe0 : // APP0 Marker
+ sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
+ switch( nMarker )
{
- if ( nLength == 16 )
+ case 0xe0 : // APP0 Marker
{
- sal_Int32 nIdentifier = 0;
- rStm.ReadInt32( nIdentifier );
- if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
+ if ( nLength == 16 )
{
- sal_uInt8 nStringTerminator = 0;
- sal_uInt8 nMajorRevision = 0;
- sal_uInt8 nMinorRevision = 0;
- sal_uInt8 nUnits = 0;
- sal_uInt16 nHorizontalResolution = 0;
- sal_uInt16 nVerticalResolution = 0;
- sal_uInt8 nHorzThumbnailPixelCount = 0;
- sal_uInt8 nVertThumbnailPixelCount = 0;
-
- rStm.ReadUChar( nStringTerminator )
- .ReadUChar( nMajorRevision )
- .ReadUChar( nMinorRevision )
- .ReadUChar( nUnits )
- .ReadUInt16( nHorizontalResolution )
- .ReadUInt16( nVerticalResolution )
- .ReadUChar( nHorzThumbnailPixelCount )
- .ReadUChar( nVertThumbnailPixelCount );
-
- // setting the logical size
- if ( nUnits && nHorizontalResolution && nVerticalResolution )
+ sal_Int32 nIdentifier = 0;
+ rStm.ReadInt32( nIdentifier );
+ if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
{
- aMap.SetMapUnit( nUnits == 1 ? MapUnit::MapInch : MapUnit::MapCM );
- aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
- aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
- aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MapUnit::Map100thMM ) );
+ sal_uInt8 nStringTerminator = 0;
+ sal_uInt8 nMajorRevision = 0;
+ sal_uInt8 nMinorRevision = 0;
+ sal_uInt8 nUnits = 0;
+ sal_uInt16 nHorizontalResolution = 0;
+ sal_uInt16 nVerticalResolution = 0;
+ sal_uInt8 nHorzThumbnailPixelCount = 0;
+ sal_uInt8 nVertThumbnailPixelCount = 0;
+
+ rStm.ReadUChar( nStringTerminator )
+ .ReadUChar( nMajorRevision )
+ .ReadUChar( nMinorRevision )
+ .ReadUChar( nUnits )
+ .ReadUInt16( nHorizontalResolution )
+ .ReadUInt16( nVerticalResolution )
+ .ReadUChar( nHorzThumbnailPixelCount )
+ .ReadUChar( nVertThumbnailPixelCount );
+
+ // setting the logical size
+ if ( nUnits && nHorizontalResolution && nVerticalResolution )
+ {
+ aMap.SetMapUnit( nUnits == 1 ? MapUnit::MapInch : MapUnit::MapCM );
+ aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
+ aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
+ aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MapUnit::Map100thMM ) );
+ }
}
}
}
+ break;
+
+ // Start of Frame Markers
+ case 0xc0 : // SOF0
+ case 0xc1 : // SOF1
+ case 0xc2 : // SOF2
+ case 0xc3 : // SOF3
+ case 0xc5 : // SOF5
+ case 0xc6 : // SOF6
+ case 0xc7 : // SOF7
+ case 0xc9 : // SOF9
+ case 0xca : // SOF10
+ case 0xcb : // SOF11
+ case 0xcd : // SOF13
+ case 0xce : // SOF14
+ case 0xcf : // SOF15
+ {
+ sal_uInt8 nSamplePrecision = 0;
+ sal_uInt16 nNumberOfLines = 0;
+ sal_uInt16 nSamplesPerLine = 0;
+ sal_uInt8 nNumberOfImageComponents = 0;
+ sal_uInt8 nComponentsIdentifier = 0;
+ sal_uInt8 nSamplingFactor = 0;
+ sal_uInt8 nQuantizationTableDestinationSelector = 0;
+ rStm.ReadUChar( nSamplePrecision )
+ .ReadUInt16( nNumberOfLines )
+ .ReadUInt16( nSamplesPerLine )
+ .ReadUChar( nNumberOfImageComponents )
+ .ReadUChar( nComponentsIdentifier )
+ .ReadUChar( nSamplingFactor )
+ .ReadUChar( nQuantizationTableDestinationSelector );
+ mnNumberOfImageComponents = nNumberOfImageComponents;
+
+ // nSamplingFactor (lower nibble: vertical,
+ // upper nibble: horizontal) is unused
+
+ aPixSize.setHeight( nNumberOfLines );
+ aPixSize.setWidth( nSamplesPerLine );
+ nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
+ nPlanes = 1;
+
+ if (aMap.GetMapUnit() != MapUnit::MapPixel)
+ // We already know the DPI, but the
+ // pixel size arrived later, so do the
+ // conversion again.
+ aLogSize = OutputDevice::LogicToLogic(
+ aPixSize, aMap, MapMode(MapUnit::Map100thMM));
+
+ bScanFinished = true;
+ }
+ break;
}
- break;
-
- // Start of Frame Markers
- case 0xc0 : // SOF0
- case 0xc1 : // SOF1
- case 0xc2 : // SOF2
- case 0xc3 : // SOF3
- case 0xc5 : // SOF5
- case 0xc6 : // SOF6
- case 0xc7 : // SOF7
- case 0xc9 : // SOF9
- case 0xca : // SOF10
- case 0xcb : // SOF11
- case 0xcd : // SOF13
- case 0xce : // SOF14
- case 0xcf : // SOF15
- {
- sal_uInt8 nSamplePrecision = 0;
- sal_uInt16 nNumberOfLines = 0;
- sal_uInt16 nSamplesPerLine = 0;
- sal_uInt8 nNumberOfImageComponents = 0;
- sal_uInt8 nComponentsIdentifier = 0;
- sal_uInt8 nSamplingFactor = 0;
- sal_uInt8 nQuantizationTableDestinationSelector = 0;
- rStm.ReadUChar( nSamplePrecision )
- .ReadUInt16( nNumberOfLines )
- .ReadUInt16( nSamplesPerLine )
- .ReadUChar( nNumberOfImageComponents )
- .ReadUChar( nComponentsIdentifier )
- .ReadUChar( nSamplingFactor )
- .ReadUChar( nQuantizationTableDestinationSelector );
- mnNumberOfImageComponents = nNumberOfImageComponents;
-
- // nSamplingFactor (lower nibble: vertical,
- // upper nibble: horizontal) is unused
-
- aPixSize.setHeight( nNumberOfLines );
- aPixSize.setWidth( nSamplesPerLine );
- nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
- nPlanes = 1;
-
- if (aMap.GetMapUnit() != MapUnit::MapPixel)
- // We already know the DPI, but the
- // pixel size arrived later, so do the
- // conversion again.
- aLogSize = OutputDevice::LogicToLogic(
- aPixSize, aMap, MapMode(MapUnit::Map100thMM));
-
- bScanFinished = true;
- }
- break;
+ rStm.Seek( nNextMarkerPos );
}
- rStm.Seek( nNextMarkerPos );
}
+ break;
}
- break;
}
+ rStm.SetError( nError );
}
- rStm.SetError( nError );
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -415,23 +432,29 @@ bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, bool )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::LITTLE );
+ try
+ {
+ rStm.SetEndian( SvStreamEndian::LITTLE );
- sal_uInt32 nTemp32 = 0;
- sal_uInt16 nTemp16 = 0;
- sal_uInt8 cByte = 0;
+ sal_uInt32 nTemp32 = 0;
+ sal_uInt16 nTemp16 = 0;
+ sal_uInt8 cByte = 0;
- rStm.SeekRel( 2048 );
- rStm.ReadUInt32( nTemp32 );
- rStm.ReadUInt16( nTemp16 );
- rStm.ReadUChar( cByte );
+ rStm.SeekRel( 2048 );
+ rStm.ReadUInt32( nTemp32 );
+ rStm.ReadUInt16( nTemp16 );
+ rStm.ReadUChar( cByte );
- if ( ( nTemp32 == 0x5f444350 ) &&
- ( nTemp16 == 0x5049 ) &&
- ( cByte == 0x49 ) )
+ if ( ( nTemp32 == 0x5f444350 ) &&
+ ( nTemp16 == 0x5049 ) &&
+ ( cByte == 0x49 ) )
+ {
+ nFormat = GraphicFileFormat::PCD;
+ bRet = true;
+ }
+ }
+ catch(SvStreamEOFException&)
{
- nFormat = GraphicFileFormat::PCD;
- bRet = true;
}
rStm.Seek( nStmPos );
return bRet;
@@ -448,67 +471,73 @@ bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm )
sal_uInt8 cByte = 0;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::LITTLE );
- rStm.ReadUChar( cByte );
-
- if ( cByte == 0x0a )
+ try
{
- nFormat = GraphicFileFormat::PCX;
-
- rStm.SeekRel( 1 );
-
- // compression
+ rStm.SetEndian( SvStreamEndian::LITTLE );
rStm.ReadUChar( cByte );
- bRet = (cByte==0 || cByte ==1);
- if (bRet)
+ if ( cByte == 0x0a )
{
- sal_uInt16 nTemp16;
- sal_uInt16 nXmin;
- sal_uInt16 nXmax;
- sal_uInt16 nYmin;
- sal_uInt16 nYmax;
- sal_uInt16 nDPIx;
- sal_uInt16 nDPIy;
-
- // Bits/Pixel
+ nFormat = GraphicFileFormat::PCX;
+
+ rStm.SeekRel( 1 );
+
+ // compression
rStm.ReadUChar( cByte );
- nBitsPerPixel = cByte;
- // image dimensions
- rStm.ReadUInt16( nTemp16 );
- nXmin = nTemp16;
- rStm.ReadUInt16( nTemp16 );
- nYmin = nTemp16;
- rStm.ReadUInt16( nTemp16 );
- nXmax = nTemp16;
- rStm.ReadUInt16( nTemp16 );
- nYmax = nTemp16;
+ bRet = (cByte==0 || cByte ==1);
+ if (bRet)
+ {
+ sal_uInt16 nTemp16;
+ sal_uInt16 nXmin;
+ sal_uInt16 nXmax;
+ sal_uInt16 nYmin;
+ sal_uInt16 nYmax;
+ sal_uInt16 nDPIx;
+ sal_uInt16 nDPIy;
- aPixSize.setWidth( nXmax - nXmin + 1 );
- aPixSize.setHeight( nYmax - nYmin + 1 );
+ // Bits/Pixel
+ rStm.ReadUChar( cByte );
+ nBitsPerPixel = cByte;
- // resolution
- rStm.ReadUInt16( nTemp16 );
- nDPIx = nTemp16;
- rStm.ReadUInt16( nTemp16 );
- nDPIy = nTemp16;
+ // image dimensions
+ rStm.ReadUInt16( nTemp16 );
+ nXmin = nTemp16;
+ rStm.ReadUInt16( nTemp16 );
+ nYmin = nTemp16;
+ rStm.ReadUInt16( nTemp16 );
+ nXmax = nTemp16;
+ rStm.ReadUInt16( nTemp16 );
+ nYmax = nTemp16;
- // set logical size
- MapMode aMap( MapUnit::MapInch, Point(),
- Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
- aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
- MapMode( MapUnit::Map100thMM ) );
+ aPixSize.setWidth( nXmax - nXmin + 1 );
+ aPixSize.setHeight( nYmax - nYmin + 1 );
- // number of color planes
- cByte = 5; // Illegal value in case of EOF.
- rStm.SeekRel( 49 );
- rStm.ReadUChar( cByte );
- nPlanes = cByte;
+ // resolution
+ rStm.ReadUInt16( nTemp16 );
+ nDPIx = nTemp16;
+ rStm.ReadUInt16( nTemp16 );
+ nDPIy = nTemp16;
+
+ // set logical size
+ MapMode aMap( MapUnit::MapInch, Point(),
+ Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
+ aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
+ MapMode( MapUnit::Map100thMM ) );
- bRet = (nPlanes<=4);
+ // number of color planes
+ cByte = 5; // Illegal value in case of EOF.
+ rStm.SeekRel( 49 );
+ rStm.ReadUChar( cByte );
+ nPlanes = cByte;
+
+ bRet = (nPlanes<=4);
+ }
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
@@ -520,109 +549,115 @@ bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::BIG );
- rStm.ReadUInt32( nTemp32 );
-
- if ( nTemp32 == 0x89504e47 )
+ try
{
+ rStm.SetEndian( SvStreamEndian::BIG );
rStm.ReadUInt32( nTemp32 );
- if ( nTemp32 == 0x0d0a1a0a )
- {
- nFormat = GraphicFileFormat::PNG;
- bRet = true;
- if ( bExtendedInfo )
+ if ( nTemp32 == 0x89504e47 )
+ {
+ rStm.ReadUInt32( nTemp32 );
+ if ( nTemp32 == 0x0d0a1a0a )
{
- do {
- sal_uInt8 cByte = 0;
+ nFormat = GraphicFileFormat::PNG;
+ bRet = true;
- // IHDR-Chunk
- rStm.SeekRel( 8 );
+ if ( bExtendedInfo )
+ {
+ do {
+ sal_uInt8 cByte = 0;
- // width
- rStm.ReadUInt32( nTemp32 );
- if (!rStm.good())
- break;
- aPixSize.setWidth( nTemp32 );
+ // IHDR-Chunk
+ rStm.SeekRel( 8 );
- // height
- rStm.ReadUInt32( nTemp32 );
- if (!rStm.good())
- break;
- aPixSize.setHeight( nTemp32 );
+ // width
+ rStm.ReadUInt32( nTemp32 );
+ if (!rStm.good())
+ break;
+ aPixSize.setWidth( nTemp32 );
- // Bits/Pixel
- rStm.ReadUChar( cByte );
- if (!rStm.good())
- break;
- nBitsPerPixel = cByte;
+ // height
+ rStm.ReadUInt32( nTemp32 );
+ if (!rStm.good())
+ break;
+ aPixSize.setHeight( nTemp32 );
- // Colour type - check whether it supports alpha values
- sal_uInt8 cColType = 0;
- rStm.ReadUChar( cColType );
- if (!rStm.good())
- break;
- bIsAlpha = bIsTransparent = ( cColType == 4 || cColType == 6 );
+ // Bits/Pixel
+ rStm.ReadUChar( cByte );
+ if (!rStm.good())
+ break;
+ nBitsPerPixel = cByte;
- // Planes always 1;
- // compression always
- nPlanes = 1;
+ // Colour type - check whether it supports alpha values
+ sal_uInt8 cColType = 0;
+ rStm.ReadUChar( cColType );
+ if (!rStm.good())
+ break;
+ bIsAlpha = bIsTransparent = ( cColType == 4 || cColType == 6 );
- sal_uInt32 nLen32 = 0;
- nTemp32 = 0;
+ // Planes always 1;
+ // compression always
+ nPlanes = 1;
- rStm.SeekRel( 7 );
+ sal_uInt32 nLen32 = 0;
+ nTemp32 = 0;
- // read up to the start of the image
- rStm.ReadUInt32( nLen32 );
- rStm.ReadUInt32( nTemp32 );
- while( ( nTemp32 != 0x49444154 ) && rStm.good() )
- {
- if ( nTemp32 == 0x70485973 ) // physical pixel dimensions
+ rStm.SeekRel( 7 );
+
+ // read up to the start of the image
+ rStm.ReadUInt32( nLen32 );
+ rStm.ReadUInt32( nTemp32 );
+ while( ( nTemp32 != 0x49444154 ) && rStm.good() )
{
- sal_uLong nXRes;
- sal_uLong nYRes;
+ if ( nTemp32 == 0x70485973 ) // physical pixel dimensions
+ {
+ sal_uLong nXRes;
+ sal_uLong nYRes;
- // horizontal resolution
- nTemp32 = 0;
- rStm.ReadUInt32( nTemp32 );
- nXRes = nTemp32;
+ // horizontal resolution
+ nTemp32 = 0;
+ rStm.ReadUInt32( nTemp32 );
+ nXRes = nTemp32;
- // vertical resolution
- nTemp32 = 0;
- rStm.ReadUInt32( nTemp32 );
- nYRes = nTemp32;
+ // vertical resolution
+ nTemp32 = 0;
+ rStm.ReadUInt32( nTemp32 );
+ nYRes = nTemp32;
- // unit
- cByte = 0;
- rStm.ReadUChar( cByte );
+ // unit
+ cByte = 0;
+ rStm.ReadUChar( cByte );
- if ( cByte )
- {
- if ( nXRes )
- aLogSize.setWidth( (aPixSize.Width() * 100000) / nXRes );
+ if ( cByte )
+ {
+ if ( nXRes )
+ aLogSize.setWidth( (aPixSize.Width() * 100000) / nXRes );
+
+ if ( nYRes )
+ aLogSize.setHeight( (aPixSize.Height() * 100000) / nYRes );
+ }
- if ( nYRes )
- aLogSize.setHeight( (aPixSize.Height() * 100000) / nYRes );
+ nLen32 -= 9;
+ }
+ else if ( nTemp32 == 0x74524e53 ) // transparency
+ {
+ bIsTransparent = true;
+ bIsAlpha = ( cColType != 0 && cColType != 2 );
}
- nLen32 -= 9;
- }
- else if ( nTemp32 == 0x74524e53 ) // transparency
- {
- bIsTransparent = true;
- bIsAlpha = ( cColType != 0 && cColType != 2 );
+ // skip forward to next chunk
+ rStm.SeekRel( 4 + nLen32 );
+ rStm.ReadUInt32( nLen32 );
+ rStm.ReadUInt32( nTemp32 );
}
-
- // skip forward to next chunk
- rStm.SeekRel( 4 + nLen32 );
- rStm.ReadUInt32( nLen32 );
- rStm.ReadUInt32( nTemp32 );
- }
- } while (false);
+ } while (false);
+ }
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -634,124 +669,130 @@ bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, bool bExtendedInfo )
sal_uInt8 cByte2 = 1;
sal_Int32 nStmPos = rStm.Tell();
- rStm.ReadUChar( cByte1 );
- rStm.ReadUChar( cByte2 );
- if ( cByte1 == cByte2 )
+ try
{
- bool bDetectOk = false;
-
- if ( cByte1 == 0x49 )
- {
- rStm.SetEndian( SvStreamEndian::LITTLE );
- bDetectOk = true;
- }
- else if ( cByte1 == 0x4d )
+ rStm.ReadUChar( cByte1 );
+ rStm.ReadUChar( cByte2 );
+ if ( cByte1 == cByte2 )
{
- rStm.SetEndian( SvStreamEndian::BIG );
- bDetectOk = true;
- }
+ bool bDetectOk = false;
- if ( bDetectOk )
- {
- sal_uInt16 nTemp16 = 0;
+ if ( cByte1 == 0x49 )
+ {
+ rStm.SetEndian( SvStreamEndian::LITTLE );
+ bDetectOk = true;
+ }
+ else if ( cByte1 == 0x4d )
+ {
+ rStm.SetEndian( SvStreamEndian::BIG );
+ bDetectOk = true;
+ }
- rStm.ReadUInt16( nTemp16 );
- if ( nTemp16 == 0x2a )
+ if ( bDetectOk )
{
- nFormat = GraphicFileFormat::TIF;
- bRet = true;
+ sal_uInt16 nTemp16 = 0;
- if ( bExtendedInfo )
+ rStm.ReadUInt16( nTemp16 );
+ if ( nTemp16 == 0x2a )
{
- sal_uLong nCount;
- sal_uLong nMax = DATA_SIZE - 48;
- sal_uInt32 nTemp32 = 0;
+ nFormat = GraphicFileFormat::TIF;
+ bRet = true;
- // Offset of the first IFD
- rStm.ReadUInt32( nTemp32 );
- nCount = nTemp32 + 2;
- rStm.SeekRel( nCount - 0x08 );
-
- if ( nCount < nMax )
+ if ( bExtendedInfo )
{
- bool bOk = false;
+ sal_uLong nCount;
+ sal_uLong nMax = DATA_SIZE - 48;
+ sal_uInt32 nTemp32 = 0;
- // read tags till we find Tag256 ( Width )
- // do not read more bytes than DATA_SIZE
- rStm.ReadUInt16( nTemp16 );
- while ( nTemp16 != 256 )
- {
- bOk = nCount < nMax;
- if ( !bOk )
- {
- break;
- }
- rStm.SeekRel( 10 );
- rStm.ReadUInt16( nTemp16 );
- nCount += 12;
- }
+ // Offset of the first IFD
+ rStm.ReadUInt32( nTemp32 );
+ nCount = nTemp32 + 2;
+ rStm.SeekRel( nCount - 0x08 );
- if ( bOk )
+ if ( nCount < nMax )
{
- // width
+ bool bOk = false;
+
+ // read tags till we find Tag256 ( Width )
+ // do not read more bytes than DATA_SIZE
rStm.ReadUInt16( nTemp16 );
- rStm.SeekRel( 4 );
- if ( nTemp16 == 3 )
+ while ( nTemp16 != 256 )
{
+ bOk = nCount < nMax;
+ if ( !bOk )
+ {
+ break;
+ }
+ rStm.SeekRel( 10 );
rStm.ReadUInt16( nTemp16 );
- aPixSize.setWidth( nTemp16 );
- rStm.SeekRel( 2 );
- }
- else
- {
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setWidth( nTemp32 );
+ nCount += 12;
}
- // height
- rStm.SeekRel( 2 );
- rStm.ReadUInt16( nTemp16 );
- rStm.SeekRel( 4 );
- if ( nTemp16 == 3 )
+ if ( bOk )
{
+ // width
rStm.ReadUInt16( nTemp16 );
- aPixSize.setHeight( nTemp16 );
+ rStm.SeekRel( 4 );
+ if ( nTemp16 == 3 )
+ {
+ rStm.ReadUInt16( nTemp16 );
+ aPixSize.setWidth( nTemp16 );
+ rStm.SeekRel( 2 );
+ }
+ else
+ {
+ rStm.ReadUInt32( nTemp32 );
+ aPixSize.setWidth( nTemp32 );
+ }
+
+ // height
rStm.SeekRel( 2 );
- }
- else
- {
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setHeight( nTemp32 );
- }
+ rStm.ReadUInt16( nTemp16 );
+ rStm.SeekRel( 4 );
+ if ( nTemp16 == 3 )
+ {
+ rStm.ReadUInt16( nTemp16 );
+ aPixSize.setHeight( nTemp16 );
+ rStm.SeekRel( 2 );
+ }
+ else
+ {
+ rStm.ReadUInt32( nTemp32 );
+ aPixSize.setHeight( nTemp32 );
+ }
- // Bits/Pixel
- rStm.ReadUInt16( nTemp16 );
- if ( nTemp16 == 258 )
- {
- rStm.SeekRel( 6 );
+ // Bits/Pixel
rStm.ReadUInt16( nTemp16 );
- nBitsPerPixel = nTemp16;
- rStm.SeekRel( 2 );
- }
- else
- rStm.SeekRel( -2 );
+ if ( nTemp16 == 258 )
+ {
+ rStm.SeekRel( 6 );
+ rStm.ReadUInt16( nTemp16 );
+ nBitsPerPixel = nTemp16;
+ rStm.SeekRel( 2 );
+ }
+ else
+ rStm.SeekRel( -2 );
- // compression
- rStm.ReadUInt16( nTemp16 );
- if ( nTemp16 == 259 )
- {
- rStm.SeekRel( 6 );
- rStm.ReadUInt16( nTemp16 ); // compression
- rStm.SeekRel( 2 );
+ // compression
+ rStm.ReadUInt16( nTemp16 );
+ if ( nTemp16 == 259 )
+ {
+ rStm.SeekRel( 6 );
+ rStm.ReadUInt16( nTemp16 ); // compression
+ rStm.SeekRel( 2 );
+ }
+ else
+ rStm.SeekRel( -2 );
}
- else
- rStm.SeekRel( -2 );
}
}
}
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -784,10 +825,16 @@ bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, bool )
else
{
sal_Int32 nStmPos = rStm.Tell();
- sal_uInt8 nFirst = 0, nSecond = 0;
- rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
- if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
- bRet = true;
+ try
+ {
+ sal_uInt8 nFirst = 0, nSecond = 0;
+ rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
+ if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
+ bRet = true;
+ }
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
}
@@ -807,9 +854,15 @@ bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, bool )
{
sal_uInt8 nFirst = 0, nSecond = 0;
sal_Int32 nStmPos = rStm.Tell();
- rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
- if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
- bRet = true;
+ try
+ {
+ rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
+ if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
+ bRet = true;
+ }
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
}
@@ -829,9 +882,15 @@ bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, bool )
{
sal_uInt8 nFirst = 0, nSecond = 0;
sal_Int32 nStmPos = rStm.Tell();
- rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
- if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
- bRet = true;
+ try
+ {
+ rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
+ if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
+ bRet = true;
+ }
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
}
@@ -846,12 +905,18 @@ bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, bool )
sal_uInt32 nMagicNumber = 0;
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::BIG );
- rStm.ReadUInt32( nMagicNumber );
- if ( nMagicNumber == 0x59a66a95 )
+ try
+ {
+ rStm.SetEndian( SvStreamEndian::BIG );
+ rStm.ReadUInt32( nMagicNumber );
+ if ( nMagicNumber == 0x59a66a95 )
+ {
+ nFormat = GraphicFileFormat::RAS;
+ bRet = true;
+ }
+ }
+ catch(SvStreamEOFException&)
{
- nFormat = GraphicFileFormat::RAS;
- bRet = true;
}
rStm.Seek( nStmPos );
return bRet;
@@ -872,50 +937,56 @@ bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, bool bExtendedInfo )
sal_uInt32 nMagicNumber = 0;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::BIG );
- rStm.ReadUInt32( nMagicNumber );
- if ( nMagicNumber == 0x38425053 )
+ try
{
- sal_uInt16 nVersion = 0;
- rStm.ReadUInt16( nVersion );
- if ( nVersion == 1 )
+ rStm.SetEndian( SvStreamEndian::BIG );
+ rStm.ReadUInt32( nMagicNumber );
+ if ( nMagicNumber == 0x38425053 )
{
- bRet = true;
- if ( bExtendedInfo )
+ sal_uInt16 nVersion = 0;
+ rStm.ReadUInt16( nVersion );
+ if ( nVersion == 1 )
{
- sal_uInt16 nChannels = 0;
- sal_uInt32 nRows = 0;
- sal_uInt32 nColumns = 0;
- sal_uInt16 nDepth = 0;
- sal_uInt16 nMode = 0;
- rStm.SeekRel( 6 ); // Pad
- rStm.ReadUInt16( nChannels ).ReadUInt32( nRows ).ReadUInt32( nColumns ).ReadUInt16( nDepth ).ReadUInt16( nMode );
- if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
+ bRet = true;
+ if ( bExtendedInfo )
{
- nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
- switch ( nChannels )
+ sal_uInt16 nChannels = 0;
+ sal_uInt32 nRows = 0;
+ sal_uInt32 nColumns = 0;
+ sal_uInt16 nDepth = 0;
+ sal_uInt16 nMode = 0;
+ rStm.SeekRel( 6 ); // Pad
+ rStm.ReadUInt16( nChannels ).ReadUInt32( nRows ).ReadUInt32( nColumns ).ReadUInt16( nDepth ).ReadUInt16( nMode );
+ if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
{
- case 4 :
- case 3 :
- nBitsPerPixel = 24;
- [[fallthrough]];
- case 2 :
- case 1 :
- aPixSize.setWidth( nColumns );
- aPixSize.setHeight( nRows );
- break;
- default:
- bRet = false;
+ nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
+ switch ( nChannels )
+ {
+ case 4 :
+ case 3 :
+ nBitsPerPixel = 24;
+ [[fallthrough]];
+ case 2 :
+ case 1 :
+ aPixSize.setWidth( nColumns );
+ aPixSize.setHeight( nRows );
+ break;
+ default:
+ bRet = false;
+ }
}
+ else
+ bRet = false;
}
- else
- bRet = false;
}
}
- }
- if ( bRet )
- nFormat = GraphicFileFormat::PSD;
+ if ( bRet )
+ nFormat = GraphicFileFormat::PSD;
+ }
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -928,17 +999,23 @@ bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, bool )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::BIG );
- rStm.ReadUInt32( nFirstLong );
- rStm.SeekRel( -4 );
- rStm.ReadBytes( &nFirstBytes, 20 );
-
- if ( ( nFirstLong == 0xC5D0D3C6 ) || aPathExt.startsWith( "eps" ) ||
- ( ImplSearchEntry( nFirstBytes, reinterpret_cast<sal_uInt8 const *>("%!PS-Adobe"), 10, 10 )
- && ImplSearchEntry( &nFirstBytes[15], reinterpret_cast<sal_uInt8 const *>("EPS"), 3, 3 ) ) )
+ try
+ {
+ rStm.SetEndian( SvStreamEndian::BIG );
+ rStm.ReadUInt32( nFirstLong );
+ rStm.SeekRel( -4 );
+ rStm.ReadBytes( &nFirstBytes, 20 );
+
+ if ( ( nFirstLong == 0xC5D0D3C6 ) || aPathExt.startsWith( "eps" ) ||
+ ( ImplSearchEntry( nFirstBytes, reinterpret_cast<sal_uInt8 const *>("%!PS-Adobe"), 10, 10 )
+ && ImplSearchEntry( &nFirstBytes[15], reinterpret_cast<sal_uInt8 const *>("EPS"), 3, 3 ) ) )
+ {
+ nFormat = GraphicFileFormat::EPS;
+ bRet = true;
+ }
+ }
+ catch(SvStreamEOFException&)
{
- nFormat = GraphicFileFormat::EPS;
- bRet = true;
}
rStm.Seek( nStmPos );
return bRet;
@@ -970,11 +1047,17 @@ bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, bool )
else
{
sal_uInt64 const nStreamPos = rStm.Tell();
- sal_uInt64 const nStreamLen = rStm.remainingSize();
- if (isPCT(rStm, nStreamPos, nStreamLen))
+ try
+ {
+ sal_uInt64 const nStreamLen = rStm.remainingSize();
+ if (isPCT(rStm, nStreamPos, nStreamLen))
+ {
+ bRet = true;
+ nFormat = GraphicFileFormat::PCT;
+ }
+ }
+ catch(SvStreamEOFException&)
{
- bRet = true;
- nFormat = GraphicFileFormat::PCT;
}
rStm.Seek(nStreamPos);
}
@@ -988,73 +1071,79 @@ bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, bool bExtendedInfo )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::LITTLE );
- rStm.ReadUInt32( n32 );
- if ( n32 == 0x44475653 )
+ try
{
- sal_uInt8 cByte = 0;
- rStm.ReadUChar( cByte );
- if ( cByte == 0x49 )
+ rStm.SetEndian( SvStreamEndian::LITTLE );
+ rStm.ReadUInt32( n32 );
+ if ( n32 == 0x44475653 )
{
- nFormat = GraphicFileFormat::SVM;
- bRet = true;
-
- if ( bExtendedInfo )
+ sal_uInt8 cByte = 0;
+ rStm.ReadUChar( cByte );
+ if ( cByte == 0x49 )
{
- sal_uInt32 nTemp32;
- sal_uInt16 nTemp16;
+ nFormat = GraphicFileFormat::SVM;
+ bRet = true;
- rStm.SeekRel( 0x04 );
+ if ( bExtendedInfo )
+ {
+ sal_uInt32 nTemp32;
+ sal_uInt16 nTemp16;
- // width
- nTemp32 = 0;
- rStm.ReadUInt32( nTemp32 );
- aLogSize.setWidth( nTemp32 );
+ rStm.SeekRel( 0x04 );
- // height
- nTemp32 = 0;
- rStm.ReadUInt32( nTemp32 );
- aLogSize.setHeight( nTemp32 );
+ // width
+ nTemp32 = 0;
+ rStm.ReadUInt32( nTemp32 );
+ aLogSize.setWidth( nTemp32 );
- // read MapUnit and determine PrefSize
- nTemp16 = 0;
- rStm.ReadUInt16( nTemp16 );
- aLogSize = OutputDevice::LogicToLogic( aLogSize,
- MapMode( static_cast<MapUnit>(nTemp16) ),
- MapMode( MapUnit::Map100thMM ) );
+ // height
+ nTemp32 = 0;
+ rStm.ReadUInt32( nTemp32 );
+ aLogSize.setHeight( nTemp32 );
+
+ // read MapUnit and determine PrefSize
+ nTemp16 = 0;
+ rStm.ReadUInt16( nTemp16 );
+ aLogSize = OutputDevice::LogicToLogic( aLogSize,
+ MapMode( static_cast<MapUnit>(nTemp16) ),
+ MapMode( MapUnit::Map100thMM ) );
+ }
}
}
- }
- else
- {
- rStm.SeekRel( -4 );
- n32 = 0;
- rStm.ReadUInt32( n32 );
-
- if( n32 == 0x4D4C4356 )
+ else
{
- sal_uInt16 nTmp16 = 0;
+ rStm.SeekRel( -4 );
+ n32 = 0;
+ rStm.ReadUInt32( n32 );
- rStm.ReadUInt16( nTmp16 );
-
- if( nTmp16 == 0x4654 )
+ if( n32 == 0x4D4C4356 )
{
- nFormat = GraphicFileFormat::SVM;
- bRet = true;
+ sal_uInt16 nTmp16 = 0;
+
+ rStm.ReadUInt16( nTmp16 );
- if( bExtendedInfo )
+ if( nTmp16 == 0x4654 )
{
- MapMode aMapMode;
+ nFormat = GraphicFileFormat::SVM;
+ bRet = true;
- rStm.SeekRel( 0x06 );
- ReadMapMode( rStm, aMapMode );
- TypeSerializer aSerializer(rStm);
- aSerializer.readSize(aLogSize);
- aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MapUnit::Map100thMM ) );
+ if( bExtendedInfo )
+ {
+ MapMode aMapMode;
+
+ rStm.SeekRel( 0x06 );
+ ReadMapMode( rStm, aMapMode );
+ TypeSerializer aSerializer(rStm);
+ aSerializer.readSize(aLogSize);
+ aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MapUnit::Map100thMM ) );
+ }
}
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
}
@@ -1074,44 +1163,50 @@ bool GraphicDescriptor::ImpDetectEMF( SvStream& rStm, bool bExtendedInfo )
bool bRet = false;
sal_Int32 nStmPos = rStm.Tell();
- rStm.SetEndian( SvStreamEndian::LITTLE );
- rStm.ReadUInt32( nRecordType );
-
- if ( nRecordType == 0x00000001 )
+ try
{
- sal_uInt32 nHeaderSize = 0;
- sal_Int32 nBoundLeft = 0, nBoundTop = 0, nBoundRight = 0, nBoundBottom = 0;
- sal_Int32 nFrameLeft = 0, nFrameTop = 0, nFrameRight = 0, nFrameBottom = 0;
- sal_uInt32 nSignature = 0;
-
- rStm.ReadUInt32( nHeaderSize );
- rStm.ReadInt32( nBoundLeft );
- rStm.ReadInt32( nBoundTop );
- rStm.ReadInt32( nBoundRight );
- rStm.ReadInt32( nBoundBottom );
- rStm.ReadInt32( nFrameLeft );
- rStm.ReadInt32( nFrameTop );
- rStm.ReadInt32( nFrameRight );
- rStm.ReadInt32( nFrameBottom );
- rStm.ReadUInt32( nSignature );
-
- if ( nSignature == 0x464d4520 )
- {
- nFormat = GraphicFileFormat::EMF;
- bRet = true;
+ rStm.SetEndian( SvStreamEndian::LITTLE );
+ rStm.ReadUInt32( nRecordType );
- if ( bExtendedInfo )
+ if ( nRecordType == 0x00000001 )
+ {
+ sal_uInt32 nHeaderSize = 0;
+ sal_Int32 nBoundLeft = 0, nBoundTop = 0, nBoundRight = 0, nBoundBottom = 0;
+ sal_Int32 nFrameLeft = 0, nFrameTop = 0, nFrameRight = 0, nFrameBottom = 0;
+ sal_uInt32 nSignature = 0;
+
+ rStm.ReadUInt32( nHeaderSize );
+ rStm.ReadInt32( nBoundLeft );
+ rStm.ReadInt32( nBoundTop );
+ rStm.ReadInt32( nBoundRight );
+ rStm.ReadInt32( nBoundBottom );
+ rStm.ReadInt32( nFrameLeft );
+ rStm.ReadInt32( nFrameTop );
+ rStm.ReadInt32( nFrameRight );
+ rStm.ReadInt32( nFrameBottom );
+ rStm.ReadUInt32( nSignature );
+
+ if ( nSignature == 0x464d4520 )
{
- // size in pixels
- aPixSize.setWidth( nBoundRight - nBoundLeft + 1 );
- aPixSize.setHeight( nBoundBottom - nBoundTop + 1 );
+ nFormat = GraphicFileFormat::EMF;
+ bRet = true;
+
+ if ( bExtendedInfo )
+ {
+ // size in pixels
+ aPixSize.setWidth( nBoundRight - nBoundLeft + 1 );
+ aPixSize.setHeight( nBoundBottom - nBoundTop + 1 );
- // size in 0.01mm units
- aLogSize.setWidth( nFrameRight - nFrameLeft + 1 );
- aLogSize.setHeight( nFrameBottom - nFrameTop + 1 );
+ // size in 0.01mm units
+ aLogSize.setWidth( nFrameRight - nFrameLeft + 1 );
+ aLogSize.setHeight( nFrameBottom - nFrameTop + 1 );
+ }
}
}
}
+ catch(SvStreamEOFException&)
+ {
+ }
rStm.Seek( nStmPos );
return bRet;
diff --git a/vcl/source/filter/png/pngread.cxx b/vcl/source/filter/png/pngread.cxx
index 8ab3cc216a8d..5a4e113867c9 100644
--- a/vcl/source/filter/png/pngread.cxx
+++ b/vcl/source/filter/png/pngread.cxx
@@ -256,7 +256,7 @@ bool PNGReaderImpl::ReadNextChunk()
// get the next chunk from the stream
// unless we are at the end of the PNG stream
- if (!mrPNGStream.good())
+ if (!mrPNGStream.good() || mrPNGStream.remainingSize() < 8)
return false;
if( !maChunkSeq.empty() && (maChunkSeq.back().nType == PNGCHUNK_IEND) )
return false;
diff --git a/vcl/source/gdi/TypeSerializer.cxx b/vcl/source/gdi/TypeSerializer.cxx
index f02edcb38b25..ac06a0d3bcb3 100644
--- a/vcl/source/gdi/TypeSerializer.cxx
+++ b/vcl/source/gdi/TypeSerializer.cxx
@@ -220,12 +220,13 @@ void TypeSerializer::readGraphic(Graphic& rGraphic)
{
sal_uInt32 nMagic1 = 0;
sal_uInt32 nMagic2 = 0;
- sal_uInt64 nBeginPosition = mrStream.Tell();
-
- mrStream.ReadUInt32(nMagic1);
- mrStream.ReadUInt32(nMagic2);
- mrStream.Seek(nBeginPosition);
-
+ if (mrStream.remainingSize() >= 8)
+ {
+ sal_uInt64 nBeginPosition = mrStream.Tell();
+ mrStream.ReadUInt32(nMagic1);
+ mrStream.ReadUInt32(nMagic2);
+ mrStream.Seek(nBeginPosition);
+ }
if (!mrStream.GetError())
{
if (nMagic1 == 0x5344414e && nMagic2 == 0x494d4931)
diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx
index c846d0a3a60c..4361f8b14053 100644
--- a/vcl/source/gdi/dibtools.cxx
+++ b/vcl/source/gdi/dibtools.cxx
@@ -151,6 +151,8 @@ bool isBitfieldCompression( ScanlineFormat nScanlineFormat )
bool ImplReadDIBInfoHeader(SvStream& rIStm, DIBV5Header& rHeader, bool& bTopDown, bool bMSOFormat)
{
+ if (rIStm.remainingSize() <= 4)
+ return false;
// BITMAPINFOHEADER or BITMAPCOREHEADER or BITMAPV5HEADER
sal_uInt64 const aStartPos(rIStm.Tell());
rIStm.ReadUInt32( rHeader.nSize );
@@ -1757,7 +1759,8 @@ bool ReadDIBBitmapEx(
sal_uInt32 nMagic2(0);
rTarget = BitmapEx(aBmp);
- rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
+ if (rIStm.remainingSize() >= 4)
+ rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
bRetval = (0x25091962 == nMagic1) && (0xACB20201 == nMagic2) && !rIStm.GetError();
if(bRetval)
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 2dd1d0447f10..70e4fafd09f0 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -1724,16 +1724,15 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
rImpGraphic.ImplClear();
- // read Id
- rIStm.ReadUInt32( nTmp );
-
// if there is no more data, avoid further expensive
// reading which will create VDevs and other stuff, just to
- // read nothing. CAUTION: Eof is only true AFTER reading another
- // byte, a speciality of SvMemoryStream (!)
- if (!rIStm.good())
+ // read nothing.
+ if (rIStm.remainingSize() < 4)
return;
+ // read Id
+ rIStm.ReadUInt32( nTmp );
+
if (NATIVE_FORMAT_50 == nTmp)
{
Graphic aGraphic;
@@ -1788,8 +1787,11 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
sal_uInt32 nMagic1(0), nMagic2(0);
sal_uLong nActPos = rIStm.Tell();
- rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
- rIStm.Seek( nActPos );
+ if (rIStm.remainingSize() >= 8)
+ {
+ rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
+ rIStm.Seek( nActPos );
+ }
rImpGraphic = ImpGraphic( aBmpEx );
More information about the Libreoffice-commits
mailing list