From e8d98fd4d3ec5be83145d6fce52da0e5062f61a3 Mon Sep 17 00:00:00 2001 From: qbnu <93988953+qbnu@users.noreply.github.com> Date: Wed, 12 Jun 2024 00:34:11 -0400 Subject: [PATCH 1/4] psd: use byte counts for scan lines --- src/JPEGView/PSDWrapper.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/JPEGView/PSDWrapper.cpp b/src/JPEGView/PSDWrapper.cpp index c5ac0907..a4654ab3 100644 --- a/src/JPEGView/PSDWrapper.cpp +++ b/src/JPEGView/PSDWrapper.cpp @@ -300,6 +300,8 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) if (nCompressionMethod == COMPRESSION_RLE) { // Skip byte counts for scanlines p += nHeight * nRealChannels * 2; + ThrowIf(p >= (unsigned char*)pBuffer + nImageDataSize); + unsigned char* pOffset = p; for (unsigned channel = 0; channel < nChannels; channel++) { unsigned rchannel; if (nColorMode == MODE_Lab) { @@ -308,9 +310,14 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) rchannel = (-channel - 2) % nChannels; } for (unsigned row = 0; row < nHeight; row++) { + pOffset += _byteswap_ushort(*(unsigned short *)(pBuffer + (channel * nHeight + row) * 2)); + p = pOffset; + for (unsigned count = 0; count < nWidth; ) { unsigned char c; - ThrowIf(p >= (unsigned char*)pBuffer + nImageDataSize); + if (p >= (unsigned char*)pBuffer + nImageDataSize) { + break; + }; c = *p; p += 1; From bd7bb2b173ee730f480d8ac7e432c109c4d39743 Mon Sep 17 00:00:00 2001 From: qbnu <93988953+qbnu@users.noreply.github.com> Date: Wed, 12 Jun 2024 00:57:40 -0400 Subject: [PATCH 2/4] fix order --- src/JPEGView/PSDWrapper.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/JPEGView/PSDWrapper.cpp b/src/JPEGView/PSDWrapper.cpp index a4654ab3..0cb30a78 100644 --- a/src/JPEGView/PSDWrapper.cpp +++ b/src/JPEGView/PSDWrapper.cpp @@ -300,7 +300,6 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) if (nCompressionMethod == COMPRESSION_RLE) { // Skip byte counts for scanlines p += nHeight * nRealChannels * 2; - ThrowIf(p >= (unsigned char*)pBuffer + nImageDataSize); unsigned char* pOffset = p; for (unsigned channel = 0; channel < nChannels; channel++) { unsigned rchannel; @@ -310,14 +309,11 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) rchannel = (-channel - 2) % nChannels; } for (unsigned row = 0; row < nHeight; row++) { - pOffset += _byteswap_ushort(*(unsigned short *)(pBuffer + (channel * nHeight + row) * 2)); p = pOffset; for (unsigned count = 0; count < nWidth; ) { unsigned char c; - if (p >= (unsigned char*)pBuffer + nImageDataSize) { - break; - }; + ThrowIf(p >= (unsigned char*)pBuffer + nImageDataSize); c = *p; p += 1; @@ -351,6 +347,8 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) count += c; } + + pOffset += _byteswap_ushort(*(unsigned short*)(pBuffer + (channel * nHeight + row) * 2)); } } } else { // No compression From 6529fe9f878b97f6ba378447e69878d5f9251aad Mon Sep 17 00:00:00 2001 From: qbnu <93988953+qbnu@users.noreply.github.com> Date: Wed, 12 Jun 2024 01:14:57 -0400 Subject: [PATCH 3/4] check for 0 width/height --- src/JPEGView/PSDWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JPEGView/PSDWrapper.cpp b/src/JPEGView/PSDWrapper.cpp index 0cb30a78..b126d0ea 100644 --- a/src/JPEGView/PSDWrapper.cpp +++ b/src/JPEGView/PSDWrapper.cpp @@ -135,7 +135,7 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) if ((double)nHeight * nWidth > MAX_IMAGE_PIXELS) { bOutOfMemory = true; } - ThrowIf(bOutOfMemory || nHeight > MAX_IMAGE_DIMENSION || nWidth > MAX_IMAGE_DIMENSION); + ThrowIf(bOutOfMemory || max(nHeight, nWidth) > MAX_IMAGE_DIMENSION || !min(nHeight, nWidth)); // PSD can have bit depths of 1, 2, 4, 8, 16, 32 unsigned short nBitDepth = ReadUShortFromFile(hFile); From eab4a2b79c92c4d94bbfbb321246befd319c5c0f Mon Sep 17 00:00:00 2001 From: qbnu <93988953+qbnu@users.noreply.github.com> Date: Wed, 12 Jun 2024 21:03:01 -0400 Subject: [PATCH 4/4] add debug log --- src/JPEGView/PSDWrapper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/JPEGView/PSDWrapper.cpp b/src/JPEGView/PSDWrapper.cpp index b126d0ea..c3dc7a8b 100644 --- a/src/JPEGView/PSDWrapper.cpp +++ b/src/JPEGView/PSDWrapper.cpp @@ -349,6 +349,13 @@ CJPEGImage* PsdReader::ReadImage(LPCTSTR strFileName, bool& bOutOfMemory) } pOffset += _byteswap_ushort(*(unsigned short*)(pBuffer + (channel * nHeight + row) * 2)); +#ifdef DEBUG + if (p != pOffset) { + WCHAR buf[100]; + swprintf(buf, _T("Misaligned scan line bytes (%+d) for channel %d row %d\n"), p - pOffset, channel, row); + ::OutputDebugString(buf); + } +#endif } } } else { // No compression