diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp
index e0518f13da..eeebe8b305 100644
--- a/DesktopEditor/common/File.cpp
+++ b/DesktopEditor/common/File.cpp
@@ -159,60 +159,90 @@ namespace NSFile
else if (0x00 == (byteMain & 0x20))
{
// 2 byte
- int val = (int)(((byteMain & 0x1F) << 6) |
- (pBuffer[lIndex + 1] & 0x3F));
+ int val = 0;
+ if ((lIndex + 1) < lCount)
+ {
+ val = (int)(((byteMain & 0x1F) << 6) |
+ (pBuffer[lIndex + 1] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 2;
}
else if (0x00 == (byteMain & 0x10))
{
// 3 byte
- int val = (int)(((byteMain & 0x0F) << 12) |
- ((pBuffer[lIndex + 1] & 0x3F) << 6) |
- (pBuffer[lIndex + 2] & 0x3F));
+ int val = 0;
+ if ((lIndex + 2) < lCount)
+ {
+ val = (int)(((byteMain & 0x0F) << 12) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 6) |
+ (pBuffer[lIndex + 2] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 3;
}
else if (0x00 == (byteMain & 0x0F))
{
// 4 byte
- int val = (int)(((byteMain & 0x07) << 18) |
- ((pBuffer[lIndex + 1] & 0x3F) << 12) |
- ((pBuffer[lIndex + 2] & 0x3F) << 6) |
- (pBuffer[lIndex + 3] & 0x3F));
+ int val = 0;
+ if ((lIndex + 3) < lCount)
+ {
+ val = (int)(((byteMain & 0x07) << 18) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 6) |
+ (pBuffer[lIndex + 3] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 4;
}
else if (0x00 == (byteMain & 0x08))
{
// 4 byte
- int val = (int)(((byteMain & 0x07) << 18) |
- ((pBuffer[lIndex + 1] & 0x3F) << 12) |
- ((pBuffer[lIndex + 2] & 0x3F) << 6) |
- (pBuffer[lIndex + 3] & 0x3F));
+ int val = 0;
+ if ((lIndex + 3) < lCount)
+ {
+ val = (int)(((byteMain & 0x07) << 18) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 6) |
+ (pBuffer[lIndex + 3] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 4;
}
else if (0x00 == (byteMain & 0x04))
{
// 5 byte
- int val = (int)(((byteMain & 0x03) << 24) |
- ((pBuffer[lIndex + 1] & 0x3F) << 18) |
- ((pBuffer[lIndex + 2] & 0x3F) << 12) |
- ((pBuffer[lIndex + 3] & 0x3F) << 6) |
- (pBuffer[lIndex + 4] & 0x3F));
+ int val = 0;
+ if ((lIndex + 4) < lCount)
+ {
+ val = (int)(((byteMain & 0x03) << 24) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 18) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 3] & 0x3F) << 6) |
+ (pBuffer[lIndex + 4] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 5;
}
else
{
// 6 byte
- int val = (int)(((byteMain & 0x01) << 30) |
- ((pBuffer[lIndex + 1] & 0x3F) << 24) |
- ((pBuffer[lIndex + 2] & 0x3F) << 18) |
- ((pBuffer[lIndex + 3] & 0x3F) << 12) |
- ((pBuffer[lIndex + 4] & 0x3F) << 6) |
- (pBuffer[lIndex + 5] & 0x3F));
+ int val = 0;
+ if ((lIndex + 5) < lCount)
+ {
+ val = (int)(((byteMain & 0x01) << 30) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 24) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 18) |
+ ((pBuffer[lIndex + 3] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 4] & 0x3F) << 6) |
+ (pBuffer[lIndex + 5] & 0x3F));
+ }
+
pUnicodeString[lIndexUnicode++] = (WCHAR)(val);
lIndex += 5;
}
@@ -242,17 +272,26 @@ namespace NSFile
else if (0x00 == (byteMain & 0x20))
{
// 2 byte
- int val = (int)(((byteMain & 0x1F) << 6) |
- (pBuffer[lIndex + 1] & 0x3F));
+ int val = 0;
+ if ((lIndex + 1) < lCount)
+ {
+ val = (int)(((byteMain & 0x1F) << 6) |
+ (pBuffer[lIndex + 1] & 0x3F));
+ }
+
*pUnicodeString++ = (WCHAR)(val);
lIndex += 2;
}
else if (0x00 == (byteMain & 0x10))
{
// 3 byte
- int val = (int)(((byteMain & 0x0F) << 12) |
- ((pBuffer[lIndex + 1] & 0x3F) << 6) |
- (pBuffer[lIndex + 2] & 0x3F));
+ int val = 0;
+ if ((lIndex + 2) < lCount)
+ {
+ val = (int)(((byteMain & 0x0F) << 12) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 6) |
+ (pBuffer[lIndex + 2] & 0x3F));
+ }
WriteUtf16_WCHAR(val, pUnicodeString);
lIndex += 3;
@@ -260,10 +299,14 @@ namespace NSFile
else if (0x00 == (byteMain & 0x0F))
{
// 4 byte
- int val = (int)(((byteMain & 0x07) << 18) |
- ((pBuffer[lIndex + 1] & 0x3F) << 12) |
- ((pBuffer[lIndex + 2] & 0x3F) << 6) |
- (pBuffer[lIndex + 3] & 0x3F));
+ int val = 0;
+ if ((lIndex + 3) < lCount)
+ {
+ val = (int)(((byteMain & 0x07) << 18) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 6) |
+ (pBuffer[lIndex + 3] & 0x3F));
+ }
WriteUtf16_WCHAR(val, pUnicodeString);
lIndex += 4;
@@ -271,10 +314,14 @@ namespace NSFile
else if (0x00 == (byteMain & 0x08))
{
// 4 byte
- int val = (int)(((byteMain & 0x07) << 18) |
- ((pBuffer[lIndex + 1] & 0x3F) << 12) |
- ((pBuffer[lIndex + 2] & 0x3F) << 6) |
- (pBuffer[lIndex + 3] & 0x3F));
+ int val = 0;
+ if ((lIndex + 3) < lCount)
+ {
+ val = (int)(((byteMain & 0x07) << 18) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 6) |
+ (pBuffer[lIndex + 3] & 0x3F));
+ }
WriteUtf16_WCHAR(val, pUnicodeString);
lIndex += 4;
@@ -282,11 +329,15 @@ namespace NSFile
else if (0x00 == (byteMain & 0x04))
{
// 5 byte
- int val = (int)(((byteMain & 0x03) << 24) |
- ((pBuffer[lIndex + 1] & 0x3F) << 18) |
- ((pBuffer[lIndex + 2] & 0x3F) << 12) |
- ((pBuffer[lIndex + 3] & 0x3F) << 6) |
- (pBuffer[lIndex + 4] & 0x3F));
+ int val = 0;
+ if ((lIndex + 4) < lCount)
+ {
+ val = (int)(((byteMain & 0x03) << 24) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 18) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 3] & 0x3F) << 6) |
+ (pBuffer[lIndex + 4] & 0x3F));
+ }
WriteUtf16_WCHAR(val, pUnicodeString);
lIndex += 5;
@@ -294,12 +345,16 @@ namespace NSFile
else
{
// 6 byte
- int val = (int)(((byteMain & 0x01) << 30) |
- ((pBuffer[lIndex + 1] & 0x3F) << 24) |
- ((pBuffer[lIndex + 2] & 0x3F) << 18) |
- ((pBuffer[lIndex + 3] & 0x3F) << 12) |
- ((pBuffer[lIndex + 4] & 0x3F) << 6) |
- (pBuffer[lIndex + 5] & 0x3F));
+ int val = 0;
+ if ((lIndex + 5) < lCount)
+ {
+ val = (int)(((byteMain & 0x01) << 30) |
+ ((pBuffer[lIndex + 1] & 0x3F) << 24) |
+ ((pBuffer[lIndex + 2] & 0x3F) << 18) |
+ ((pBuffer[lIndex + 3] & 0x3F) << 12) |
+ ((pBuffer[lIndex + 4] & 0x3F) << 6) |
+ (pBuffer[lIndex + 5] & 0x3F));
+ }
WriteUtf16_WCHAR(val, pUnicodeString);
lIndex += 5;
diff --git a/DesktopEditor/cximage/CxImage/xfile.h b/DesktopEditor/cximage/CxImage/xfile.h
index 78482cce45..1e84f1c156 100644
--- a/DesktopEditor/cximage/CxImage/xfile.h
+++ b/DesktopEditor/cximage/CxImage/xfile.h
@@ -49,11 +49,11 @@
class DLL_EXP CxFile
{
public:
- CxFile(void) { };
- virtual ~CxFile() { };
+ CxFile(void) { }
+ virtual ~CxFile() { }
virtual bool Close() = 0;
- virtual size_t Read(void *buffer, size_t size, size_t count) = 0;
+ virtual size_t Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL) = 0;
virtual size_t Write(const void *buffer, size_t size, size_t count) = 0;
virtual bool Seek(int32_t offset, int32_t origin) = 0;
virtual int32_t Tell() = 0;
@@ -72,4 +72,27 @@ public:
virtual int32_t Scanf(const char *format, void* output) = 0;
};
+static void clamp_buffer(void*& buffer, size_t& size, void* limit_start, void* limit_end)
+{
+ if (NULL == limit_start || NULL == limit_end)
+ return;
+
+ uint8_t* _buffer = (uint8_t*)buffer;
+ uint8_t* _limit_start = (uint8_t*)limit_start;
+ uint8_t* _limit_end = (uint8_t*)limit_end;
+
+ if (_buffer > _limit_end)
+ {
+ buffer = limit_end;
+ size = 0;
+ return;
+ }
+
+ if (_buffer < _limit_start)
+ _buffer = _limit_start;
+
+ if ((_buffer + size) > _limit_end)
+ size = (_limit_end - _buffer);
+}
+
#endif //__xfile_h
diff --git a/DesktopEditor/cximage/CxImage/ximabmp.cpp b/DesktopEditor/cximage/CxImage/ximabmp.cpp
index d03d97d78e..cd8b2743e7 100644
--- a/DesktopEditor/cximage/CxImage/ximabmp.cpp
+++ b/DesktopEditor/cximage/CxImage/ximabmp.cpp
@@ -133,7 +133,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
if (bIsOldBmp){
// convert a old color table (3 byte entries) to a new
// color table (4 byte entries)
- hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
+ hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1,GetDIB(),GetDIBLimit());
for (int32_t i=DibNumColors(&head)-1; i>=0; i--){
pRgb[i].rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
pRgb[i].rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
@@ -141,7 +141,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
pRgb[i].rgbReserved = (uint8_t)0;
}
} else {
- hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
+ hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1,GetDIB(),GetDIBLimit());
//force rgbReserved=0, to avoid problems with some WinXp bitmaps
for (uint32_t i=0; i
Read(buff32, imagesize,1); // read in the pixels
+ hFile->Read(buff32, imagesize,1,GetDIB(),GetDIBLimit()); // read in the pixels
#if CXIMAGE_SUPPORT_ALPHA
if (dwCompression == BI_RGB){
@@ -195,7 +195,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
case 24 :
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
if (dwCompression == BI_RGB){
- hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
+ hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
} else cx_throw("unknown compression");
break;
case 16 :
@@ -210,7 +210,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
// bf.bfOffBits required after the bitfield mask
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
// read in the pixels
- hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
+ hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1,GetDIB(),GetDIBLimit());
// transform into RGB
Bitfield2RGB(info.pImage,bfmask[0],bfmask[1],bfmask[2],16);
break;
@@ -229,7 +229,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
}
switch (dwCompression) {
case BI_RGB :
- hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
+ hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
break;
case BI_RLE4 :
{
@@ -355,7 +355,7 @@ bool CxImageBMP::Decode(CxFile * hFile)
break;
}
default :
- hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1);
+ hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1,GetDIB(),GetDIBLimit());
// align run length to even number of bytes
if ((status_byte & 1) == 1)
hFile->Read(&second_byte, sizeof(uint8_t), 1);
diff --git a/DesktopEditor/cximage/CxImage/ximaexif.cpp b/DesktopEditor/cximage/CxImage/ximaexif.cpp
index e93ec53eaa..d5cd21cc3d 100644
--- a/DesktopEditor/cximage/CxImage/ximaexif.cpp
+++ b/DesktopEditor/cximage/CxImage/ximaexif.cpp
@@ -165,7 +165,7 @@ bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
// Seen files from some 'U-lead' software with Vivitar scanner
// that uses marker 31 for non exif stuff. Thus make sure
// it says 'Exif' in the section before treating it as exif.
- if ((nReadMode & EXIF_READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){
+ if ((nReadMode & EXIF_READ_EXIF) && itemlen >= 6 && memcmp(Data+2, "Exif", 4) == 0){
m_exifinfo->IsExif = process_EXIF((uint8_t *)Data+2, itemlen-2);
}else{
// Discard this section.
@@ -187,6 +187,8 @@ bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
case M_SOF13:
case M_SOF14:
case M_SOF15:
+ if (itemlen < 8)
+ return false;
process_SOFn(Data, marker);
break;
default:
@@ -208,6 +210,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
/* If it's from a digicam, and it used flash, it says so. */
m_exifinfo->Comments[0] = '\0'; /* Initial value - null string */
+ if (length < 6)
+ return false;
+
ExifImageWidth = 0;
{ /* Check the EXIF header component */
@@ -218,6 +223,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
}
}
+ if (length < 8)
+ return false;
+
if (memcmp(CharBuf+6,"II",2) == 0){
MotorolaOrder = 0;
}else{
@@ -229,6 +237,9 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
}
}
+ if (length < 14)
+ return false;
+
/* Check the next two values for correctness. */
if (Get16u(CharBuf+8) != 0x2a){
strcpy(m_szLastError,"Invalid Exif start (1)");
@@ -246,6 +257,7 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
uint8_t * LastExifRefd = CharBuf;
+#if 0
/* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
return false;
@@ -255,6 +267,18 @@ bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
if (!ProcessExifDir(CharBuf+14+FirstOffset-8, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
return false;
}
+#else
+ CSafeReader reader(CharBuf, length);
+ /* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
+ if (!ProcessExifDir2(reader.Offset(14), reader.Offset(6), length-6, m_exifinfo, &LastExifRefd))
+ return false;
+
+ /* give a chance for a second directory */
+ if (FirstOffset > 8) {
+ if (!ProcessExifDir2(reader.Offset(14+FirstOffset-8), reader.Offset(6), length-6, m_exifinfo, &LastExifRefd))
+ return false;
+ }
+#endif
/* This is how far the interesting (non thumbnail) part of the exif went. */
// int32_t ExifSettingsLength = LastExifRefd - CharBuf;
@@ -692,6 +716,322 @@ bool CxImageJPG::CxExifInfo::ProcessExifDir(uint8_t * DirStart, uint8_t * Offset
return true;
}
+bool CxImageJPG::CxExifInfo::ProcessExifDir2(CSafeReader DirStart, CSafeReader OffsetBase, unsigned ExifLength,
+ EXIFINFO * const m_exifinfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel)
+{
+ int32_t de;
+ int32_t a;
+ int32_t NumDirEntries;
+ unsigned ThumbnailOffset = 0;
+ unsigned ThumbnailSize = 0;
+
+ if (NestingLevel > 4){
+ strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)");
+ return false;
+ }
+
+ NumDirEntries = DirStart.Check(2) ? Get16u(DirStart.GetData(0)) : 0;
+
+ if ((DirStart.GetData(2+NumDirEntries*12+2)) > (OffsetBase.GetData(ExifLength))){
+ strcpy(m_szLastError,"Illegally sized directory");
+ return false;
+ }
+
+ for (de=0;de= NUM_FORMATS) {
+ /* (-1) catches illegal zero case as unsigned underflows to positive large */
+ strcpy(m_szLastError,"Illegal format code in EXIF dir");
+ return false;
+ }
+
+ ByteCount = Components * BytesPerFormat[Format];
+
+ if (ByteCount > 4){
+ unsigned OffsetVal;
+ OffsetVal = DirEntry.Check(8, 4) ? Get32u(DirEntry.GetData(8)) : 0;
+ /* If its bigger than 4 bytes, the dir entry contains an offset.*/
+ if (OffsetVal+ByteCount > ExifLength){
+ /* Bogus pointer offset and / or bytecount value */
+ strcpy(m_szLastError,"Illegal pointer offset value in EXIF.");
+ return false;
+ }
+ ValuePtr = OffsetBase.Offset(OffsetVal);
+ }else{
+ /* 4 bytes or less and value is in the dir entry itself */
+ ValuePtr = DirEntry.Offset(8);
+ }
+
+ if (*LastExifRefdP < ValuePtr.GetData(ByteCount)){
+ /* Keep track of last byte in the exif header that was
+ actually referenced. That way, we know where the
+ discardable thumbnail data begins.
+ */
+ *LastExifRefdP = ValuePtr.GetData(ByteCount);
+ }
+
+ /* Extract useful components of tag */
+ switch(Tag){
+
+ case TAG_MAKE:
+ if (ValuePtr.Check(31)) strncpy(m_exifinfo->CameraMake, (char*)ValuePtr.GetData(0), 31);
+ break;
+
+ case TAG_MODEL:
+ if (ValuePtr.Check(39)) strncpy(m_exifinfo->CameraModel, (char*)ValuePtr.GetData(0), 39);
+ break;
+
+ case TAG_EXIF_VERSION:
+ if (ValuePtr.Check(4)) strncpy(m_exifinfo->Version,(char*)ValuePtr.GetData(0), 4);
+ break;
+
+ case TAG_DATETIME_ORIGINAL:
+ if (ValuePtr.Check(19)) strncpy(m_exifinfo->DateTime, (char*)ValuePtr.GetData(0), 19);
+ break;
+
+ case TAG_USERCOMMENT:
+ // Olympus has this padded with trailing spaces. Remove these first.
+ if (ValuePtr.Check(ByteCount))
+ {
+ for (a=ByteCount;;){
+ a--;
+ if (*((char*)ValuePtr.GetData(a)) == ' '){
+ *((char*)ValuePtr.GetData(a)) = '\0';
+ }else{
+ break;
+ }
+ if (a == 0) break;
+ }
+ }
+
+ /* Copy the comment */
+ if (ValuePtr.Check(5) && memcmp(ValuePtr.GetData(0), "ASCII",5) == 0){
+ for (a=5;a<10;a++){
+ char c;
+ c = *((char*)ValuePtr.GetData(a));
+ if (c != '\0' && c != ' '){
+ if (ValuePtr.Check(a, 199))
+ strncpy(m_exifinfo->Comments, (char*)ValuePtr.GetData(a), 199);
+ break;
+ }
+ }
+
+ }else{
+ if (ValuePtr.Check(199))
+ strncpy(m_exifinfo->Comments, (char*)ValuePtr.GetData(0), 199);
+ }
+ break;
+
+ case TAG_FNUMBER:
+ /* Simplest way of expressing aperture, so I trust it the most.
+ (overwrite previously computd value if there is one)
+ */
+ m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_APERTURE:
+ case TAG_MAXAPERTURE:
+ /* More relevant info always comes earlier, so only
+ use this field if we don't have appropriate aperture
+ information yet.
+ */
+ if (m_exifinfo->ApertureFNumber == 0){
+ m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat2(ValuePtr, Format)*log(2.0f)*0.5);
+ }
+ break;
+
+ case TAG_BRIGHTNESS:
+ m_exifinfo->Brightness = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_FOCALLENGTH:
+ /* Nice digital cameras actually save the focal length
+ as a function of how farthey are zoomed in.
+ */
+
+ m_exifinfo->FocalLength = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_SUBJECT_DISTANCE:
+ /* Inidcates the distacne the autofocus camera is focused to.
+ Tends to be less accurate as distance increases.
+ */
+ m_exifinfo->Distance = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_EXPOSURETIME:
+ /* Simplest way of expressing exposure time, so I
+ trust it most. (overwrite previously computd value
+ if there is one)
+ */
+ m_exifinfo->ExposureTime =
+ (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_SHUTTERSPEED:
+ /* More complicated way of expressing exposure time,
+ so only use this value if we don't already have it
+ from somewhere else.
+ */
+ if (m_exifinfo->ExposureTime == 0){
+ m_exifinfo->ExposureTime = (float)
+ (1/exp(ConvertAnyFormat2(ValuePtr, Format)*log(2.0f)));
+ }
+ break;
+
+ case TAG_FLASH:
+ if ((int32_t)ConvertAnyFormat2(ValuePtr, Format) & 7){
+ m_exifinfo->FlashUsed = 1;
+ }else{
+ m_exifinfo->FlashUsed = 0;
+ }
+ break;
+
+ case TAG_ORIENTATION:
+ m_exifinfo->Orientation = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ if (m_exifinfo->Orientation < 1 || m_exifinfo->Orientation > 8){
+ strcpy(m_szLastError,"Undefined rotation value");
+ m_exifinfo->Orientation = 0;
+ }
+ break;
+
+ case TAG_EXIF_IMAGELENGTH:
+ case TAG_EXIF_IMAGEWIDTH:
+ /* Use largest of height and width to deal with images
+ that have been rotated to portrait format.
+ */
+ a = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ if (ExifImageWidth < a) ExifImageWidth = a;
+ break;
+
+ case TAG_FOCALPLANEXRES:
+ m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_FOCALPLANEYRES:
+ m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_RESOLUTIONUNIT:
+ switch((int32_t)ConvertAnyFormat2(ValuePtr, Format)){
+ case 1: m_exifinfo->ResolutionUnit = 1.0f; break; /* 1 inch */
+ case 2: m_exifinfo->ResolutionUnit = 1.0f; break;
+ case 3: m_exifinfo->ResolutionUnit = 0.3937007874f; break; /* 1 centimeter*/
+ case 4: m_exifinfo->ResolutionUnit = 0.03937007874f; break; /* 1 millimeter*/
+ case 5: m_exifinfo->ResolutionUnit = 0.00003937007874f; /* 1 micrometer*/
+ }
+ break;
+
+ case TAG_FOCALPLANEUNITS:
+ switch((int32_t)ConvertAnyFormat2(ValuePtr, Format)){
+ case 1: m_exifinfo->FocalplaneUnits = 1.0f; break; /* 1 inch */
+ case 2: m_exifinfo->FocalplaneUnits = 1.0f; break;
+ case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break; /* 1 centimeter*/
+ case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break; /* 1 millimeter*/
+ case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f; /* 1 micrometer*/
+ }
+ break;
+
+ // Remaining cases contributed by: Volker C. Schoech
+
+ case TAG_EXPOSURE_BIAS:
+ m_exifinfo->ExposureBias = (float) ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_WHITEBALANCE:
+ m_exifinfo->Whitebalance = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_METERING_MODE:
+ m_exifinfo->MeteringMode = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_EXPOSURE_PROGRAM:
+ m_exifinfo->ExposureProgram = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_ISO_EQUIVALENT:
+ m_exifinfo->ISOequivalent = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
+ break;
+
+ case TAG_COMPRESSION_LEVEL:
+ m_exifinfo->CompressionLevel = (int32_t)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_XRESOLUTION:
+ m_exifinfo->Xresolution = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+ case TAG_YRESOLUTION:
+ m_exifinfo->Yresolution = (float)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_THUMBNAIL_OFFSET:
+ ThumbnailOffset = (unsigned)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ case TAG_THUMBNAIL_LENGTH:
+ ThumbnailSize = (unsigned)ConvertAnyFormat2(ValuePtr, Format);
+ break;
+
+ }
+
+ if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
+ unsigned Offset = ValuePtr.Check(4) ? Get32u(ValuePtr.GetData(0)) : 0;
+ if (Offset>8){
+ if (!OffsetBase.Check(Offset))
+ {
+ strcpy(m_szLastError,"Illegal subdirectory link");
+ return false;
+ }
+ ProcessExifDir2(OffsetBase.Offset(Offset), OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
+ }
+ continue;
+ }
+ }
+
+
+ {
+ /* In addition to linking to subdirectories via exif tags,
+ there's also a potential link to another directory at the end
+ of each directory. This has got to be the result of a
+ committee!
+ */
+ unsigned Offset;
+ Offset = DirStart.Check(2+12*NumDirEntries, 2) ? Get16u(DirStart.GetData(2+12*NumDirEntries)) : 0;
+ if (Offset){
+ if (!OffsetBase.Check(Offset))
+ {
+ strcpy(m_szLastError,"Illegal subdirectory link");
+ return false;
+ }
+ ProcessExifDir2(OffsetBase.Offset(Offset), OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
+ }
+ }
+
+
+ if (ThumbnailSize && ThumbnailOffset){
+ if (ThumbnailSize + ThumbnailOffset <= ExifLength){
+ /* The thumbnail pointer appears to be valid. Store it. */
+ m_exifinfo->ThumbnailPointer = OffsetBase.GetData(ThumbnailOffset);
+ m_exifinfo->ThumbnailSize = ThumbnailSize;
+ }
+ }
+
+ return true;
+}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Evaluate number, be it int32_t, rational, or float from directory.
@@ -732,6 +1072,58 @@ double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int32_t Format)
}
return Value;
}
+double CxImageJPG::CxExifInfo::ConvertAnyFormat2(CSafeReader& reader, int32_t Format)
+{
+ double Value;
+ Value = 0;
+
+ switch(Format){
+ case FMT_SBYTE:
+ case FMT_BYTE: if (!reader.Check(1)) {return Value;} break;
+ case FMT_USHORT:
+ case FMT_SSHORT: if (!reader.Check(2)) {return Value;} break;
+ case FMT_ULONG:
+ case FMT_SLONG: if (!reader.Check(4)) {return Value;} break;
+ case FMT_URATIONAL:
+ case FMT_SRATIONAL: if (!reader.Check(8)) {return Value;} break;
+ case FMT_SINGLE: if (!reader.Check(sizeof(float))) {return Value;} break;
+ case FMT_DOUBLE: if (!reader.Check(sizeof(double))) {return Value;} break;
+ default:
+ break;
+ }
+
+ void * ValuePtr = (void*)reader.GetData(0);
+ switch(Format){
+ case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
+ case FMT_BYTE: Value = *(uint8_t *)ValuePtr; break;
+
+ case FMT_USHORT: Value = Get16u(ValuePtr); break;
+ case FMT_ULONG: Value = Get32u(ValuePtr); break;
+
+ case FMT_URATIONAL:
+ case FMT_SRATIONAL:
+ {
+ int32_t Num,Den;
+ Num = Get32s(ValuePtr);
+ Den = Get32s(4+(char *)ValuePtr);
+ if (Den == 0){
+ Value = 0;
+ }else{
+ Value = (double)Num/Den;
+ }
+ break;
+ }
+
+ case FMT_SSHORT: Value = (int16_t)Get16u(ValuePtr); break;
+ case FMT_SLONG: Value = Get32s(ValuePtr); break;
+
+ /* Not sure if this is correct (never seen float used in Exif format)
+ */
+ case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break;
+ case FMT_DOUBLE: Value = *(double *)ValuePtr; break;
+ }
+ return Value;
+}
////////////////////////////////////////////////////////////////////////////////
void CxImageJPG::CxExifInfo::process_COM (const uint8_t * Data, int32_t length)
{
@@ -747,7 +1139,7 @@ void CxImageJPG::CxExifInfo::process_COM (const uint8_t * Data, int32_t length)
for (a=2;a 0xFFFFFFFF)
+ return 0xFFFFFFFF;
+ return (uint32_t)size64;
}
////////////////////////////////////////////////////////////////////////////////
/**
@@ -324,13 +328,14 @@ bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
pDib = from.pDib;
+ pDibLimit = from.pDibLimit;
pSelection = from.pSelection;
pAlpha = from.pAlpha;
ppLayers = from.ppLayers;
memset(&from.head,0,sizeof(BITMAPINFOHEADER));
memset(&from.info,0,sizeof(CXIMAGEINFO));
- from.pDib = from.pSelection = from.pAlpha = NULL;
+ from.pDib = from.pDibLimit = from.pSelection = from.pAlpha = NULL;
from.ppLayers = NULL;
if (bTransferFrames){
@@ -352,6 +357,7 @@ void CxImage::Ghost(const CxImage *from)
memcpy(&head,&from->head,sizeof(BITMAPINFOHEADER));
memcpy(&info,&from->info,sizeof(CXIMAGEINFO));
pDib = from->pDib;
+ pDibLimit = from->pDibLimit;
pSelection = from->pSelection;
pAlpha = from->pAlpha;
ppLayers = from->ppLayers;
diff --git a/DesktopEditor/cximage/CxImage/ximage.h b/DesktopEditor/cximage/CxImage/ximage.h
index 61f8f4aa53..599ecf1af9 100644
--- a/DesktopEditor/cximage/CxImage/ximage.h
+++ b/DesktopEditor/cximage/CxImage/ximage.h
@@ -289,10 +289,11 @@ public:
//@}
/** \addtogroup Attributes */ //@{
- int32_t GetSize();
+ uint32_t GetSize();
uint8_t* GetBits(uint32_t row = 0);
uint8_t GetColorType();
void* GetDIB() const;
+ void* GetDIBLimit() const;
uint32_t GetHeight() const;
uint32_t GetWidth() const;
uint32_t GetEffWidth() const;
@@ -796,6 +797,8 @@ protected:
void bihtoh(BITMAPINFOHEADER* bih);
void* pDib; //contains the header, the palette, the pixels
+ void* pDibLimit;
+
BITMAPINFOHEADER head; //standard header
CXIMAGEINFO info; //extended information
uint8_t* pSelection; //selected region
diff --git a/DesktopEditor/cximage/CxImage/ximaico.cpp b/DesktopEditor/cximage/CxImage/ximaico.cpp
index 4fed96cdbc..b8729e0d60 100644
--- a/DesktopEditor/cximage/CxImage/ximaico.cpp
+++ b/DesktopEditor/cximage/CxImage/ximaico.cpp
@@ -95,9 +95,15 @@ bool CxImageICO::Decode(CxFile *hFile)
// read the palette
RGBQUAD pal[256];
if (bih.biClrUsed)
- hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
+ {
+ uint32_t _count = bih.biClrUsed; if (_count > 256) _count = 256;
+ hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
+ }
else
- hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
+ {
+ uint32_t _count = head.biClrUsed; if (_count > 256) _count = 256;
+ hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
+ }
SetPalette(pal,head.biClrUsed); //palette assign
diff --git a/DesktopEditor/cximage/CxImage/ximainfo.cpp b/DesktopEditor/cximage/CxImage/ximainfo.cpp
index e3a278c0c0..9ebd904e89 100644
--- a/DesktopEditor/cximage/CxImage/ximainfo.cpp
+++ b/DesktopEditor/cximage/CxImage/ximainfo.cpp
@@ -181,6 +181,10 @@ void* CxImage::GetDIB() const
{
return pDib;
}
+void* CxImage::GetDIBLimit() const
+{
+ return pDibLimit;
+}
////////////////////////////////////////////////////////////////////////////////
uint32_t CxImage::GetHeight() const
{
diff --git a/DesktopEditor/cximage/CxImage/ximajpg.h b/DesktopEditor/cximage/CxImage/ximajpg.h
index 4cb2484a8b..418dc6ca55 100644
--- a/DesktopEditor/cximage/CxImage/ximajpg.h
+++ b/DesktopEditor/cximage/CxImage/ximajpg.h
@@ -101,6 +101,55 @@ typedef struct tag_Section_t{
unsigned Size;
} Section_t;
+public:
+ class CSafeReader
+ {
+ private:
+ uint8_t* data;
+ unsigned int len;
+
+ public:
+ CSafeReader(uint8_t* _data = NULL, unsigned int _len = 0)
+ {
+ data = _data;
+ len = _len;
+ }
+ CSafeReader(const CSafeReader& src)
+ {
+ data = src.data;
+ len = src.len;
+ }
+ CSafeReader& operator=(const CSafeReader& src)
+ {
+ data = src.data;
+ len = src.len;
+ return *this;
+ }
+ CSafeReader Offset(unsigned int offset)
+ {
+ if (offset > len)
+ offset = len;
+ CSafeReader reader(data, len);
+ reader.data += offset;
+ reader.len -= offset;
+ return reader;
+ }
+ bool Check(unsigned int size)
+ {
+ if (len >= size)
+ return true;
+ return false;
+ }
+ bool Check(unsigned int offset, unsigned int size)
+ {
+ return Check(offset + size);
+ }
+ uint8_t* GetData(unsigned int offset)
+ {
+ return data + offset;
+ }
+ };
+
public:
EXIFINFO* m_exifinfo;
char m_szLastError[256];
@@ -118,9 +167,12 @@ protected:
int32_t Get32s(void * Long);
uint32_t Get32u(void * Long);
double ConvertAnyFormat(void * ValuePtr, int32_t Format);
+ double ConvertAnyFormat2(CSafeReader& reader, int32_t Format);
void* FindSection(int32_t SectionType);
bool ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0);
+ bool ProcessExifDir2(CSafeReader DirStart, CSafeReader OffsetBase, unsigned ExifLength,
+ EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0);
int32_t ExifImageWidth;
int32_t MotorolaOrder;
Section_t Sections[MAX_SECTIONS];
diff --git a/DesktopEditor/cximage/CxImage/ximapcx.cpp b/DesktopEditor/cximage/CxImage/ximapcx.cpp
index 0a96c33ab4..b233557e02 100644
--- a/DesktopEditor/cximage/CxImage/ximapcx.cpp
+++ b/DesktopEditor/cximage/CxImage/ximapcx.cpp
@@ -50,6 +50,9 @@ bool CxImagePCX::Decode(CxFile *hFile)
info.xDPI = pcxHeader.Hres;
info.yDPI = pcxHeader.Vres;
+ if (Width <= 0 || Height <= 0)
+ cx_throw("Error: Not a PCX file");
+
if (info.nEscape == -1){
head.biWidth = Width;
head.biHeight= Height;
@@ -76,7 +79,11 @@ bool CxImagePCX::Decode(CxFile *hFile)
//Read the image and check if it's ok
nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
+ uint32_t pcximage_size = nbytes;
lpHead1 = pcximage = (uint8_t*)malloc(nbytes);
+ if (!pcximage)
+ cx_throw("Cancelled");
+
while (nbytes > 0){
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted PCX");
@@ -119,6 +126,9 @@ bool CxImagePCX::Decode(CxFile *hFile)
for (uint32_t idx=0; idx127) a-=256;
if (b>127) b-=256;
// lab to xyz
diff --git a/DesktopEditor/cximage/CxImage/xiofile.h b/DesktopEditor/cximage/CxImage/xiofile.h
index 8ab5f1bfaf..e6b8334c08 100644
--- a/DesktopEditor/cximage/CxImage/xiofile.h
+++ b/DesktopEditor/cximage/CxImage/xiofile.h
@@ -59,9 +59,10 @@ public:
return (bool)(iErr==0);
}
//////////////////////////////////////////////////////////
- virtual size_t Read(void *buffer, size_t size, size_t count)
+ virtual size_t Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL)
{
if (!m_fp) return 0;
+ clamp_buffer(buffer, size, limit_start, limit_end);
return fread(buffer, size, count, m_fp);
}
//////////////////////////////////////////////////////////
diff --git a/DesktopEditor/cximage/CxImage/xmemfile.cpp b/DesktopEditor/cximage/CxImage/xmemfile.cpp
index 42dfadef35..180184db22 100644
--- a/DesktopEditor/cximage/CxImage/xmemfile.cpp
+++ b/DesktopEditor/cximage/CxImage/xmemfile.cpp
@@ -45,7 +45,7 @@ uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
return m_pBuffer;
}
//////////////////////////////////////////////////////////
-size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
+size_t CxMemFile::Read(void *buffer, size_t size, size_t count, void* limit_start, void* limit_end)
{
if (buffer==NULL) return 0;
@@ -53,7 +53,7 @@ size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
if (m_Position >= (int32_t)m_Size){
m_bEOF = true;
return 0;
- }
+ }
int32_t nCount = (int32_t)(count*size);
if (nCount == 0) return 0;
diff --git a/DesktopEditor/cximage/CxImage/xmemfile.h b/DesktopEditor/cximage/CxImage/xmemfile.h
index 71e00eb069..385d16b30e 100644
--- a/DesktopEditor/cximage/CxImage/xmemfile.h
+++ b/DesktopEditor/cximage/CxImage/xmemfile.h
@@ -14,7 +14,7 @@ public:
uint8_t* GetBuffer(bool bDetachBuffer = true);
virtual bool Close();
- virtual size_t Read(void *buffer, size_t size, size_t count);
+ virtual size_t Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL);
virtual size_t Write(const void *buffer, size_t size, size_t count);
virtual bool Seek(int32_t offset, int32_t origin);
virtual int32_t Tell();
diff --git a/DesktopEditor/cximage/jasper/jpc/jpc_dec.c b/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
index fa72a0e82c..df986bcc66 100644
--- a/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
+++ b/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
@@ -2171,7 +2171,12 @@ int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
int inspt;
int i;
- for (i = 0; i < tab->numents; ++i) {
+ // check on MAX_INT
+ int correct_num_ents = tab->numents;
+ if (correct_num_ents > 0x7FFFFFFE)
+ correct_num_ents = 0x7FFFFFFE;
+
+ for (i = 0; i < correct_num_ents; ++i) {
if (tab->ents[i]->ind > ent->ind) {
break;
}
diff --git a/DesktopEditor/cximage/raw/libdcr.c b/DesktopEditor/cximage/raw/libdcr.c
index e671e47c66..73f4ab3758 100644
--- a/DesktopEditor/cximage/raw/libdcr.c
+++ b/DesktopEditor/cximage/raw/libdcr.c
@@ -3518,20 +3518,21 @@ void DCR_CLASS dcr_cam_xyz_coeff (DCRAW* p, double cam_xyz[4][3])
{
double cam_rgb[4][3], inverse[4][3], num;
int i, j, k;
-
- for (i=0; i < p->colors; i++) /* Multiply out XYZ colorspace */
+ int max_colors = p->colors;
+ if (max_colors > 4) max_colors = 4;
+ for (i=0; i < max_colors; i++) /* Multiply out XYZ colorspace */
for (j=0; j < 3; j++)
for (cam_rgb[i][j] = k=0; k < 3; k++)
cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j];
- for (i=0; i < p->colors; i++) { /* Normalize cam_rgb so that */
+ for (i=0; i < max_colors; i++) { /* Normalize cam_rgb so that */
for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
num += cam_rgb[i][j];
for (j=0; j < 3; j++)
cam_rgb[i][j] /= num;
p->pre_mul[i] = 1 / (float)num;
}
- dcr_pseudoinverse (cam_rgb, inverse, p->colors);
+ dcr_pseudoinverse (cam_rgb, inverse, max_colors);
for (p->raw_color = i=0; i < 3; i++)
for (j=0; j < p->colors; j++)
p->rgb_cam[i][j] = (float)inverse[j][i];
@@ -5391,9 +5392,12 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
p->tiff_ifd[raw].phint == 1) p->is_raw = 0;
if (p->tiff_bps == 8 && p->tiff_samples == 4) p->is_raw = 0;
for (i=0; i < (int)p->tiff_nifds; i++)
+ {
+ int sqr_1 = SQR(p->tiff_ifd[i].bps+1); if (sqr_1 == 0) sqr_1 = 1;
+ int sqr_2 = SQR(p->thumb_misc+1); if (sqr_2 == 0) sqr_2 = 1;
if (i != raw && p->tiff_ifd[i].samples == max_samp &&
- p->tiff_ifd[i].width * p->tiff_ifd[i].height / SQR(p->tiff_ifd[i].bps+1) >
- (int)(p->thumb_width * p->thumb_height / SQR(p->thumb_misc+1))) {
+ p->tiff_ifd[i].width * p->tiff_ifd[i].height / sqr_1 >
+ (int)(p->thumb_width * p->thumb_height / sqr_2)) {
p->thumb_width = p->tiff_ifd[i].width;
p->thumb_height = p->tiff_ifd[i].height;
p->thumb_offset = p->tiff_ifd[i].offset;
@@ -5401,6 +5405,7 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
p->thumb_misc = p->tiff_ifd[i].bps;
thm = i;
}
+ }
if (thm >= 0) {
p->thumb_misc |= p->tiff_ifd[thm].samples << 5;
switch (p->tiff_ifd[thm].comp) {
@@ -5845,10 +5850,16 @@ void DCR_CLASS dcr_parse_riff(DCRAW* p)
{ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
struct tm t;
+ if (dcr_feof(p->obj_))
+ {
+ fprintf (stderr,_("Unexpected end of file\n"));
+ return;
+ }
+
p->order = 0x4949;
dcr_fread(p->obj_, tag, 4, 1);
size = dcr_get4(p);
- end = dcr_ftell(p->obj_) + size;
+ end = dcr_ftell(p->obj_) + size;
if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
dcr_get4(p);
while (dcr_ftell(p->obj_)+7 < (long)end)
diff --git a/DesktopEditor/cximage/tiff/tif_dirread.c b/DesktopEditor/cximage/tiff/tif_dirread.c
index 907b53188c..51d20a3b96 100644
--- a/DesktopEditor/cximage/tiff/tif_dirread.c
+++ b/DesktopEditor/cximage/tiff/tif_dirread.c
@@ -205,7 +205,7 @@ TIFFReadDirectory(TIFF* tif)
&& fix < tif->tif_nfields) {
if (fip->field_type == TIFF_ANY) /* wildcard */
break;
- fip = tif->tif_fieldinfo[++fix];
+ ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
if (fix >= tif->tif_nfields ||
fip->field_tag != dp->tdir_tag) {
TIFFWarningExt(tif->tif_clientdata, module,
@@ -333,7 +333,7 @@ TIFFReadDirectory(TIFF* tif)
&& fix < tif->tif_nfields) {
if (fip->field_type == TIFF_ANY) /* wildcard */
break;
- fip = tif->tif_fieldinfo[++fix];
+ ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
if (fix >= tif->tif_nfields ||
fip->field_tag != dp->tdir_tag) {
TIFFWarningExt(tif->tif_clientdata, module,
@@ -887,7 +887,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
&& fix < tif->tif_nfields) {
if (fip->field_type == TIFF_ANY) /* wildcard */
break;
- fip = tif->tif_fieldinfo[++fix];
+ ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[fix];
if (fix >= tif->tif_nfields ||
fip->field_tag != dp->tdir_tag) {
TIFFWarningExt(tif->tif_clientdata, module,
diff --git a/DesktopEditor/cximage/tiff/tif_ojpeg.c b/DesktopEditor/cximage/tiff/tif_ojpeg.c
index 793de83616..dea897484f 100644
--- a/DesktopEditor/cximage/tiff/tif_ojpeg.c
+++ b/DesktopEditor/cximage/tiff/tif_ojpeg.c
@@ -1920,7 +1920,9 @@ OJPEGReadBufferFill(OJPEGState* sp)
sp->in_buffer_file_pos=0;
else
{
- sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+ sp->in_buffer_file_togo=0;
+ if (sp->tif->tif_dir.td_stripbytecount)
+ sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
if (sp->in_buffer_file_togo==0)
sp->in_buffer_file_pos=0;
else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileBase.h b/DesktopEditor/fontengine/fontconverter/FontFileBase.h
index f0e4299dbd..6089793d0c 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileBase.h
+++ b/DesktopEditor/fontengine/fontconverter/FontFileBase.h
@@ -61,9 +61,9 @@ namespace NSFontConverter
CFontFileBase(char *sFile, int nLen, bool bFreeFileData)
{
m_sFileData = m_sFile = (unsigned char *)sFile;
- m_nLen = nLen;
- m_bFreeFileData = bFreeFileData;
+ m_nLen = (nLen > 0) ? 0 : (unsigned int)nLen;
m_nPos = 0;
+ m_bFreeFileData = bFreeFileData;
}
void Reset()
@@ -94,11 +94,11 @@ namespace NSFontConverter
// S = signed / U = unsigned
// 8/16/32/Var = word length, in bytes
// BE = big endian
- int GetS8 (int nPos, bool *pbSuccess)
+ int GetS8 (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos >= m_nLen )
+ if ( nPos >= m_nLen )
{
*pbSuccess = false;
return 0;
@@ -109,10 +109,10 @@ namespace NSFontConverter
return nRes;
}
- int GetU8 (int nPos, bool *pbSuccess)
+ int GetU8 (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos >= m_nLen )
+ if ( nPos >= m_nLen )
{
*pbSuccess = false;
return 0;
@@ -120,11 +120,11 @@ namespace NSFontConverter
return m_sFile[ nPos ];
}
- int GetS16BE (int nPos, bool *pbSuccess)
+ int GetS16BE (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + 1 >= m_nLen )
+ if ( m_nLen < 2 || nPos > (m_nLen - 2) )
{
*pbSuccess = false;
return 0;
@@ -136,11 +136,11 @@ namespace NSFontConverter
return nRes;
}
- int GetU16BE (int nPos, bool *pbSuccess)
+ int GetU16BE (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + 1 >= m_nLen)
+ if ( m_nLen < 2 || nPos > (m_nLen - 2) )
{
*pbSuccess = false;
return 0;
@@ -150,11 +150,11 @@ namespace NSFontConverter
return nRes;
}
- int GetS32BE (int nPos, bool *pbSuccess)
+ int GetS32BE (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + 3 >= m_nLen )
+ if ( m_nLen < 4 || nPos > (m_nLen - 4) )
{
*pbSuccess = false;
return 0;
@@ -169,11 +169,11 @@ namespace NSFontConverter
return nRes;
}
- unsigned int GetU32BE (int nPos, bool *pbSuccess)
+ unsigned int GetU32BE (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + 3 >= m_nLen )
+ if ( m_nLen < 4 || nPos > (m_nLen - 4) )
{
*pbSuccess = false;
return 0;
@@ -184,11 +184,11 @@ namespace NSFontConverter
nRes = (nRes << 8) + m_sFile[nPos + 3];
return nRes;
}
- unsigned int GetU32LE (int nPos, bool *pbSuccess)
+ unsigned int GetU32LE (const unsigned int& nPos, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + 3 >= m_nLen )
+ if ( m_nLen < 4 || nPos > (m_nLen - 4) )
{
*pbSuccess = false;
return 0;
@@ -199,11 +199,11 @@ namespace NSFontConverter
nRes = (nRes << 8) + m_sFile[nPos + 0];
return nRes;
}
- unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess)
+ unsigned int GetUVarBE(const unsigned int& nPos, const unsigned int& nSize, bool *pbSuccess)
{
//*pbSuccess = true;
- if ( nPos < 0 || nPos + nSize > m_nLen )
+ if ( m_nLen < nSize || nPos > (m_nLen - nSize) )
{
*pbSuccess = false;
return 0;
@@ -215,9 +215,9 @@ namespace NSFontConverter
return nRes;
}
- bool CheckRegion(int nPos, int nSize)
+ bool CheckRegion(const unsigned int& nPos, const unsigned int& nSize)
{
- return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen);
+ return (m_nLen >= nSize && nPos <= (m_nLen - nSize));
}
int ReadS8 (bool *pbSuccess)
{
@@ -239,10 +239,15 @@ namespace NSFontConverter
m_nPos += 4;
return unResult;
}
- int Read(void* pDestBuffer, int nSize)
+ int Read(void* pDestBuffer, unsigned int nSize)
{
- if ( m_nPos + nSize >= m_nLen )
- nSize = m_nLen - m_nPos - 1;
+ if (m_nPos >= m_nLen)
+ nSize = 0;
+ else if (nSize > (m_nLen - m_nPos))
+ nSize = m_nLen - m_nPos;
+
+ if (0 == nSize)
+ return nSize;
memcpy( pDestBuffer, (m_sFile + m_nPos), nSize );
m_nPos += nSize;
@@ -254,10 +259,9 @@ namespace NSFontConverter
unsigned char *m_sFileData;
unsigned char *m_sFile;
- int m_nLen;
+ unsigned int m_nLen;
+ unsigned int m_nPos;
bool m_bFreeFileData;
- int m_nPos;
-
};
}
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp b/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
index fb9d062a62..b2df678b14 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
+++ b/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
@@ -397,6 +397,7 @@ namespace NSFontConverter
char nChar = *pTemp;
*pTemp = '\0';
nCode = atoi( pCur );
+ if (nCode < 0) nCode = 0;
*pTemp = nChar;
if ( nCode == 8 && *pTemp == '#')
{
@@ -612,7 +613,7 @@ namespace NSFontConverter
sToken.clear();
sGlyph.clear();
- while ( ( nChar = sEexec[++nIndex] ) != ' ' )
+ while ( nIndex < nEexecLen && ( nChar = sEexec[++nIndex] ) != ' ' )
sGlyph.push_back( (wchar_t)nChar );
}
}
@@ -632,13 +633,16 @@ namespace NSFontConverter
// (пробел, таб, перенос каретки или перенос строки).
unsigned char *sCur = (unsigned char*)(*ppEexecBuffer);
while( sCur < (unsigned char*)(*ppEexecBuffer) + nLen && ( ' ' == *sCur || '\t' == *sCur || '\r' == *sCur || '\n' == *sCur ) )
+ {
++sCur;
+ --nLen;
+ }
// Теперь нам надо определить в каком формате у нас данные: ASKII или бинарные данные.
// Если первые четыре байта являются шестнадцатиричными символами, значит, кодировка ASCII.
bool bASCII = false;
- if ( isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
+ if ( nLen > 3 && isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
bASCII = true;
if ( bASCII )
@@ -656,7 +660,7 @@ namespace NSFontConverter
int nChar = 0;
unsigned char *sBuffer = NULL;
- int nBufLen = 0;
+ unsigned int nBufLen = 0;
while ( nBlockType != PFB_DONE )
{
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileType1.h b/DesktopEditor/fontengine/fontconverter/FontFileType1.h
index 7f2aa71230..a126b91a15 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileType1.h
+++ b/DesktopEditor/fontengine/fontconverter/FontFileType1.h
@@ -259,6 +259,8 @@ namespace NSFontConverter
}
sBuffer[nBufPos++] = unChar;
+ if (nBufPos >= c_nNumLimit)
+ break;
}
if ( 0 != sBuffer[0] && nCount > 0 )
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileType1C.cpp b/DesktopEditor/fontengine/fontconverter/FontFileType1C.cpp
index 7165e48fdd..620aa073fc 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileType1C.cpp
+++ b/DesktopEditor/fontengine/fontconverter/FontFileType1C.cpp
@@ -2888,15 +2888,21 @@ namespace NSFontConverter
if (m_oTopDict.nCharsetOffset == 0)
{
m_pnCharset = c_arrnFontFileType1CISOAdobeCharset;
+ if (m_nGlyphsCount > 229)
+ m_nGlyphsCount = 229;
}
else if (m_oTopDict.nCharsetOffset == 1)
{
m_pnCharset = c_arrnFontFileType1CExpertCharset;
- }
+ if (m_nGlyphsCount > 166)
+ m_nGlyphsCount = 166;
+ }
else if (m_oTopDict.nCharsetOffset == 2)
{
m_pnCharset = c_arrnFontFileType1CExpertSubsetCharset;
- }
+ if (m_nGlyphsCount > 87)
+ m_nGlyphsCount = 87;
+ }
else
{
m_pnCharset = (unsigned short *)MemUtilsMallocArray( m_nGlyphsCount, sizeof(unsigned short));