Network: Use QFile::encodeName for POSIX paths instead of toLatin1

POSIX API doesn't really have defined encoding and kernel works with
null-terminated byte strings (char *) without any knowledge about
encodings.

But usually applications use LANG (and LC_*) as encoding making it
possible to use any encoding user wishes, including full Unicode
support when UTF-8 is used.

This allows to create and listen to sockets with paths containing
non-latin characters.
eg. listen(QString("/run/υποδοχή"));

Change-Id: I022ac6a8a4575103125c48768a66bef88a232a2a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Dāvis Mosāns <davispuh@gmail.com>
This commit is contained in:
Dāvis Mosāns 2015-08-27 00:50:11 +03:00
parent bb281eea17
commit e18554d4f7
2 changed files with 15 additions and 14 deletions

View File

@ -85,7 +85,8 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
}
serverName = requestedServerName;
QString tempPath;
QByteArray encodedTempPath;
const QByteArray encodedFullServerName = QFile::encodeName(fullServerName);
QScopedPointer<QTemporaryDir> tempDir;
// Check any of the flags
@ -96,8 +97,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
setError(QLatin1String("QLocalServer::listen"));
return false;
}
tempPath = tempDir->path();
tempPath += QLatin1String("/s");
encodedTempPath = QFile::encodeName(tempDir->path() + QLatin1String("/s"));
}
// create the unix socket
@ -111,23 +111,23 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
// Construct the unix address
struct ::sockaddr_un addr;
addr.sun_family = PF_UNIX;
if (sizeof(addr.sun_path) < (uint)fullServerName.toLatin1().size() + 1) {
if (sizeof(addr.sun_path) < (uint)encodedFullServerName.size() + 1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;
}
if (socketOptions & QLocalServer::WorldAccessOption) {
if (sizeof(addr.sun_path) < (uint)tempPath.toLatin1().size() + 1) {
if (sizeof(addr.sun_path) < (uint)encodedTempPath.size() + 1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;
}
::memcpy(addr.sun_path, tempPath.toLatin1().data(),
tempPath.toLatin1().size() + 1);
::memcpy(addr.sun_path, encodedTempPath.constData(),
encodedTempPath.size() + 1);
} else {
::memcpy(addr.sun_path, fullServerName.toLatin1().data(),
fullServerName.toLatin1().size() + 1);
::memcpy(addr.sun_path, encodedFullServerName.constData(),
encodedFullServerName.size() + 1);
}
// bind
@ -165,13 +165,13 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
if (socketOptions & QLocalServer::OtherAccessOption)
mode |= S_IRWXO;
if (::chmod(tempPath.toLatin1(), mode) == -1) {
if (::chmod(encodedTempPath.constData(), mode) == -1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;
}
if (::rename(tempPath.toLatin1(), fullServerName.toLatin1()) == -1) {
if (::rename(encodedTempPath.constData(), encodedFullServerName.constData()) == -1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;

View File

@ -268,15 +268,16 @@ void QLocalSocketPrivate::_q_connectToSocket()
connectingPathName += QLatin1Char('/') + connectingName;
}
const QByteArray encodedConnectingPathName = QFile::encodeName(connectingPathName);
struct sockaddr_un name;
name.sun_family = PF_UNIX;
if (sizeof(name.sun_path) < (uint)connectingPathName.toLatin1().size() + 1) {
if (sizeof(name.sun_path) < (uint)encodedConnectingPathName.size() + 1) {
QString function = QLatin1String("QLocalSocket::connectToServer");
errorOccurred(QLocalSocket::ServerNotFoundError, function);
return;
}
::memcpy(name.sun_path, connectingPathName.toLatin1().data(),
connectingPathName.toLatin1().size() + 1);
::memcpy(name.sun_path, encodedConnectingPathName.constData(),
encodedConnectingPathName.size() + 1);
if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) {
QString function = QLatin1String("QLocalSocket::connectToServer");
switch (errno)