PSD: improve sections size checks

This commit is contained in:
Mirco Miranda
2025-10-24 08:39:58 +02:00
parent 326e56029a
commit 3d4d74fc02

View File

@ -332,6 +332,12 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
// Reading Image resource block // Reading Image resource block
for (auto size = sectioSize; size > 0;) { for (auto size = sectioSize; size > 0;) {
#define DEC_SIZE(value) \
if ((size -= (value)) < 0) { \
*ok = false; \
break; }
// Length Description // Length Description
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// 4 Signature: '8BIM' // 4 Signature: '8BIM'
@ -346,7 +352,7 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
quint32 signature; quint32 signature;
s >> signature; s >> signature;
size -= sizeof(signature); DEC_SIZE(sizeof(signature))
// NOTE: MeSa signature is not documented but found in some old PSD take from Photoshop 7.0 CD. // NOTE: MeSa signature is not documented but found in some old PSD take from Photoshop 7.0 CD.
if (signature != S_8BIM && signature != S_MeSa) { // 8BIM and MeSa if (signature != S_8BIM && signature != S_MeSa) { // 8BIM and MeSa
qCDebug(LOG_PSDPLUGIN) << "Invalid Image Resource Block Signature!"; qCDebug(LOG_PSDPLUGIN) << "Invalid Image Resource Block Signature!";
@ -357,7 +363,7 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
// id // id
quint16 id; quint16 id;
s >> id; s >> id;
size -= sizeof(id); DEC_SIZE(sizeof(id))
// getting data // getting data
PSDImageResourceBlock irb; PSDImageResourceBlock irb;
@ -365,19 +371,20 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
// name // name
qint32 bytes = 0; qint32 bytes = 0;
irb.name = readPascalString(s, 2, &bytes); irb.name = readPascalString(s, 2, &bytes);
size -= bytes; DEC_SIZE(bytes)
// data read // data read
quint32 dataSize; quint32 dataSize;
s >> dataSize; s >> dataSize;
size -= sizeof(dataSize); DEC_SIZE(sizeof(dataSize))
// NOTE: Qt device::read() and QDataStream::readRawData() could read less data than specified. // NOTE: Qt device::read() and QDataStream::readRawData() could read less data than specified.
// The read code should be improved. // The read code should be improved.
if (auto dev = s.device()) if (auto dev = s.device())
irb.data = dev->read(dataSize); irb.data = dev->read(dataSize);
auto read = irb.data.size(); auto read = irb.data.size();
if (read > 0) if (read > 0) {
size -= read; DEC_SIZE(read)
}
if (quint32(read) != dataSize) { if (quint32(read) != dataSize) {
qCDebug(LOG_PSDPLUGIN) << "Image Resource Block Read Error!"; qCDebug(LOG_PSDPLUGIN) << "Image Resource Block Read Error!";
*ok = false; *ok = false;
@ -386,12 +393,15 @@ static PSDImageResourceSection readImageResourceSection(QDataStream &s, bool *ok
if (auto pad = dataSize % 2) { if (auto pad = dataSize % 2) {
auto skipped = s.skipRawData(pad); auto skipped = s.skipRawData(pad);
if (skipped > 0) if (skipped > 0) {
size -= skipped; DEC_SIZE(skipped);
}
} }
// insert IRB // insert IRB
irs.insert(id, irb); irs.insert(id, irb);
#undef DEC_SIZE
} }
return irs; return irs;
@ -489,7 +499,13 @@ PSDColorModeDataSection readColorModeDataSection(QDataStream &s, bool *ok = null
qint32 size; qint32 size;
s >> size; s >> size;
if (size != 768) { // read the duotone data (524 bytes) if (size < 0) {
*ok = false;
} else if (size > 8 * 1024 * 1024) {
// The known color sections are all in the order of a few hundred bytes.
// I skip the ones that are too big, I don't know what to do with them.
*ok = s.skipRawData(size) == size;
} else if (size != 768) { // read the duotone data (524 bytes)
// NOTE: A RGB/Gray float image has a 112 bytes ColorModeData that could be // NOTE: A RGB/Gray float image has a 112 bytes ColorModeData that could be
// the "32-bit Toning Options" of Photoshop (starts with 'hdrt'). // the "32-bit Toning Options" of Photoshop (starts with 'hdrt').
// Official Adobe specification tells "Only indexed color and duotone // Official Adobe specification tells "Only indexed color and duotone