mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-05-28 00:30:23 -04:00
Fix endianness bug in PCX reader on big endian architectures
When reading from a sequential device, the peekHeader() method in the PCX readers reads the header its defined little endian into arch-specific endianness for multibyte types. Being a "peek" method, it then it tries to push back the bytes into the device after reading for its next use, but it doesn’t convert multibyte types correctly from arch-specifice endianness to the initial little endian format. Subsequent reading of the data from the device will thus lead to incorrect values for multibyte types on the next use. This patch reuses the same technique as the TGA reader to read the whole header as bytes before deserializing it, so that the bytes can be pushed back into the sequential device in the same order.
This commit is contained in:
parent
46f7b90ce6
commit
ae641f7e94
@ -266,29 +266,30 @@ PCXHEADER::PCXHEADER()
|
||||
|
||||
bool peekHeader(QIODevice *d, PCXHEADER& h)
|
||||
{
|
||||
qint64 pos = 0;
|
||||
if (!d->isSequential()) {
|
||||
pos = d->pos();
|
||||
qint64 oldPos = d->pos();
|
||||
QByteArray head = d->read(sizeof(PCXHEADER));
|
||||
int readBytes = head.size();
|
||||
|
||||
if (d->isSequential()) {
|
||||
for (int pos = readBytes -1; pos >= 0; --pos) {
|
||||
d->ungetChar(head[pos]);
|
||||
}
|
||||
} else {
|
||||
d->seek(oldPos);
|
||||
}
|
||||
|
||||
if (readBytes < sizeof(PCXHEADER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ok = false;
|
||||
{ // datastream is destroyed before working on device
|
||||
QDataStream ds(d);
|
||||
QDataStream ds(head);
|
||||
ds.setByteOrder(QDataStream::LittleEndian);
|
||||
ds >> h;
|
||||
ok = ds.status() == QDataStream::Ok && h.isValid();
|
||||
}
|
||||
|
||||
if (!d->isSequential()) {
|
||||
return d->seek(pos) && ok;
|
||||
}
|
||||
|
||||
// sequential device undo
|
||||
auto head = reinterpret_cast<char*>(&h);
|
||||
auto readBytes = sizeof(h);
|
||||
while (readBytes > 0) {
|
||||
d->ungetChar(head[readBytes-- - 1]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user