CVE-2022-29776: Out-of-bounds Write (CWE-787)
value: Onlyoffice Document Server v6.0.0 and below and Core 6.1.0.26 and below were discovered to contain a stack overflow via the component DesktopEditor/common/File.cpp.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 9.8
Published: 2022-06-02T14:15Z
Repository: https://github.com/ONLYOFFICE/core
Language: C++
Files changed: DesktopEditor/common/File.cpp, DesktopEditor/cximage/CxImage/xfile.h, DesktopEditor/cximage/CxImage/ximabmp.cpp, DesktopEditor/cximage/CxImage/ximage.cpp, DesktopEditor/cximage/CxImage/ximage.h, DesktopEditor/cximage/CxImage/ximaico.cpp, DesktopEditor/cximage/CxImage/ximainfo.cpp, DesktopEditor/cximage/CxImage/ximapcx.cpp, DesktopEditor/cximage/CxImage/ximatif.cpp, DesktopEditor/cximage/CxImage/xiofile.h, DesktopEditor/cximage/CxImage/xmemfile.cpp, DesktopEditor/cximage/CxImage/xmemfile.h, DesktopEditor/cximage/jasper/jpc/jpc_dec.c, DesktopEditor/cximage/raw/libdcr.c, DesktopEditor/cximage/tiff/tif_dirread.c, DesktopEditor/cximage/tiff/tif_ojpeg.c, DesktopEditor/fontengine/fontconverter/FontFileType1.cpp, DesktopEditor/fontengine/fontconverter/FontFileType1.h
Commit date: 2020-10-13 20:11:21 +0300
Commit message: Fix 25 errors

Diff: diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp
index e0518f13d..eeebe8b30 100644
--- a/DesktopEditor/common/File.cpp
+++ b/DesktopEditor/common/File.cpp
@@ -157,64 +157,94 @@ namespace NSFile
                 ++lIndex;
             }
             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;
             }
         }
 
@@ -240,68 +270,93 @@ namespace NSFile
                 ++lIndex;
             }
             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;
             }
             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;
             }
             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;
             }
             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;
             }
             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 78482cce4..1e84f1c15 100644
--- a/DesktopEditor/cximage/CxImage/xfile.h
+++ b/DesktopEditor/cximage/CxImage/xfile.h
@@ -47,15 +47,15 @@
 #include "ximadef.h"
 
 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;
 	virtual int32_t	Size() = 0;
 	virtual bool	Flush() = 0;
@@ -70,6 +70,29 @@ public:
 	virtual int32_t	GetC() = 0;
 	virtual char *	GetS(char *string, int32_t n) = 0;
 	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 d03d97d78..cd8b2743e 100644
--- a/DesktopEditor/cximage/CxImage/ximabmp.cpp
+++ b/DesktopEditor/cximage/CxImage/ximabmp.cpp
@@ -131,19 +131,19 @@ bool CxImageBMP::Decode(CxFile * hFile)
     RGBQUAD *pRgb = GetPalette();
     if (pRgb){
         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;
                 pRgb[i].rgbGreen    = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
                 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<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
         }
     }
 
@@ -163,11 +163,11 @@ bool CxImageBMP::Decode(CxFile * hFile)
 			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
 			if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
 				int32_t imagesize=4*head.biHeight*head.biWidth;
 				uint8_t* buff32=(uint8_t*)malloc(imagesize);
 				if (buff32){
-					hFile->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){
 						AlphaCreate();
 						if (AlphaIsValid()){
@@ -193,11 +193,11 @@ bool CxImageBMP::Decode(CxFile * hFile)
 			} else cx_throw("unknown compression");
 			break;
 		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 :
 		{
 			uint32_t bfmask[3];
@@ -208,11 +208,11 @@ bool CxImageBMP::Decode(CxFile * hFile)
 				bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
 			}
 			// bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
 			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;
 		}
 		case 8 :
@@ -227,11 +227,11 @@ bool CxImageBMP::Decode(CxFile * hFile)
 			{
 				if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
 			}
 		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 :
 			{
 				uint8_t status_byte = 0;
 				uint8_t second_byte = 0;
@@ -353,11 +353,11 @@ bool CxImageBMP::Decode(CxFile * hFile)
 									bits     += delta_x;
 									scanline += delta_y;
 									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);												
 									bits += status_byte;													
 									break;								
diff --git a/DesktopEditor/cximage/CxImage/ximage.cpp b/DesktopEditor/cximage/CxImage/ximage.cpp
index 1e77cabff..6d2315d51 100644
--- a/DesktopEditor/cximage/CxImage/ximage.cpp
+++ b/DesktopEditor/cximage/CxImage/ximage.cpp
@@ -19,11 +19,11 @@
  * Initialize the internal structures
  */
 void CxImage::Startup(uint32_t imagetype)
 {
 	//init pointers
-	pDib = pSelection = pAlpha = NULL;
+    pDib = pDibLimit = pSelection = pAlpha = NULL;
 	ppLayers = ppFrames = NULL;
 	//init structures
 	memset(&head,0,sizeof(BITMAPINFOHEADER));
 	memset(&info,0,sizeof(CXIMAGEINFO));
 	//init default attributes
@@ -230,10 +230,11 @@ void* CxImage::Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32
 	pDib = malloc(GetSize()); // alloc memory block to store our bitmap
     if (!pDib){
 		strcpy(info.szLastError,"CxImage::Create can't allocate memory");
 		return NULL;
 	}
+    pDibLimit = (void*)((uint8_t*)pDib + GetSize());
 
 	//clear the palette
 	RGBQUAD* pal=GetPalette();
 	if (pal) memset(pal,0,GetPaletteSize());
 	//Destroy the existing selection
@@ -276,13 +277,16 @@ uint8_t* CxImage::GetBits(uint32_t row)
 }
 ////////////////////////////////////////////////////////////////////////////////
 /**
  * \return the size in bytes of the internal pDib object
  */
-int32_t CxImage::GetSize()
+uint32_t CxImage::GetSize()
 {
-	return head.biSize + head.biSizeImage + GetPaletteSize();
+    uint64_t size64 = head.biSize + head.biSizeImage + GetPaletteSize();
+    if (size64 > 0xFFFFFFFF)
+        return 0xFFFFFFFF;
+    return (uint32_t)size64;
 }
 ////////////////////////////////////////////////////////////////////////////////
 /**
  * Checks if the coordinates are inside the image
  * \return true if x and y are both inside the image
@@ -322,17 +326,18 @@ bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
 
 	memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER));
 	memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
 
 	pDib = from.pDib;
+    pDib = 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){
 		DestroyFrames();
 		ppFrames = from.ppFrames;
@@ -350,10 +355,11 @@ void CxImage::Ghost(const CxImage *from)
 {
 	if (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;
 		ppFrames = from->ppFrames;
 		info.pGhost=(CxImage *)from;
diff --git a/DesktopEditor/cximage/CxImage/ximage.h b/DesktopEditor/cximage/CxImage/ximage.h
index 61f8f4aa5..599ecf1af 100644
--- a/DesktopEditor/cximage/CxImage/ximage.h
+++ b/DesktopEditor/cximage/CxImage/ximage.h
@@ -287,14 +287,15 @@ public:
 	uint32_t DumpSize();
 
 //@}
 
 /** \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;
 	uint32_t	GetNumColors() const;
 	uint16_t	GetBpp() const;
@@ -794,10 +795,12 @@ protected:
 	int16_t m_ntohs(const int16_t word);
 	int32_t m_ntohl(const int32_t dword);
 	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
 	uint8_t*			pAlpha; //alpha channel
 	CxImage**			ppLayers; //generic layers
diff --git a/DesktopEditor/cximage/CxImage/ximaico.cpp b/DesktopEditor/cximage/CxImage/ximaico.cpp
index 4fed96cdb..c9f653a66 100644
--- a/DesktopEditor/cximage/CxImage/ximaico.cpp
+++ b/DesktopEditor/cximage/CxImage/ximaico.cpp
@@ -93,13 +93,19 @@ bool CxImageICO::Decode(CxFile *hFile)
 				Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO);	//image creation
 
 				// read the palette
 				RGBQUAD pal[256];
 				if (bih.biClrUsed)
-					hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
+                {
+                    DWORD _count = bih.biClrUsed; if (_count > 256) _count = 256;
+                    hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
+                }
 				else
-					hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
+                {
+                    DWORD _count = head.biClrUsed; if (_count > 256) _count = 256;
+                    hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
+                }
 
 				SetPalette(pal,head.biClrUsed);	//palette assign
 
 				//read the icon
 				if (c<=24){
diff --git a/DesktopEditor/cximage/CxImage/ximainfo.cpp b/DesktopEditor/cximage/CxImage/ximainfo.cpp
index e3a278c0c..9ebd904e8 100644
--- a/DesktopEditor/cximage/CxImage/ximainfo.cpp
+++ b/DesktopEditor/cximage/CxImage/ximainfo.cpp
@@ -179,10 +179,14 @@ bool CxImage::SetCodecOption(uint32_t opt, uint32_t imagetype)
  */
 void* CxImage::GetDIB() const
 {
 	return pDib;
 }
+void* CxImage::GetDIBLimit() const
+{
+    return pDibLimit;
+}
 ////////////////////////////////////////////////////////////////////////////////
 uint32_t CxImage::GetHeight() const
 {
 	return head.biHeight;
 }
diff --git a/DesktopEditor/cximage/CxImage/ximapcx.cpp b/DesktopEditor/cximage/CxImage/ximapcx.cpp
index 0a96c33ab..b233557e0 100644
--- a/DesktopEditor/cximage/CxImage/ximapcx.cpp
+++ b/DesktopEditor/cximage/CxImage/ximapcx.cpp
@@ -48,10 +48,13 @@ bool CxImagePCX::Decode(CxFile *hFile)
     Width = (pcxHeader.Xmax - pcxHeader.Xmin) + 1;
     Height = (pcxHeader.Ymax - pcxHeader.Ymin) + 1;
 	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;
 		info.dwType = CXIMAGE_FORMAT_PCX;
 		return true;
@@ -74,11 +77,15 @@ bool CxImagePCX::Decode(CxFile *hFile)
 
 	if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
 
 	//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");
 
 		hFile->Read(&c,1,1);
 		if ((c & 0XC0) != 0XC0){ // Repeated group
@@ -117,10 +124,13 @@ bool CxImagePCX::Decode(CxFile *hFile)
 	}
 
 	for (uint32_t idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((uint8_t)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
 
     lpHead2 = pcxpixels = (uint8_t *)malloc(Width + pcxHeader.BytesPerLine * 8);
+    if (!pcxpixels)
+        cx_throw("Cancelled");
+
     // Convert the image
     for (y = 0; y < Height; y++){
 
 		if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
 
@@ -136,11 +146,15 @@ bool CxImagePCX::Decode(CxFile *hFile)
 			continue;
 #if CXIMAGE_SUPPORT_ALPHA
 		} else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 8){
 			for (x = 0; x < Width; x++){
 				SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
-				AlphaSet(x,y2,pcxplanes[3*pcxHeader.BytesPerLine + x]);
+
+                uint32_t alphaIndex = 3*pcxHeader.BytesPerLine + x;
+
+                if (alphaIndex < pcximage_size)
+                    AlphaSet(x,y2,pcxplanes[alphaIndex]);
 			}
 			continue;
 #endif //CXIMAGE_SUPPORT_ALPHA
 		} else if (pcxHeader.ColorPlanes == 1) {
 			if (!PCX_UnpackPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
diff --git a/DesktopEditor/cximage/CxImage/ximatif.cpp b/DesktopEditor/cximage/CxImage/ximatif.cpp
index 77b940c8f..2cfd5bbf6 100644
--- a/DesktopEditor/cximage/CxImage/ximatif.cpp
+++ b/DesktopEditor/cximage/CxImage/ximatif.cpp
@@ -299,18 +299,20 @@ bool CxImageTIF::Decode(CxFile * hFile)
 			rowsperstrip = tl;
 			bitsize = TIFFTileSize(m_tif) * (int32_t)(1+width/tw);
 			tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif));
 		}
 		
-		bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
+        int32_t bitsize_correct = bitspersample==16? bitsize*2 : bitsize;
+        bits = (uint8_t*)malloc(bitsize_correct); // * VK
 		uint8_t * bits16 = NULL;										  // + VK
 		int32_t line16    = 0;											  // + VK
 
 		if (!tiled_image && bitspersample==16) {					  // + VK +
 			line16 = line;
 			line   = CalculateLine(width, 8 * samplesperpixel);
 			bits16 = bits;
+            bitsize_correct = bitsize;
 			bits   = (uint8_t*)malloc(bitsize);
 		}
 
 		if (bits==NULL){
 			if (bits16) free(bits16);								  // + VK
@@ -452,13 +454,22 @@ bool CxImageTIF::Decode(CxFile * hFile)
 					RGBQUAD c;
 					int32_t l,a,b,bitsoffset;
 					double p,cx,cy,cz,cr,cg,cb;
 					while (ii</*line*/width){		// * VK
 						bitsoffset = ii*samplesperpixel+offset;
-						l=bits[bitsoffset];
-						a=bits[bitsoffset+1];
-						b=bits[bitsoffset+2];
+                        if (bitsoffset + 2 < bitsize_correct)
+                        {
+                            l=bits[bitsoffset];
+                            a=bits[bitsoffset+1];
+                            b=bits[bitsoffset+2];
+                        }
+                        else
+                        {
+                            l=0;
+                            a=0;
+                            b=0;
+                        }
 						if (a>127) a-=256;
 						if (b>127) b-=256;
 						// lab to xyz
 						p = (l/2.55 + 16) / 116.0;
 						cx = pow( p + a * 0.002, 3);
diff --git a/DesktopEditor/cximage/CxImage/xiofile.h b/DesktopEditor/cximage/CxImage/xiofile.h
index 8ab5f1bfa..e6b8334c0 100644
--- a/DesktopEditor/cximage/CxImage/xiofile.h
+++ b/DesktopEditor/cximage/CxImage/xiofile.h
@@ -57,13 +57,14 @@ public:
 			m_fp = NULL;
 		}
 		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);
 	}
 //////////////////////////////////////////////////////////
 	virtual size_t	Write(const void *buffer, size_t size, size_t count)
 	{
diff --git a/DesktopEditor/cximage/CxImage/xmemfile.cpp b/DesktopEditor/cximage/CxImage/xmemfile.cpp
index 42dfadef3..180184db2 100644
--- a/DesktopEditor/cximage/CxImage/xmemfile.cpp
+++ b/DesktopEditor/cximage/CxImage/xmemfile.cpp
@@ -43,19 +43,19 @@ uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
 	if( bDetachBuffer )
 		m_bFreeOnClose = false;
 	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;
 
 	if (m_pBuffer==NULL) return 0;
 	if (m_Position >= (int32_t)m_Size){
 		m_bEOF = true;
 		return 0;
-	}
+    }
 
 	int32_t nCount = (int32_t)(count*size);
 	if (nCount == 0) return 0;
 
 	int32_t nRead;
diff --git a/DesktopEditor/cximage/CxImage/xmemfile.h b/DesktopEditor/cximage/CxImage/xmemfile.h
index 71e00eb06..385d16b30 100644
--- a/DesktopEditor/cximage/CxImage/xmemfile.h
+++ b/DesktopEditor/cximage/CxImage/xmemfile.h
@@ -12,11 +12,11 @@ public:
 
 	bool Open();
 	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();
 	virtual int32_t	Size();
 	virtual bool	Flush();
diff --git a/DesktopEditor/cximage/jasper/jpc/jpc_dec.c b/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
index fa72a0e82..df986bcc6 100644
--- a/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
+++ b/DesktopEditor/cximage/jasper/jpc/jpc_dec.c
@@ -2169,11 +2169,16 @@ int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents)
 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;
 		}
 	}
 	inspt = i;
diff --git a/DesktopEditor/cximage/raw/libdcr.c b/DesktopEditor/cximage/raw/libdcr.c
index e671e47c6..73f4ab375 100644
--- a/DesktopEditor/cximage/raw/libdcr.c
+++ b/DesktopEditor/cximage/raw/libdcr.c
@@ -3516,24 +3516,25 @@ void DCR_CLASS dcr_pseudoinverse (double (*in)[3], double (*out)[3], int size)
 
 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];
 }
 
@@ -5389,20 +5390,24 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
 			p->is_raw = 0;
 	if (!p->dng_version && p->tiff_bps == 8 && p->tiff_compress == 1 &&
 		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;
 			p->thumb_length = p->tiff_ifd[i].bytes;
 			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) {
 		case 0:
 			p->write_thumb = &DCR_CLASS dcr_layer_thumb;
@@ -5843,14 +5848,20 @@ void DCR_CLASS dcr_parse_riff(DCRAW* p)
 	char tag[4], date[64], month[64];
 	static const char mon[12][4] =
 	{ "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)
 			dcr_parse_riff(p);
 	} else if (!memcmp(tag,"nctg",4)) {
diff --git a/DesktopEditor/cximage/tiff/tif_dirread.c b/DesktopEditor/cximage/tiff/tif_dirread.c
index 907b53188..408b9980f 100644
--- a/DesktopEditor/cximage/tiff/tif_dirread.c
+++ b/DesktopEditor/cximage/tiff/tif_dirread.c
@@ -203,11 +203,11 @@ TIFFReadDirectory(TIFF* tif)
 		fip = tif->tif_fieldinfo[fix];
 		while (dp->tdir_type != (unsigned short) fip->field_type
 		    && 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,
 			"%s: wrong data type %d for \"%s\"; tag ignored",
 					    tif->tif_name, dp->tdir_type,
@@ -331,11 +331,11 @@ TIFFReadDirectory(TIFF* tif)
 		fip = tif->tif_fieldinfo[fix];
 		while (dp->tdir_type != (unsigned short) fip->field_type
 		    && 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,
 			"%s: wrong data type %d for \"%s\"; tag ignored",
 					    tif->tif_name, dp->tdir_type,
@@ -885,11 +885,11 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
 		fip = tif->tif_fieldinfo[fix];
 		while (dp->tdir_type != (unsigned short) fip->field_type
                        && 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,
 			"%s: wrong data type %d for \"%s\"; tag ignored",
 					    tif->tif_name, dp->tdir_type,
diff --git a/DesktopEditor/cximage/tiff/tif_ojpeg.c b/DesktopEditor/cximage/tiff/tif_ojpeg.c
index 793de8361..dea897484 100644
--- a/DesktopEditor/cximage/tiff/tif_ojpeg.c
+++ b/DesktopEditor/cximage/tiff/tif_ojpeg.c
@@ -1918,11 +1918,13 @@ OJPEGReadBufferFill(OJPEGState* sp)
 					{
 						if (sp->in_buffer_file_pos>=sp->file_size)
 							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)
 								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
 						}
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp b/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
index 2d9041677..b2df678b1 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
+++ b/DesktopEditor/fontengine/fontconverter/FontFileType1.cpp
@@ -631,17 +631,20 @@ namespace NSFontConverter
     {
         // Согласно спецификации Type1, первый байт не должен быть ASCII пробелом
         // (пробел, таб, перенос каретки или перенос строки).
         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 )
             ASCIIHexDecode( &sCur, sCur + nLen, sCur, nLen );
 
diff --git a/DesktopEditor/fontengine/fontconverter/FontFileType1.h b/DesktopEditor/fontengine/fontconverter/FontFileType1.h
index 7f2aa7123..a126b91a1 100644
--- a/DesktopEditor/fontengine/fontconverter/FontFileType1.h
+++ b/DesktopEditor/fontengine/fontconverter/FontFileType1.h
@@ -257,10 +257,12 @@ namespace NSFontConverter
                     bNewItem = false;
                     nCount++;
                 }
 
                 sBuffer[nBufPos++] = unChar;
+                if (nBufPos >= c_nNumLimit)
+                    break;
             }
 
             if ( 0 != sBuffer[0] && nCount > 0 )
                 pArray[nCount - 1] = Utils::GetDouble( (const char *)sBuffer );
 

Vulnerable code:                 int val = (int)(((byteMain & 0x1F) << 6) |
                    (pBuffer[lIndex + 1] & 0x3F));
                int val = (int)(((byteMain & 0x0F) << 12) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 6) |
                    (pBuffer[lIndex + 2] & 0x3F));
                int val = (int)(((byteMain & 0x07) << 18) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 12) |
                    ((pBuffer[lIndex + 2] & 0x3F) << 6) |
                    (pBuffer[lIndex + 3] & 0x3F));
                int val = (int)(((byteMain & 0x07) << 18) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 12) |
                    ((pBuffer[lIndex + 2] & 0x3F) << 6) |
                    (pBuffer[lIndex + 3] & 0x3F));
                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 = (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 = (int)(((byteMain & 0x1F) << 6) |
                    (pBuffer[lIndex + 1] & 0x3F));
                int val = (int)(((byteMain & 0x0F) << 12) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 6) |
                    (pBuffer[lIndex + 2] & 0x3F));
                int val = (int)(((byteMain & 0x07) << 18) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 12) |
                    ((pBuffer[lIndex + 2] & 0x3F) << 6) |
                    (pBuffer[lIndex + 3] & 0x3F));
                int val = (int)(((byteMain & 0x07) << 18) |
                    ((pBuffer[lIndex + 1] & 0x3F) << 12) |
                    ((pBuffer[lIndex + 2] & 0x3F) << 6) |
                    (pBuffer[lIndex + 3] & 0x3F));
                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 = (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));
	CxFile(void) { };
	virtual ~CxFile() { };
	virtual size_t	Read(void *buffer, size_t size, size_t count) = 0;
            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
					hFile->Read(buff32, imagesize,1); // read in the pixels
				hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
			hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
				hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
									hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1);
	pDib = pSelection = pAlpha = NULL;
int32_t CxImage::GetSize()
	return head.biSize + head.biSizeImage + GetPaletteSize();
	from.pDib = from.pSelection = from.pAlpha = NULL;
	int32_t	GetSize();
					hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
					hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
				AlphaSet(x,y2,pcxplanes[3*pcxHeader.BytesPerLine + x]);
		bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
						l=bits[bitsoffset];
						a=bits[bitsoffset+1];
						b=bits[bitsoffset+2];
	virtual size_t	Read(void *buffer, size_t size, size_t count)
size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
	}
	virtual size_t	Read(void *buffer, size_t size, size_t count);
	for (i = 0; i < tab->numents; ++i) {

	for (i=0; i < p->colors; i++)		/* Multiply out XYZ colorspace */
	for (i=0; i < p->colors; i++) {		/* Normalize cam_rgb so that */
	dcr_pseudoinverse (cam_rgb, inverse, p->colors);
			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))) {
	end = dcr_ftell(p->obj_) + size;
			fip = tif->tif_fieldinfo[++fix];
			fip = tif->tif_fieldinfo[++fix];
                        fip = tif->tif_fieldinfo[++fix];
							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];  
        if ( isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
Fixed code:                 int val = 0;
                if ((lIndex + 1) < lCount)
                {
                    val = (int)(((byteMain & 0x1F) << 6) |
                                (pBuffer[lIndex + 1] & 0x3F));
                }

                int val = 0;
                if ((lIndex + 2) < lCount)
                {
                    val = (int)(((byteMain & 0x0F) << 12) |
                                ((pBuffer[lIndex + 1] & 0x3F) << 6) |
                                (pBuffer[lIndex + 2] & 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));
                }

                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));
                }

                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));
                }

                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));
                }

                int val = 0;
                if ((lIndex + 1) < lCount)
                {
                    val = (int)(((byteMain & 0x1F) << 6) |
                                (pBuffer[lIndex + 1] & 0x3F));
                }

                int val = 0;
                if ((lIndex + 2) < lCount)
                {
                    val = (int)(((byteMain & 0x0F) << 12) |
                                ((pBuffer[lIndex + 1] & 0x3F) << 6) |
                                (pBuffer[lIndex + 2] & 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));
                }
                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));
                }
                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));
                }
                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));
                }
	CxFile(void) { }
	virtual ~CxFile() { }
	virtual size_t	Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL) = 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);
}

            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1,GetDIB(),GetDIBLimit());
            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1,GetDIB(),GetDIBLimit());
                    hFile->Read(buff32, imagesize,1,GetDIB(),GetDIBLimit()); // read in the pixels
                hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
            hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1,GetDIB(),GetDIBLimit());
                hFile->Read(info.pImage, head.biSizeImage,1,GetDIB(),GetDIBLimit()); // read in the pixels
                                    hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1,GetDIB(),GetDIBLimit());
    pDib = pDibLimit = pSelection = pAlpha = NULL;
    pDibLimit = (void*)((uint8_t*)pDib + GetSize());
uint32_t CxImage::GetSize()
    uint64_t size64 = head.biSize + head.biSizeImage + GetPaletteSize();
    if (size64 > 0xFFFFFFFF)
        return 0xFFFFFFFF;
    return (uint32_t)size64;
    pDib = from.pDibLimit;
    from.pDib = from.pDibLimit = from.pSelection = from.pAlpha = NULL;
        pDibLimit = from->pDibLimit;
	uint32_t	GetSize();
	void*	GetDIBLimit() const;
	void*				pDibLimit;

                {
                    DWORD _count = bih.biClrUsed; if (_count > 256) _count = 256;
                    hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
                }
                {
                    DWORD _count = head.biClrUsed; if (_count > 256) _count = 256;
                    hFile->Read(pal,_count*sizeof(RGBQUAD), 1);
                }
void* CxImage::GetDIBLimit() const
{
    return pDibLimit;
}
    if (Width <= 0 || Height <= 0)
        cx_throw("Error: Not a PCX file");

    uint32_t pcximage_size = nbytes;
    if (!pcximage)
        cx_throw("Cancelled");

    if (!pcxpixels)
        cx_throw("Cancelled");


                uint32_t alphaIndex = 3*pcxHeader.BytesPerLine + x;

                if (alphaIndex < pcximage_size)
                    AlphaSet(x,y2,pcxplanes[alphaIndex]);
        int32_t bitsize_correct = bitspersample==16? bitsize*2 : bitsize;
        bits = (uint8_t*)malloc(bitsize_correct); // * VK
            bitsize_correct = bitsize;
                        if (bitsoffset + 2 < bitsize_correct)
                        {
                            l=bits[bitsoffset];
                            a=bits[bitsoffset+1];
                            b=bits[bitsoffset+2];
                        }
                        else
                        {
                            l=0;
                            a=0;
                            b=0;
                        }
	virtual size_t	Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL)
		clamp_buffer(buffer, size, limit_start, limit_end);
size_t CxMemFile::Read(void *buffer, size_t size, size_t count, void* limit_start, void* limit_end)
    }
	virtual size_t	Read(void *buffer, size_t size, size_t count, void* limit_start = NULL, void* limit_end = NULL);
    // 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) {
    int max_colors = p->colors;
    if (max_colors > 4) max_colors = 4;
    for (i=0; i < max_colors; i++)		/* Multiply out XYZ colorspace */
    for (i=0; i < max_colors; i++) {		/* Normalize cam_rgb so that */
    dcr_pseudoinverse (cam_rgb, inverse, max_colors);
    {
        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;
            p->tiff_ifd[i].width * p->tiff_ifd[i].height / sqr_1 >
            (int)(p->thumb_width *       p->thumb_height / sqr_2)) {
    }
    if (dcr_feof(p->obj_))
    {
        fprintf (stderr,_("Unexpected end of file\n"));
        return;
    }

    end = dcr_ftell(p->obj_) + size;
            ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[++fix];
            ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[++fix];
            ++fix; fip = (fix >= tif->tif_nfields) ? 0 : tif->tif_fieldinfo[++fix];
                            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];
        {
            --nLen;
        }
        if ( nLen > 3 && isxdigit( sCur[0] ) && isxdigit( sCur[1] ) && isxdigit( sCur[2] ) && isxdigit( sCur[3] ) )
                if (nBufPos >= c_nNumLimit)
                    break;