JXL: Fix missing checks for BOXES when parsing animation

Fix error when parsing something like:

```
JXL_DEC_BOX
JXL_DEC_BOX
JXL_DEC_BOX
JXL_DEC_BASIC_INFO
JXL_DEC_COLOR_ENCODING
JXL_DEC_BOX
JXL_DEC_BOX
JXL_DEC_FRAME
JXL_DEC_BOX
JXL_DEC_FRAME
```

CCBUG: 496350
This commit is contained in:
Mirco Miranda 2025-01-04 06:46:41 +00:00
parent 5c0c7e4fd7
commit e6a0f8758b
4 changed files with 29 additions and 10 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -382,6 +382,11 @@ bool QJpegXLHandler::countALLFrames()
case JXL_DEC_NEED_MORE_INPUT: case JXL_DEC_NEED_MORE_INPUT:
qWarning("ERROR: JXL data incomplete"); qWarning("ERROR: JXL data incomplete");
break; break;
case JXL_DEC_BOX:
if (!decodeBox(status)) {
qWarning("ERROR: JXL BOX decoding failed");
}
continue;
default: default:
qWarning("Unexpected event %d instead of JXL_DEC_FRAME", status); qWarning("Unexpected event %d instead of JXL_DEC_FRAME", status);
break; break;
@ -1214,16 +1219,8 @@ bool QJpegXLHandler::decodeBoxes(JxlDecoderStatus &status)
{ {
do { // decode metadata do { // decode metadata
status = JxlDecoderProcessInput(m_decoder); status = JxlDecoderProcessInput(m_decoder);
if (status == JXL_DEC_BOX) { if (!decodeBox(status)) {
JxlBoxType type; qWarning("ERROR: JXL BOX decoding failed");
JxlDecoderGetBoxType(m_decoder, type, JXL_FALSE);
if (memcmp(type, "xml ", 4) == 0) {
uint64_t size;
if (JxlDecoderGetBoxSizeRaw(m_decoder, &size) == JXL_DEC_SUCCESS && size < uint64_t(kMaxQVectorSize)) {
m_xmp = QByteArray(size, '\0');
JxlDecoderSetBoxBuffer(m_decoder, reinterpret_cast<uint8_t *>(m_xmp.data()), m_xmp.size());
}
}
} }
} while (status == JXL_DEC_BOX); } while (status == JXL_DEC_BOX);
@ -1240,6 +1237,27 @@ bool QJpegXLHandler::decodeBoxes(JxlDecoderStatus &status)
return true; return true;
} }
bool QJpegXLHandler::decodeBox(const JxlDecoderStatus &status)
{
if (status != JXL_DEC_BOX) {
return true;
}
JxlBoxType type;
JxlDecoderGetBoxType(m_decoder, type, JXL_FALSE);
if (memcmp(type, "xml ", 4) == 0) {
uint64_t size;
if (JxlDecoderGetBoxSizeRaw(m_decoder, &size) == JXL_DEC_SUCCESS && size < uint64_t(kMaxQVectorSize)) {
m_xmp = QByteArray(size, '\0');
JxlDecoderSetBoxBuffer(m_decoder, reinterpret_cast<uint8_t *>(m_xmp.data()), m_xmp.size());
return true;
}
return false;
}
return true;
}
QImageIOPlugin::Capabilities QJpegXLPlugin::capabilities(QIODevice *device, const QByteArray &format) const QImageIOPlugin::Capabilities QJpegXLPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{ {
if (format == "jxl") { if (format == "jxl") {

View File

@ -52,6 +52,7 @@ private:
bool decode_one_frame(); bool decode_one_frame();
bool rewind(); bool rewind();
bool decodeBoxes(JxlDecoderStatus &status); bool decodeBoxes(JxlDecoderStatus &status);
bool decodeBox(const JxlDecoderStatus &status);
enum ParseJpegXLState { enum ParseJpegXLState {
ParseJpegXLError = -1, ParseJpegXLError = -1,