[Libreoffice-commits] core.git: vcl/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Tue Nov 19 13:32:34 UTC 2019
vcl/source/filter/graphicfilter2.cxx | 128 ++++++++++++++++++-----------------
1 file changed, 69 insertions(+), 59 deletions(-)
New commits:
commit 4ec93b7c71da27c0e986468e1635412a0c67cc00
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Mon Nov 18 21:19:01 2019 +0300
Commit: Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Tue Nov 19 14:31:43 2019 +0100
Fix UBSan build after 9fdf8c0a5cc036ea9bd1e11dd8f2c1a6e601fae2
The said commit simplified a testdoc to testTdf128820, using a smallest
possible SVG in it. This seems to produce the smallest possible PNG of
size 8, which is passed into GraphicDescriptor::ImpDetectPNG. There its
size is read into nTemp32 past the end of the file without checks,
which keeps last value of the variable (which was the magic number
0x0d0a1a0a), which is then saved into the descriptor. Then that value
is used in ImpGraphic::ImplGetSizePixel, and later multiplying it in
lclConvertScreenPixelToHmm causes UB.
Fix by checking all the reads in GraphicDescriptor::ImpDetectPNG.
Change-Id: Ib4740fac2b87fbef57d5150151129b9852f3ecb8
Reviewed-on: https://gerrit.libreoffice.org/83119
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx
index 5640e7c96ed2..0faaaeb81997 100644
--- a/vcl/source/filter/graphicfilter2.cxx
+++ b/vcl/source/filter/graphicfilter2.cxx
@@ -533,83 +533,93 @@ bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo )
if ( bExtendedInfo )
{
- sal_uInt8 cByte = 0;
+ do {
+ sal_uInt8 cByte = 0;
- // IHDR-Chunk
- rStm.SeekRel( 8 );
+ // IHDR-Chunk
+ rStm.SeekRel( 8 );
- // width
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setWidth( nTemp32 );
+ // width
+ rStm.ReadUInt32( nTemp32 );
+ if (!rStm.good())
+ break;
+ aPixSize.setWidth( nTemp32 );
- // height
- rStm.ReadUInt32( nTemp32 );
- aPixSize.setHeight( nTemp32 );
+ // height
+ rStm.ReadUInt32( nTemp32 );
+ if (!rStm.good())
+ break;
+ aPixSize.setHeight( nTemp32 );
- // Bits/Pixel
- rStm.ReadUChar( cByte );
- nBitsPerPixel = cByte;
+ // Bits/Pixel
+ rStm.ReadUChar( cByte );
+ if (!rStm.good())
+ break;
+ nBitsPerPixel = cByte;
- // Colour type - check whether it supports alpha values
- sal_uInt8 cColType = 0;
- rStm.ReadUChar( cColType );
- bIsAlpha = bIsTransparent = ( cColType == 4 || cColType == 6 );
+ // 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 );
- // Planes always 1;
- // compression always
- nPlanes = 1;
+ // Planes always 1;
+ // compression always
+ nPlanes = 1;
- sal_uInt32 nLen32 = 0;
- nTemp32 = 0;
+ sal_uInt32 nLen32 = 0;
+ nTemp32 = 0;
- rStm.SeekRel( 7 );
+ rStm.SeekRel( 7 );
- // 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
+ // 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);
}
}
}
More information about the Libreoffice-commits
mailing list