diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 294f68b1220cf0ad761a8f4daad227147007c9e0..7735dc13797a2807c7425eed8c778f501554def1 100755
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -67,7 +67,7 @@ BOOL LLImagePNG::updateData()
 	}
 
 	LLPngWrapper::ImageInfo infop;
-	if (! pngWrapper.readPng(getData(), NULL, &infop))
+	if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
 	{
 		setLastError(pngWrapper.getErrorMessage());
 		return FALSE;
@@ -102,7 +102,7 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
 		return FALSE;
 	}
 
-	if (! pngWrapper.readPng(getData(), raw_image))
+	if (! pngWrapper.readPng(getData(), getDataSize(), raw_image))
 	{
 		setLastError(pngWrapper.getErrorMessage());
 		return FALSE;
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 2cc7d3c460c7ed93146271a1e013ab26d7ef7b49..aad139f57087c2dc818a67f57ee08d1bf6840522 100755
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
@@ -87,6 +87,12 @@ void LLPngWrapper::errorHandler(png_structp png_ptr, png_const_charp msg)
 void LLPngWrapper::readDataCallback(png_structp png_ptr, png_bytep dest, png_size_t length)
 {
 	PngDataInfo *dataInfo = (PngDataInfo *) png_get_io_ptr(png_ptr);
+	if(dataInfo->mOffset + length > dataInfo->mDataSize)
+	{
+		png_error(png_ptr, "Data read error. Requested data size exceeds available data size.");
+		return;
+	}
+
 	U8 *src = &dataInfo->mData[dataInfo->mOffset];
 	memcpy(dest, src, length);
 	dataInfo->mOffset += static_cast<U32>(length);
@@ -114,7 +120,7 @@ void LLPngWrapper::writeFlush(png_structp png_ptr)
 // The scanline also begins at the bottom of
 // the image (per SecondLife conventions) instead of at the top, so we
 // must assign row-pointers in "reverse" order.
-BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop)
+BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop)
 {
 	try
 	{
@@ -133,6 +139,7 @@ BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop)
 		PngDataInfo dataPtr;
 		dataPtr.mData = src;
 		dataPtr.mOffset = 0;
+		dataPtr.mDataSize = dataSize;
 
 		png_set_read_fn(mReadPngPtr, &dataPtr, &readDataCallback);
 		png_set_sig_bytes(mReadPngPtr, 0);
diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h
index 739f4359961c6155bcfb3bd68fb11c70326b8883..27d7df3bef9a9af161542a7b2d4077908cbfcd50 100755
--- a/indra/llimage/llpngwrapper.h
+++ b/indra/llimage/llpngwrapper.h
@@ -44,7 +44,7 @@ class LLPngWrapper
 	};
 
 	BOOL isValidPng(U8* src);
-	BOOL readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop = NULL);
+	BOOL readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop = NULL);
 	BOOL writePng(const LLImageRaw* rawImage, U8* dst);
 	U32  getFinalSize();
 	const std::string& getErrorMessage();
@@ -61,6 +61,7 @@ class LLPngWrapper
 	{
 		U8 *mData;
 		U32 mOffset;
+		S32 mDataSize;
 	};
 
 	static void writeFlush(png_structp png_ptr);