Commit d7008760 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Let Krita open invalid PSD files

Some weird web apps generate invalid invalid PSD files with the
layer-mask-section size tag set incorrectly. We can still make some
effort on trying to load these file, though we give no guarantess.

BUG:444844
parent a30ff02f
Pipeline #206503 passed with stage
in 49 minutes and 16 seconds
......@@ -203,30 +203,38 @@ bool PSDLayerMaskSection::readPsdImpl(QIODevice &io)
{
dbgFile << "(PSD) reading layer section. Pos:" << io.pos() << "bytes left:" << io.bytesAvailable();
layerMaskBlockSize = 0;
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_21849
boost::optional<quint64> layerMaskBlockSize = 0;
if (m_header.version == 1) {
quint32 _layerMaskBlockSize = 0;
if (!psdread(io, _layerMaskBlockSize) || _layerMaskBlockSize > (quint64)io.bytesAvailable()) {
error = QString("Could not read layer block size. Got %1. Bytes left %2").arg(_layerMaskBlockSize).arg(io.bytesAvailable());
return false;
}
SAFE_READ_EX(psd_byte_order::psdBigEndian, io, _layerMaskBlockSize);
layerMaskBlockSize = _layerMaskBlockSize;
} else if (m_header.version == 2) {
if (!psdread(io, layerMaskBlockSize) || layerMaskBlockSize > (quint64)io.bytesAvailable()) {
error = QString("Could not read layer block size. Got %1. Bytes left %2").arg(layerMaskBlockSize).arg(io.bytesAvailable());
return false;
}
SAFE_READ_EX(psd_byte_order::psdBigEndian, io, *layerMaskBlockSize);
}
qint64 start = io.pos();
dbgFile << "layer block size" << layerMaskBlockSize;
dbgFile << "layer block size" << *layerMaskBlockSize;
if (layerMaskBlockSize == 0) {
if (*layerMaskBlockSize == 0) {
dbgFile << "No layer info, so no PSD layers available";
return false;
}
/**
* PSD files created in some weird web applications may
* have invalid layer-mask-block-size set. Just do a simple
* sanity check to catch this case
*/
if (static_cast<qint64>(*layerMaskBlockSize) > io.bytesAvailable()) {
warnKrita << "WARNING: invalid layer block size. Got" << *layerMaskBlockSize << "Bytes left" << io.bytesAvailable() << "Triggering a workaround...";
// just don't use this value for offset recovery at the end
layerMaskBlockSize = boost::none;
}
if (!readLayerInfoImpl(io)) {
return false;
}
......@@ -290,8 +298,10 @@ bool PSDLayerMaskSection::readPsdImpl(QIODevice &io)
globalInfoSection.read(io);
/* put us after this section so reading the next section will work even if we mess up */
io.seek(start + static_cast<qint64>(layerMaskBlockSize));
if (layerMaskBlockSize) {
/* put us after this section so reading the next section will work even if we mess up */
io.seek(start + static_cast<qint64>(*layerMaskBlockSize));
}
return true;
}
......
......@@ -30,9 +30,6 @@ public:
QString error;
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_21849
quint64 layerMaskBlockSize{0}; // Length of the layer and mask information section
// layer info: https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_16000
bool hasTransparency{false};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment