summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-12-29 15:56:33 +0100
committerLars Knoll <lars.knoll@qt.io>2017-12-30 12:09:53 +0100
commitdb92f2f3aac60218756a1aa8811cf192acc0b0e6 (patch)
treef28a47aebb2f08e221fe7bffafce62a0a96cf7fd /src/corelib/io
parentdd61a1d98ea9fbffeaf0e2adcd0ddd58105f6a75 (diff)
parent44da5b863597e761df3545dc7ff02a9b53bbb13d (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: .qmake.conf mkspecs/win32-g++/qmake.conf src/corelib/global/qglobal_p.h src/corelib/global/qoperatingsystemversion_p.h src/corelib/io/qfilesystemengine_win.cpp src/network/bearer/qbearerengine.cpp src/platformsupport/input/libinput/qlibinputpointer.cpp src/sql/doc/snippets/code/doc_src_sql-driver.cpp src/widgets/kernel/qwidget_p.h src/widgets/kernel/qwidgetwindow.cpp src/widgets/styles/qfusionstyle.cpp tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp Change-Id: I80e2722f481b12fff5d967c28f89208c0e9a1dd8
Diffstat (limited to 'src/corelib/io')
-rwxr-xr-x[-rw-r--r--]src/corelib/io/qfilesystemengine_win.cpp64
-rw-r--r--src/corelib/io/qloggingregistry.cpp4
-rw-r--r--src/corelib/io/qloggingregistry_p.h2
-rw-r--r--src/corelib/io/qurl.cpp110
4 files changed, 163 insertions, 17 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 944ca232ee..fadc058110 100644..100755
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -160,6 +160,7 @@ static TRUSTEE_W currentUserTrusteeW;
static TRUSTEE_W worldTrusteeW;
static PSID currentUserSID = 0;
static PSID worldSID = 0;
+static HANDLE currentUserImpersonatedToken = nullptr;
QT_BEGIN_NAMESPACE
@@ -180,6 +181,11 @@ GlobalSid::~GlobalSid()
::FreeSid(worldSID);
worldSID = 0;
}
+
+ if (currentUserImpersonatedToken) {
+ ::CloseHandle(currentUserImpersonatedToken);
+ currentUserImpersonatedToken = nullptr;
+ }
}
GlobalSid::GlobalSid()
@@ -210,6 +216,12 @@ GlobalSid::GlobalSid()
::CloseHandle(token);
}
+ token = nullptr;
+ if (::OpenProcessToken(hnd, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &token)) {
+ ::DuplicateToken(token, SecurityImpersonation, &currentUserImpersonatedToken);
+ ::CloseHandle(token);
+ }
+
{
// Create TRUSTEE for Everyone (World)
SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY };
@@ -724,15 +736,49 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
ACCESS_MASK access_mask;
TRUSTEE_W trustee;
if (what & QFileSystemMetaData::UserPermissions) { // user
- data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
- if (GetEffectiveRightsFromAcl(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
- access_mask = (ACCESS_MASK)-1;
- if(access_mask & ReadMask)
- data.entryFlags |= QFileSystemMetaData::UserReadPermission;
- if(access_mask & WriteMask)
- data.entryFlags|= QFileSystemMetaData::UserWritePermission;
- if(access_mask & ExecMask)
- data.entryFlags|= QFileSystemMetaData::UserExecutePermission;
+ // Using AccessCheck because GetEffectiveRightsFromAcl doesn't account for elevation
+ if (currentUserImpersonatedToken) {
+ GENERIC_MAPPING mapping = {FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS};
+ PRIVILEGE_SET privileges;
+ DWORD grantedAccess;
+ BOOL result;
+
+ data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
+ DWORD genericAccessRights = GENERIC_READ;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+
+ DWORD privilegesLength = sizeof(privileges);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserReadPermission;
+ }
+
+ privilegesLength = sizeof(privileges);
+ genericAccessRights = GENERIC_WRITE;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserWritePermission;
+ }
+
+ privilegesLength = sizeof(privileges);
+ genericAccessRights = GENERIC_EXECUTE;
+ ::MapGenericMask(&genericAccessRights, &mapping);
+ if (::AccessCheck(pSD, currentUserImpersonatedToken, genericAccessRights,
+ &mapping, &privileges, &privilegesLength, &grantedAccess, &result) && result) {
+ data.entryFlags |= QFileSystemMetaData::UserExecutePermission;
+ }
+ } else { // fallback to GetEffectiveRightsFromAcl
+ data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
+ if (GetEffectiveRightsFromAclW(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
+ access_mask = ACCESS_MASK(-1);
+ if (access_mask & ReadMask)
+ data.entryFlags |= QFileSystemMetaData::UserReadPermission;
+ if (access_mask & WriteMask)
+ data.entryFlags|= QFileSystemMetaData::UserWritePermission;
+ if (access_mask & ExecMask)
+ data.entryFlags|= QFileSystemMetaData::UserExecutePermission;
+ }
}
if (what & QFileSystemMetaData::OwnerPermissions) { // owner
data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions;
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 1bf61017f6..b5f8e30b80 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -255,7 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
QLoggingRegistry::QLoggingRegistry()
: categoryFilter(defaultCategoryFilter)
{
- initalizeRules(); // Init on first use
+ initializeRules(); // Init on first use
}
static bool qtLoggingDebug()
@@ -284,7 +284,7 @@ static QVector<QLoggingRule> loadRulesFromFile(const QString &filePath)
Initializes the rules database by loading
$QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini.
*/
-void QLoggingRegistry::initalizeRules()
+void QLoggingRegistry::initializeRules()
{
QVector<QLoggingRule> er, qr, cr;
// get rules from environment
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index a3857d3588..12a1f166b3 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry
public:
QLoggingRegistry();
- void initalizeRules();
+ void initializeRules();
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
void unregisterCategory(QLoggingCategory *category);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index cf7ed130ba..4587b9fcd6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -90,11 +90,6 @@
fromPercentEncoding() and toPercentEncoding() which deal with
percent encoding and decoding of QString objects.
- Calling isRelative() will tell whether or not the URL is
- relative. A relative URL can be resolved by passing it as argument
- to resolved(), which returns an absolute URL. isParentOf() is used
- for determining whether one URL is a parent of another.
-
fromLocalFile() constructs a QUrl by parsing a local
file path. toLocalFile() converts a URL to a local file path.
@@ -116,6 +111,37 @@
from freedesktop.org, provided that the locale encodes file names using
UTF-8 (required by IDN).
+ \section2 Relative URLs vs Relative Paths
+
+ Calling isRelative() will return whether or not the URL is relative.
+ A relative URL has no \l {scheme}. For example:
+
+ \code
+ qDebug() << QUrl("main.qml").isRelative(); // true: no scheme
+ qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme
+ qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme
+ qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme
+ \endcode
+
+ Notice that a URL can be absolute while containing a relative path, and
+ vice versa:
+
+ \code
+ // Absolute URL, relative path
+ QUrl url("file:file.txt");
+ qDebug() << url.isRelative(); // false: has "file" scheme
+ qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path
+
+ // Relative URL, absolute path
+ url = QUrl("/home/user/file.txt");
+ qDebug() << url.isRelative(); // true: has no scheme
+ qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path
+ \endcode
+
+ A relative URL can be resolved by passing it as an argument to resolved(),
+ which returns an absolute URL. isParentOf() is used for determining whether
+ one URL is a parent of another.
+
\section2 Error checking
QUrl is capable of detecting many errors in URLs while parsing it or when
@@ -2539,6 +2565,12 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
/*!
Returns the path of the URL.
+ \code
+ qDebug() << QUrl("file:file.txt").path(); // "file.txt"
+ qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt"
+ qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123"
+ \endcode
+
The \a options argument controls how to format the path component. All
values produce an unambiguous result. With QUrl::FullyDecoded, all
percent-encoded sequences are decoded; otherwise, the returned value may
@@ -2549,6 +2581,31 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
sequences are present. It is recommended to use that value when the result
will be used in a non-URL context, such as sending to an FTP server.
+ An example of data loss is when you have non-Unicode percent-encoded sequences
+ and use FullyDecoded (the default):
+
+ \code
+ qDebug() << QUrl("/foo%FFbar").path();
+ \endcode
+
+ In this example, there will be some level of data loss because the \c %FF cannot
+ be converted.
+
+ Data loss can also occur when the path contains sub-delimiters (such as \c +):
+
+ \code
+ qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+"
+ \endcode
+
+ Other decoding examples:
+
+ \code
+ const QUrl url("/tmp/Mambo %235%3F.mp3");
+ qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3"
+ qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3"
+ qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3"
+ \endcode
+
\sa setPath()
*/
QString QUrl::path(ComponentFormattingOptions options) const
@@ -3257,6 +3314,8 @@ QUrl QUrl::resolved(const QUrl &relative) const
equivalent to calling scheme().isEmpty().
Relative references are defined in RFC 3986 section 4.2.
+
+ \sa {Relative URLs vs Relative Paths}
*/
bool QUrl::isRelative() const
{
@@ -3796,6 +3855,41 @@ bool QUrl::isDetached() const
An empty \a localFile leads to an empty URL (since Qt 5.4).
+ \code
+ qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt")
+ qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt")
+ qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme
+ \endcode
+
+ In the first line in snippet above, a file URL is constructed from a
+ local, relative path. A file URL with a relative path only makes sense
+ if there is a base URL to resolve it against. For example:
+
+ \code
+ QUrl url = QUrl::fromLocalFile("file.txt");
+ QUrl baseUrl = QUrl("file:/home/user/");
+ // wrong: prints QUrl("file:file.txt"), as url already has a scheme
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
+ To resolve such a URL, it's necessary to remove the scheme beforehand:
+
+ \code
+ // correct: prints QUrl("file:///home/user/file.txt")
+ url.setScheme(QString());
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
+ For this reason, it is better to use a relative URL (that is, no scheme)
+ for relative file paths:
+
+ \code
+ QUrl url = QUrl("file.txt");
+ QUrl baseUrl = QUrl("file:/home/user/");
+ // prints QUrl("file:///home/user/file.txt")
+ qDebug() << baseUrl.resolved(url);
+ \endcode
+
\sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators()
*/
QUrl QUrl::fromLocalFile(const QString &localFile)
@@ -3840,6 +3934,12 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
returned value in the form found on SMB networks (for example,
"//servername/path/to/file.txt").
+ \code
+ qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt"
+ qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt"
+ qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme
+ \endcode
+
Note: if the path component of this URL contains a non-UTF-8 binary
sequence (such as %80), the behaviour of this function is undefined.