mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 09:28:22 +08:00
Fix possible unaligned access to UCS2 strings
This commit is contained in:
parent
20d0155130
commit
c9939e23ec
@ -61,13 +61,11 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
|||||||
QRegularExpressionMatch regexpmatch;
|
QRegularExpressionMatch regexpmatch;
|
||||||
|
|
||||||
INT32 offset = 0;
|
INT32 offset = 0;
|
||||||
while ((offset = (INT32)hexBody.indexOf(regexp, (qsizetype)offset, ®expmatch)) != -1)
|
while ((offset = (INT32)hexBody.indexOf(regexp, (qsizetype)offset, ®expmatch)) != -1) {
|
||||||
{
|
|
||||||
#else
|
#else
|
||||||
QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive);
|
QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive);
|
||||||
|
|
||||||
INT32 offset = regexp.indexIn(hexBody);
|
INT32 offset = regexp.indexIn(hexBody);
|
||||||
|
|
||||||
while (offset >= 0) {
|
while (offset >= 0) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -223,11 +221,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
|||||||
|
|
||||||
UString data;
|
UString data;
|
||||||
if (unicode)
|
if (unicode)
|
||||||
#if QT_VERSION_MAJOR >= 6
|
data = uFromUcs2(body.constData(), body.length() / 2);
|
||||||
data = UString::fromUtf16((const char16_t*)body.constData(), (int)(body.length() / 2));
|
|
||||||
#else
|
|
||||||
data = UString::fromUtf16((const ushort*)body.constData(), (int)(body.length() / 2));
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
data = UString::fromLatin1((const char*)body.constData(), body.length());
|
data = UString::fromLatin1((const char*)body.constData(), body.length());
|
||||||
|
|
||||||
|
@ -807,7 +807,6 @@ void UEFITool::showParserMessages()
|
|||||||
|
|
||||||
#if QT_VERSION_MAJOR < 6
|
#if QT_VERSION_MAJOR < 6
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<QString, QModelIndex> msg;
|
||||||
|
|
||||||
foreach (msg, messages)
|
foreach (msg, messages)
|
||||||
#else
|
#else
|
||||||
for (const auto &msg : messages)
|
for (const auto &msg : messages)
|
||||||
@ -832,7 +831,6 @@ void UEFITool::showFinderMessages()
|
|||||||
|
|
||||||
#if QT_VERSION_MAJOR < 6
|
#if QT_VERSION_MAJOR < 6
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<QString, QModelIndex> msg;
|
||||||
|
|
||||||
foreach (msg, messages)
|
foreach (msg, messages)
|
||||||
#else
|
#else
|
||||||
for (const auto &msg : messages)
|
for (const auto &msg : messages)
|
||||||
@ -858,7 +856,6 @@ void UEFITool::showBuilderMessages()
|
|||||||
|
|
||||||
#if QT_VERSION_MAJOR < 6
|
#if QT_VERSION_MAJOR < 6
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<QString, QModelIndex> msg;
|
||||||
|
|
||||||
foreach (msg, messages)
|
foreach (msg, messages)
|
||||||
#else
|
#else
|
||||||
for (const auto &msg : messages)
|
for (const auto &msg : messages)
|
||||||
|
@ -373,16 +373,6 @@ struct CBString : public tagbstring {
|
|||||||
CBString mid(int pos, int len) const { return midstr(pos, len); }
|
CBString mid(int pos, int len) const { return midstr(pos, len); }
|
||||||
CBString chopped(int len) const { return midstr(slen - len, len); }
|
CBString chopped(int len) const { return midstr(slen - len, len); }
|
||||||
void chop(int len) { trunc(((slen > len) ? slen - len : 0)); }
|
void chop(int len) { trunc(((slen > len) ? slen - len : 0)); }
|
||||||
static CBString fromUtf16(const unsigned short* str) {
|
|
||||||
// Naive implementation assuming that only ASCII LE part of UCS2 is used, str may not be aligned.
|
|
||||||
CBString msg;
|
|
||||||
const char *str8 = reinterpret_cast<const char *>(str);
|
|
||||||
while (str8[0]) {
|
|
||||||
msg += str8[0];
|
|
||||||
str8 += 2;
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
CBString leftJustified(int length) { if (length > slen) { return *this + CBString(' ', length - slen); } return *this; }
|
CBString leftJustified(int length) { if (length > slen) { return *this + CBString(' ', length - slen); } return *this; }
|
||||||
};
|
};
|
||||||
extern const CBString operator + (const char *a, const CBString& b);
|
extern const CBString operator + (const char *a, const CBString& b);
|
||||||
|
@ -1122,7 +1122,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
|||||||
|
|
||||||
// Check attributes
|
// Check attributes
|
||||||
// Determine value of empty byte
|
// Determine value of empty byte
|
||||||
UINT8 emptyByte = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
|
UINT8 emptyByte = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? 0xFF : 0x00;
|
||||||
|
|
||||||
// Check for AppleCRC32 and UsedSpace in ZeroVector
|
// Check for AppleCRC32 and UsedSpace in ZeroVector
|
||||||
bool hasAppleCrc32 = false;
|
bool hasAppleCrc32 = false;
|
||||||
@ -2941,11 +2941,7 @@ USTATUS FfsParser::parseVersionSectionBody(const UModelIndex & index)
|
|||||||
return U_INVALID_PARAMETER;
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
#if QT_VERSION_MAJOR >= 6
|
model->addInfo(index, UString("\nVersion string: ") + uFromUcs2(model->body(index).constData()));
|
||||||
model->addInfo(index, UString("\nVersion string: ") + UString::fromUtf16((const char16_t*)model->body(index).constData()));
|
|
||||||
#else
|
|
||||||
model->addInfo(index, UString("\nVersion string: ") + UString::fromUtf16((const CHAR16*)model->body(index).constData()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -3082,11 +3078,7 @@ USTATUS FfsParser::parseUiSectionBody(const UModelIndex & index)
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return U_INVALID_PARAMETER;
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
#if QT_VERSION_MAJOR >= 6
|
UString text = uFromUcs2(model->body(index).constData());
|
||||||
UString text = UString::fromUtf16((const char16_t*)model->body(index).constData());
|
|
||||||
#else
|
|
||||||
UString text = UString::fromUtf16((const CHAR16*)model->body(index).constData());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
model->addInfo(index, UString("\nText: ") + text);
|
model->addInfo(index, UString("\nText: ") + text);
|
||||||
|
@ -258,12 +258,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
|||||||
nameSize = (UINT32)(text.length() + 1);
|
nameSize = (UINT32)(text.length() + 1);
|
||||||
}
|
}
|
||||||
else { // Name is stored as UCS2 string of CHAR16s
|
else { // Name is stored as UCS2 string of CHAR16s
|
||||||
#if QT_VERSION_MAJOR >= 6
|
text = uFromUcs2(namePtr);
|
||||||
text = UString::fromUtf16((char16_t*)namePtr);
|
|
||||||
#else
|
|
||||||
text = UString::fromUtf16((CHAR16*)namePtr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nameSize = (UINT32)((text.length() + 1) * 2);
|
nameSize = (UINT32)((text.length() + 1) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +534,9 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
UINT32 offset = storeOffset;
|
UINT32 offset = storeOffset;
|
||||||
for (; offset < dataSize - sizeof(UINT32); offset++) {
|
for (; offset < dataSize - sizeof(UINT32); offset++) {
|
||||||
const UINT32* currentPos = (const UINT32*)(volume.constData() + offset);
|
const UINT32* currentPos = (const UINT32*)(volume.constData() + offset);
|
||||||
if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_NSS_STORE_SIGNATURE) { // $VSS, $SVS or $NSS signatures found, perform checks
|
if (readUnaligned(currentPos) == NVRAM_VSS_STORE_SIGNATURE
|
||||||
|
|| readUnaligned(currentPos) == NVRAM_APPLE_SVS_STORE_SIGNATURE
|
||||||
|
|| readUnaligned(currentPos) == NVRAM_APPLE_NSS_STORE_SIGNATURE) { // $VSS, $SVS or $NSS signatures found, perform checks
|
||||||
const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos;
|
const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos;
|
||||||
if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) {
|
if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) {
|
||||||
msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index);
|
msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index);
|
||||||
@ -552,7 +549,8 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1 || *currentPos == NVRAM_VSS2_STORE_GUID_PART1) { // VSS2 store signatures found, perform checks
|
else if (readUnaligned(currentPos) == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1
|
||||||
|
|| readUnaligned(currentPos) == NVRAM_VSS2_STORE_GUID_PART1) { // VSS2 store signatures found, perform checks
|
||||||
UByteArray guid = UByteArray(volume.constData() + offset, sizeof(EFI_GUID));
|
UByteArray guid = UByteArray(volume.constData() + offset, sizeof(EFI_GUID));
|
||||||
if (guid != NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID && guid != NVRAM_VSS2_STORE_GUID) // Check the whole signature
|
if (guid != NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID && guid != NVRAM_VSS2_STORE_GUID) // Check the whole signature
|
||||||
continue;
|
continue;
|
||||||
@ -569,7 +567,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { // FDC signature found
|
else if (readUnaligned(currentPos) == NVRAM_FDC_VOLUME_SIGNATURE) { // FDC signature found
|
||||||
const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos;
|
const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos;
|
||||||
if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) {
|
if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) {
|
||||||
msg(usprintf("%s: FDC store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fdcHeader->Size), index);
|
msg(usprintf("%s: FDC store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fdcHeader->Size), index);
|
||||||
@ -578,7 +576,8 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { // Fsys or Gaid signature found
|
else if (readUnaligned(currentPos) == NVRAM_APPLE_FSYS_STORE_SIGNATURE
|
||||||
|
|| readUnaligned(currentPos) == NVRAM_APPLE_GAID_STORE_SIGNATURE) { // Fsys or Gaid signature found
|
||||||
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos;
|
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos;
|
||||||
if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) {
|
if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) {
|
||||||
msg(usprintf("%s: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fsysHeader->Size), index);
|
msg(usprintf("%s: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fsysHeader->Size), index);
|
||||||
@ -587,7 +586,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_EVSA_STORE_SIGNATURE) { //EVSA signature found
|
else if (readUnaligned(currentPos) == NVRAM_EVSA_STORE_SIGNATURE) { //EVSA signature found
|
||||||
if (offset < sizeof(UINT32))
|
if (offset < sizeof(UINT32))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -604,7 +603,8 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
offset -= sizeof(UINT32);
|
offset -= sizeof(UINT32);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *currentPos == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { // Possible FTW block signature found
|
else if (readUnaligned(currentPos) == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1
|
||||||
|
|| readUnaligned(currentPos) == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { // Possible FTW block signature found
|
||||||
UByteArray guid = UByteArray(volume.constData() + offset, sizeof(EFI_GUID));
|
UByteArray guid = UByteArray(volume.constData() + offset, sizeof(EFI_GUID));
|
||||||
if (guid != NVRAM_MAIN_STORE_VOLUME_GUID && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID && guid != VSS2_WORKING_BLOCK_SIGNATURE_GUID) // Check the whole signature
|
if (guid != NVRAM_MAIN_STORE_VOLUME_GUID && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID && guid != VSS2_WORKING_BLOCK_SIGNATURE_GUID) // Check the whole signature
|
||||||
continue;
|
continue;
|
||||||
@ -630,7 +630,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) {// Phoenix SCT flash map
|
else if (readUnaligned(currentPos) == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) {// Phoenix SCT flash map
|
||||||
UByteArray signature = UByteArray(volume.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH);
|
UByteArray signature = UByteArray(volume.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH);
|
||||||
if (signature != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE) // Check the whole signature
|
if (signature != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE) // Check the whole signature
|
||||||
continue;
|
continue;
|
||||||
@ -638,7 +638,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
else if (readUnaligned(currentPos) == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
||||||
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)currentPos;
|
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)currentPos;
|
||||||
|
|
||||||
// Check size
|
// Check size
|
||||||
@ -648,7 +648,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == INTEL_MICROCODE_HEADER_VERSION_1) {// Intel microcode
|
else if (readUnaligned(currentPos) == INTEL_MICROCODE_HEADER_VERSION_1) {// Intel microcode
|
||||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
|
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
|
||||||
|
|
||||||
// TotalSize is greater then DataSize and is multiple of 1024
|
// TotalSize is greater then DataSize and is multiple of 1024
|
||||||
@ -659,7 +659,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
// All checks passed, store found
|
// All checks passed, store found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
else if (readUnaligned(currentPos) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
||||||
if (offset < 4 * sizeof(UINT32))
|
if (offset < 4 * sizeof(UINT32))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
|
|||||||
offset -= 4 * sizeof(UINT32);
|
offset -= 4 * sizeof(UINT32);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*currentPos == OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1) { // SLIC marker
|
else if (readUnaligned(currentPos) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1) { // SLIC marker
|
||||||
if (offset < 26
|
if (offset < 26
|
||||||
|| offset >= dataSize - sizeof(UINT64)
|
|| offset >= dataSize - sizeof(UINT64)
|
||||||
|| *(const UINT64*)currentPos != OEM_ACTIVATION_MARKER_WINDOWS_FLAG) // Check full windows flag and structure size
|
|| *(const UINT64*)currentPos != OEM_ACTIVATION_MARKER_WINDOWS_FLAG) // Check full windows flag and structure size
|
||||||
@ -1504,12 +1504,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
|
|||||||
else { // Add GUID and text for valid variables
|
else { // Add GUID and text for valid variables
|
||||||
name = guidToUString(readUnaligned(variableGuid));
|
name = guidToUString(readUnaligned(variableGuid));
|
||||||
info += UString("Variable GUID: ") + guidToUString(readUnaligned(variableGuid), false) + "\n";
|
info += UString("Variable GUID: ") + guidToUString(readUnaligned(variableGuid), false) + "\n";
|
||||||
|
text = uFromUcs2((const char*)variableName);
|
||||||
#if QT_VERSION_MAJOR >= 6
|
|
||||||
text = UString::fromUtf16((char16_t *)variableName);
|
|
||||||
#else
|
|
||||||
text = UString::fromUtf16(variableName);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
@ -1741,13 +1736,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
|
|||||||
const EVSA_NAME_ENTRY* nameHeader = (const EVSA_NAME_ENTRY*)entryHeader;
|
const EVSA_NAME_ENTRY* nameHeader = (const EVSA_NAME_ENTRY*)entryHeader;
|
||||||
header = data.mid(offset, sizeof(EVSA_NAME_ENTRY));
|
header = data.mid(offset, sizeof(EVSA_NAME_ENTRY));
|
||||||
body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY));
|
body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY));
|
||||||
|
name = uFromUcs2(body.constData());
|
||||||
#if QT_VERSION_MAJOR >= 6
|
|
||||||
name = UString::fromUtf16((const char16_t *)body.constData());
|
|
||||||
#else
|
|
||||||
name = UString::fromUtf16((const CHAR16*)body.constData());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info = UString("Name: ") + name
|
info = UString("Name: ") + name
|
||||||
+ usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
|
+ usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
|
||||||
variableSize, variableSize,
|
variableSize, variableSize,
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if defined(QT_CORE_LIB)
|
#if defined(QT_CORE_LIB)
|
||||||
@ -104,3 +106,19 @@ UString urepeated(char c, int len)
|
|||||||
return UString(c, len);
|
return UString(c, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UString uFromUcs2(const char* str, size_t max_len)
|
||||||
|
{
|
||||||
|
// Naive implementation assuming that only ASCII LE part of UCS2 is used, str may not be aligned.
|
||||||
|
UString msg;
|
||||||
|
const char *str8 = str;
|
||||||
|
size_t rest = (max_len == 0) ? SIZE_MAX : max_len;
|
||||||
|
if (max_len == 0) {
|
||||||
|
while (str8[0] && rest) {
|
||||||
|
msg += str8[0];
|
||||||
|
str8 += 2;
|
||||||
|
rest--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
@ -29,5 +29,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
UString usprintf(const char* fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2);
|
UString usprintf(const char* fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2);
|
||||||
UString urepeated(char c, int len);
|
UString urepeated(char c, int len);
|
||||||
|
UString uFromUcs2(const char* str, size_t max_len = 0);
|
||||||
|
|
||||||
#endif // USTRING_H
|
#endif // USTRING_H
|
||||||
|
Loading…
Reference in New Issue
Block a user