@@ -1395,7 +1395,7 @@ private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata met
13951395
13961396 ReadOnlySpan < byte > compressedData = data [ ( zeroIndex + 2 ) ..] ;
13971397
1398- if ( this . TryUncompressTextData ( compressedData , PngConstants . Encoding , out string ? uncompressed )
1398+ if ( this . TryDecompressTextData ( compressedData , PngConstants . Encoding , out string ? uncompressed )
13991399 && ! TryReadTextChunkMetadata ( baseMetadata , name , uncompressed ) )
14001400 {
14011401 metadata . TextData . Add ( new PngTextData ( name , uncompressed , string . Empty , string . Empty ) ) ;
@@ -1539,19 +1539,19 @@ private void ReadColorProfileChunk(ImageMetadata metadata, ReadOnlySpan<byte> da
15391539
15401540 ReadOnlySpan < byte > compressedData = data [ ( zeroIndex + 2 ) ..] ;
15411541
1542- if ( this . TryUncompressZlibData ( compressedData , out byte [ ] iccpProfileBytes ) )
1542+ if ( this . TryDecompressZlibData ( compressedData , out byte [ ] iccpProfileBytes ) )
15431543 {
15441544 metadata . IccProfile = new IccProfile ( iccpProfileBytes ) ;
15451545 }
15461546 }
15471547
15481548 /// <summary>
1549- /// Tries to un-compress zlib compressed data.
1549+ /// Tries to decompress zlib compressed data.
15501550 /// </summary>
15511551 /// <param name="compressedData">The compressed data.</param>
15521552 /// <param name="uncompressedBytesArray">The uncompressed bytes array.</param>
15531553 /// <returns>True, if de-compressing was successful.</returns>
1554- private unsafe bool TryUncompressZlibData ( ReadOnlySpan < byte > compressedData , out byte [ ] uncompressedBytesArray )
1554+ private unsafe bool TryDecompressZlibData ( ReadOnlySpan < byte > compressedData , out byte [ ] uncompressedBytesArray )
15551555 {
15561556 fixed ( byte * compressedDataBase = compressedData )
15571557 {
@@ -1688,7 +1688,7 @@ private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan<byt
16881688 {
16891689 ReadOnlySpan < byte > compressedData = data [ dataStartIdx ..] ;
16901690
1691- if ( this . TryUncompressTextData ( compressedData , PngConstants . TranslatedEncoding , out string ? uncompressed ) )
1691+ if ( this . TryDecompressTextData ( compressedData , PngConstants . TranslatedEncoding , out string ? uncompressed ) )
16921692 {
16931693 pngMetadata . TextData . Add ( new PngTextData ( keyword , uncompressed , language , translatedKeyword ) ) ;
16941694 }
@@ -1711,9 +1711,9 @@ private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan<byt
17111711 /// <param name="encoding">The string encoding to use.</param>
17121712 /// <param name="value">The uncompressed value.</param>
17131713 /// <returns>The <see cref="bool"/>.</returns>
1714- private bool TryUncompressTextData ( ReadOnlySpan < byte > compressedData , Encoding encoding , [ NotNullWhen ( true ) ] out string ? value )
1714+ private bool TryDecompressTextData ( ReadOnlySpan < byte > compressedData , Encoding encoding , [ NotNullWhen ( true ) ] out string ? value )
17151715 {
1716- if ( this . TryUncompressZlibData ( compressedData , out byte [ ] uncompressedData ) )
1716+ if ( this . TryDecompressZlibData ( compressedData , out byte [ ] uncompressedData ) )
17171717 {
17181718 value = encoding . GetString ( uncompressedData ) ;
17191719 return true ;
@@ -1736,7 +1736,11 @@ private int ReadNextDataChunk()
17361736
17371737 Span < byte > buffer = stackalloc byte [ 20 ] ;
17381738
1739- _ = this . currentStream . Read ( buffer , 0 , 4 ) ;
1739+ int length = this . currentStream . Read ( buffer , 0 , 4 ) ;
1740+ if ( length == 0 )
1741+ {
1742+ return 0 ;
1743+ }
17401744
17411745 if ( this . TryReadChunk ( buffer , out PngChunk chunk ) )
17421746 {
@@ -1765,7 +1769,11 @@ private int ReadNextFrameDataChunk()
17651769
17661770 Span < byte > buffer = stackalloc byte [ 20 ] ;
17671771
1768- _ = this . currentStream . Read ( buffer , 0 , 4 ) ;
1772+ int length = this . currentStream . Read ( buffer , 0 , 4 ) ;
1773+ if ( length == 0 )
1774+ {
1775+ return 0 ;
1776+ }
17691777
17701778 if ( this . TryReadChunk ( buffer , out PngChunk chunk ) )
17711779 {
@@ -1802,8 +1810,9 @@ private bool TryReadChunk(Span<byte> buffer, out PngChunk chunk)
18021810 return true ;
18031811 }
18041812
1805- if ( this . currentStream . Position == this . currentStream . Length )
1813+ if ( this . currentStream . Position >= this . currentStream . Length - 1 )
18061814 {
1815+ // IEND
18071816 chunk = default ;
18081817 return false ;
18091818 }
@@ -1820,6 +1829,7 @@ private bool TryReadChunk(Span<byte> buffer, out PngChunk chunk)
18201829 // Not a valid chunk so try again until we reach a known chunk.
18211830 if ( ! this . TryReadChunkLength ( buffer , out length ) )
18221831 {
1832+ // IEND
18231833 chunk = default ;
18241834 return false ;
18251835 }
@@ -1832,10 +1842,11 @@ private bool TryReadChunk(Span<byte> buffer, out PngChunk chunk)
18321842 if ( this . colorMetadataOnly && type != PngChunkType . Header && type != PngChunkType . Transparency && type != PngChunkType . Palette )
18331843 {
18341844 chunk = new PngChunk ( length , type ) ;
1835-
18361845 return true ;
18371846 }
18381847
1848+ // A chunk might report a length that exceeds the length of the stream.
1849+ // Take the minimum of the two values to ensure we don't read past the end of the stream.
18391850 long position = this . currentStream . Position ;
18401851 chunk = new PngChunk (
18411852 length : ( int ) Math . Min ( length , this . currentStream . Length - position ) ,
0 commit comments