[Development] QJsonPrivate::Parser::parseObject broken on big endian
Konstantin Tokarev
annulen at yandex.ru
Thu Sep 13 12:56:02 CEST 2012
03.09.2012, 15:21, "Olivier Goffart" <olivier at woboq.com>:
> On Sunday 02 September 2012 23:10:18 Konstantin Tokarev wrote:
>> Hi all,
>>
>> When building Qt 5 on big endian host (PPC) I've found moc breaking on Qt
>> classes containing Q_PLUGIN_METADATA with
>>
>> ASSERT: "idx >= 0 && idx < s" in file
>> ../../../include/QtCore/../../src/corelib/tools/qvarlengtharray.h, line 111
>>
>> It turned out to be a fault of QJsonPrivate::Parser::parseObject which has
>> different code for handling of big endian and little endian cases:
>>
>> if (parsedObject.offsets.size()) {
>> int tableSize = parsedObject.offsets.size()*sizeof(uint);
> ^^^^^^^^^^^^^
>
> The error is there: one should multiply tableSize by sizeof(uint) only if one
> do a memcpy.
>> table = reserveSpace(tableSize);
>> #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
>> memcpy(data + table, parsedObject.offsets.constData(), tableSize);
>> #else
>> offset *o = (offset *)(data + table);
>> for (int i = 0; i < tableSize; ++i)
>> o[i] = parsedObject.offsets[i];
>>
>> #endif
>> }
>>
>> Could anyone explain why memcpy cannot be used for big endian case here?
> I guess that's because the offsets needs to be stored in little endian.
> offset is a typedef to a class that has an assignement operator which swap the
> bytes.
It turned out to be not the only place where memcpy is working incorrectly.
Unit test segfaults on memcpy in Value::copyData
404 case QJsonValue::Array:
405 case QJsonValue::Object: {
406 const QJsonPrivate::Base *b = v.base;
407 if (!b)
408 b = (v.t == QJsonValue::Array ? &emptyArray : &emptyObject);
409 memcpy(dest, b, b->size);
410 break;
411 }
I tried to understand why memcpy fails here and how to replace it for BE case,
but still don't have a clue. I'm also quite disappointed to see so heavily endian-
dependent code written nowadays.
--
Regards,
Konstantin
More information about the Development
mailing list