QStorageInfo: Properly decode labels from /dev/disk/by-label

udev encodes the labels for /dev/disk/by-label/ with ID_LABEL_FS_ENC
which is done with blkid_encode_string(). This function encodes some
unsafe 1-byte utf-8 characters as hex (e.g. '\' or ' ')

Task-number: QTBUG-61420
Change-Id: If82f4381d348acf9008b79ec5ac7c55e6d3819de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Christian Ehrlicher 2017-10-22 21:39:31 +02:00
parent acdb334032
commit 8f1277da8c

View File

@ -544,6 +544,38 @@ void QStorageInfoPrivate::initRootPath()
}
}
#ifdef Q_OS_LINUX
// udev encodes the labels with ID_LABEL_FS_ENC which is done with
// blkid_encode_string(). Within this function some 1-byte utf-8
// characters not considered safe (e.g. '\' or ' ') are encoded as hex
static QString decodeFsEncString(const QString &str)
{
QString decoded;
decoded.reserve(str.size());
int i = 0;
while (i < str.size()) {
if (i <= str.size() - 4) { // we need at least four characters \xAB
if (str.at(i) == QLatin1Char('\\') &&
str.at(i+1) == QLatin1Char('x')) {
bool bOk;
const int code = str.midRef(i+2, 2).toInt(&bOk, 16);
// only decode characters between 0x20 and 0x7f but not
// the backslash to prevent collisions
if (bOk && code >= 0x20 && code < 0x80 && code != '\\') {
decoded += QChar(code);
i += 4;
continue;
}
}
}
decoded += str.at(i);
++i;
}
return decoded;
}
#endif
static inline QString retrieveLabel(const QByteArray &device)
{
#ifdef Q_OS_LINUX
@ -557,7 +589,7 @@ static inline QString retrieveLabel(const QByteArray &device)
it.next();
QFileInfo fileInfo(it.fileInfo());
if (fileInfo.isSymLink() && fileInfo.symLinkTarget() == devicePath)
return fileInfo.fileName();
return decodeFsEncString(fileInfo.fileName());
}
#elif defined Q_OS_HAIKU
fs_info fsInfo;