@ -34,6 +34,8 @@
# include "image.hpp"
# include "image.hpp"
# include "error.hpp"
# include "error.hpp"
# include "enforce.hpp"
# include "enforce.hpp"
# include "helper_functions.hpp"
# include "safe_op.hpp"
// + standard includes
// + standard includes
# include <sstream>
# include <sstream>
@ -133,6 +135,8 @@ namespace Exiv2 {
if ( type = = zTXt_Chunk )
if ( type = = zTXt_Chunk )
{
{
enforce ( data . size_ > = Safe : : add ( keysize , 2 ) , Exiv2 : : kerCorruptedMetadata ) ;
// Extract a deflate compressed Latin-1 text chunk
// Extract a deflate compressed Latin-1 text chunk
// we get the compression method after the key
// we get the compression method after the key
@ -149,11 +153,13 @@ namespace Exiv2 {
// compressed string after the compression technique spec
// compressed string after the compression technique spec
const byte * compressedText = data . pData_ + keysize + 2 ;
const byte * compressedText = data . pData_ + keysize + 2 ;
unsigned int compressedTextSize = data . size_ - keysize - 2 ;
unsigned int compressedTextSize = data . size_ - keysize - 2 ;
enforce ( compressedTextSize < data . size_ , kerCorruptedMetadata ) ;
zlibUncompress ( compressedText , compressedTextSize , arr ) ;
zlibUncompress ( compressedText , compressedTextSize , arr ) ;
}
}
else if ( type = = tEXt_Chunk )
else if ( type = = tEXt_Chunk )
{
{
enforce ( data . size_ > = Safe : : add ( keysize , 1 ) , Exiv2 : : kerCorruptedMetadata ) ;
// Extract a non-compressed Latin-1 text chunk
// Extract a non-compressed Latin-1 text chunk
// the text comes after the key, but isn't null terminated
// the text comes after the key, but isn't null terminated
@ -164,6 +170,7 @@ namespace Exiv2 {
}
}
else if ( type = = iTXt_Chunk )
else if ( type = = iTXt_Chunk )
{
{
enforce ( data . size_ > = Safe : : add ( keysize , 3 ) , Exiv2 : : kerCorruptedMetadata ) ;
const int nullSeparators = std : : count ( & data . pData_ [ keysize + 3 ] , & data . pData_ [ data . size_ ] , ' \0 ' ) ;
const int nullSeparators = std : : count ( & data . pData_ [ keysize + 3 ] , & data . pData_ [ data . size_ ] , ' \0 ' ) ;
enforce ( nullSeparators > = 2 , Exiv2 : : kerCorruptedMetadata ) ;
enforce ( nullSeparators > = 2 , Exiv2 : : kerCorruptedMetadata ) ;
@ -178,41 +185,45 @@ namespace Exiv2 {
enforce ( compressionMethod = = 0x00 , Exiv2 : : kerCorruptedMetadata ) ;
enforce ( compressionMethod = = 0x00 , Exiv2 : : kerCorruptedMetadata ) ;
// language description string after the compression technique spec
// language description string after the compression technique spec
std : : string languageText ( ( const char * ) ( data . pData_ + keysize + 3 ) ) ;
const size_t languageTextMaxSize = data . size_ - keysize - 3 ;
unsigned int languageTextSize = static_cast < unsigned int > ( languageText . size ( ) ) ;
std : : string languageText =
string_from_unterminated ( ( const char * ) ( data . pData_ + Safe : : add ( keysize , 3 ) ) , languageTextMaxSize ) ;
const unsigned int languageTextSize = static_cast < unsigned int > ( languageText . size ( ) ) ;
enforce ( data . size_ > = Safe : : add ( static_cast < unsigned int > ( Safe : : add ( keysize , 4 ) ) , languageTextSize ) ,
Exiv2 : : kerCorruptedMetadata ) ;
// translated keyword string after the language description
// translated keyword string after the language description
std : : string translatedKeyText ( ( const char * ) ( data . pData_ + keysize + 3 + languageTextSize + 1 ) ) ;
std : : string translatedKeyText =
unsigned int translatedKeyTextSize = static_cast < unsigned int > ( translatedKeyText . size ( ) ) ;
string_from_unterminated ( ( const char * ) ( data . pData_ + keysize + 3 + languageTextSize + 1 ) ,
data . size_ - ( keysize + 3 + languageTextSize + 1 ) ) ;
const unsigned int translatedKeyTextSize = static_cast < unsigned int > ( translatedKeyText . size ( ) ) ;
if ( compressionFlag = = 0x00 )
if ( ( compressionFlag = = 0x00 ) | | ( compressionFlag = = 0x01 & & compressionMethod = = 0x00 ) ) {
{
enforce ( Safe : : add ( static_cast < unsigned int > ( keysize + 3 + languageTextSize + 1 ) ,
Safe : : add ( translatedKeyTextSize , 1u ) ) < = data . size_ ,
Exiv2 : : kerCorruptedMetadata ) ;
const byte * text = data . pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ;
const long textsize = data . size_ - ( keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ) ;
if ( compressionFlag = = 0x00 ) {
// then it's an uncompressed iTXt chunk
// then it's an uncompressed iTXt chunk
# ifdef DEBUG
# ifdef DEBUG
std : : cout < < " Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field \n " ;
std : : cout < < " Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field \n " ;
# endif
# endif
// the text comes after the translated keyword, but isn't null terminated
const byte * text = data . pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ;
long textsize = data . size_ - ( keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ) ;
arr . alloc ( textsize ) ;
arr . alloc ( textsize ) ;
arr = DataBuf ( text , textsize ) ;
arr = DataBuf ( text , textsize ) ;
}
} else if ( compressionFlag = = 0x01 & & compressionMethod = = 0x00 ) {
else if ( compressionFlag = = 0x01 & & compressionMethod = = 0x00 )
{
// then it's a zlib compressed iTXt chunk
// then it's a zlib compressed iTXt chunk
# ifdef DEBUG
# ifdef DEBUG
std : : cout < < " Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field \n " ;
std : : cout < < " Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field \n " ;
# endif
# endif
// the compressed text comes after the translated keyword, but isn't null terminated
// the compressed text comes after the translated keyword, but isn't null terminated
const byte * compressedText = data . pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ;
zlibUncompress ( text , textsize , arr ) ;
long compressedTextSize = data . size_ - ( keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1 ) ;
zlibUncompress ( compressedText , compressedTextSize , arr ) ;
}
}
else
} else {
{
// then it isn't zlib compressed and we are sunk
// then it isn't zlib compressed and we are sunk
# ifdef DEBUG
# ifdef DEBUG
std : : cerr < < " Exiv2::PngChunk::parseTXTChunk: Non-standard iTXt compression method. \n " ;
std : : cerr < < " Exiv2::PngChunk::parseTXTChunk: Non-standard iTXt compression method. \n " ;