summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/avx512/avx512.cpp29
-rw-r--r--config.tests/avx512/avx512.pro2
-rw-r--r--config.tests/common/aesni/aesni.cpp49
-rw-r--r--config.tests/common/aesni/aesni.pro3
-rw-r--r--config.tests/common/rdrnd/rdrnd.cpp56
-rw-r--r--config.tests/common/rdrnd/rdrnd.pro3
-rw-r--r--config.tests/common/shani/shani.cpp50
-rw-r--r--config.tests/common/shani/shani.pro3
-rw-r--r--config.tests/x86_simd/main.cpp253
-rw-r--r--config.tests/x86_simd/x86_simd.pro11
-rw-r--r--configure.json183
-rw-r--r--configure.pri23
-rw-r--r--mkspecs/common/msvc-version.conf14
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp235
-rw-r--r--src/corelib/kernel/qsystemerror_p.h52
-rw-r--r--src/corelib/mimetypes/mimetypes.qrc2
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp235
-rw-r--r--src/corelib/mimetypes/qmimedatabase_p.h27
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp5
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern_p.h2
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp2
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp521
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h64
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp23
-rw-r--r--src/corelib/mimetypes/qmimetype_p.h3
-rw-r--r--src/corelib/mimetypes/qmimetypeparser.cpp1
-rw-r--r--src/corelib/tools/qsimd_p.h6
-rw-r--r--src/gui/kernel/qplatformtheme.cpp3
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm3
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp20
-rw-r--r--tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro3
-rw-r--r--tests/auto/network/ssl/qsslcertificate/qsslcertificate.qrc79
-rw-r--r--tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp222
-rw-r--r--tests/auto/network/ssl/qsslkey/qsslkey.pro3
-rw-r--r--tests/auto/network/ssl/qsslkey/qsslkey.qrc65
-rw-r--r--tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp16
-rw-r--r--tests/auto/network/ssl/qsslsocket/qsslsocket.pro3
-rw-r--r--tests/auto/network/ssl/qsslsocket/qsslsocket.qrc21
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp138
39 files changed, 1448 insertions, 985 deletions
diff --git a/config.tests/avx512/avx512.cpp b/config.tests/avx512/avx512.cpp
index ca1a5d1357..29e88ebf15 100644
--- a/config.tests/avx512/avx512.cpp
+++ b/config.tests/avx512/avx512.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the configuration of the Qt Toolkit.
@@ -39,15 +39,18 @@
#include <immintrin.h>
-#ifndef AVX512WANT
-# error ".pro file must define AVX512WANT macro to the AVX-512 feature to be tested"
+#ifndef __AVX512F__
+# error "There doesn't seem to be AVX-512 support in this compiler"
+#endif
+#ifndef WANT_AVX512
+# error ".pro file must define WANT_AVX512 macro to the AVX-512 feature to be tested"
#endif
// The following checks if __AVXx__ is defined, where x is the value in
-// AVX512WANT
+// WANT_AVX512
#define HAS2(x) __AVX512 ## x ## __
#define HAS(x) HAS2(x)
-#if !HAS(AVX512WANT)
+#if !HAS(WANT_AVX512)
# error "Feature not supported"
#endif
@@ -62,36 +65,36 @@ int main(int, char**argv)
d = _mm512_loadu_pd((double *)argv + 64);
f = _mm512_loadu_ps((float *)argv + 128);
-#ifdef __AVX512ER__
+#ifdef WANT_AVX512ER
/* AVX512 Exponential and Reciprocal */
f = _mm512_exp2a23_round_ps(f, 8);
#endif
-#ifdef __AVX512CD__
+#ifdef WANT_AVX512CD
/* AVX512 Conflict Detection */
i = _mm512_maskz_conflict_epi32(m, i);
#endif
-#ifdef __AVX512PF__
+#ifdef WANT_AVX512PF
/* AVX512 Prefetch */
_mm512_mask_prefetch_i64scatter_pd(argv, 0xf, i, 2, 2);
#endif
-#ifdef __AVX512DQ__
+#ifdef WANT_AVX512DQ
/* AVX512 Doubleword and Quadword support */
m = _mm512_movepi32_mask(i);
#endif
-#ifdef __AVX512BW__
+#ifdef WANT_AVX512BW
/* AVX512 Byte and Word support */
i = _mm512_mask_loadu_epi8(i, m, argv - 8);
#endif
-#ifdef __AVX512VL__
+#ifdef WANT_AVX512VL
/* AVX512 Vector Length */
__m256i i2 = _mm256_maskz_loadu_epi32(0, argv);
_mm256_mask_storeu_epi32(argv + 1, m, i2);
#endif
-#ifdef __AVX512IFMA__
+#ifdef WANT_AVX512IFMA
/* AVX512 Integer Fused Multiply-Add */
i = _mm512_madd52lo_epu64(i, i, i);
#endif
-#ifdef __AVX512VBMI__
+#ifdef WANT_AVX512VBMI
/* AVX512 Vector Byte Manipulation Instructions */
i = _mm512_permutexvar_epi8(i, i);
#endif
diff --git a/config.tests/avx512/avx512.pro b/config.tests/avx512/avx512.pro
index 1edf5e5432..d295f6320c 100644
--- a/config.tests/avx512/avx512.pro
+++ b/config.tests/avx512/avx512.pro
@@ -7,4 +7,4 @@ value = $$eval($$varname)
!defined($$varname, "var"): error("This compiler does not support AVX512")
QMAKE_CXXFLAGS += $$value
-DEFINES += AVX512WANT=$$AVX512
+DEFINES += WANT_AVX512=$$AVX512 WANT_AVX512$$AVX512
diff --git a/config.tests/common/aesni/aesni.cpp b/config.tests/common/aesni/aesni.cpp
deleted file mode 100644
index a177183c72..0000000000
--- a/config.tests/common/aesni/aesni.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the config.tests of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <wmmintrin.h>
-
-int main(int, char**)
-{
- __m128i a = _mm_setzero_si128();
- __m128i b = _mm_aesenc_si128(a, a);
- __m128i c = _mm_aesdec_si128(a, b);
- (void)c;
- return 0;
-}
diff --git a/config.tests/common/aesni/aesni.pro b/config.tests/common/aesni/aesni.pro
deleted file mode 100644
index 49cb132ef7..0000000000
--- a/config.tests/common/aesni/aesni.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = aesni.cpp
-!defined(QMAKE_CFLAGS_AESNI, "var"): error("This compiler does not support AES New Instructions")
-else: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AESNI
diff --git a/config.tests/common/rdrnd/rdrnd.cpp b/config.tests/common/rdrnd/rdrnd.cpp
deleted file mode 100644
index 597f7257bf..0000000000
--- a/config.tests/common/rdrnd/rdrnd.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the config.tests of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <immintrin.h>
-
-int main(int, char**)
-{
- unsigned short us;
- unsigned int ui;
- if (_rdrand16_step(&us))
- return 1;
- if (_rdrand32_step(&ui))
- return 1;
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
- unsigned long long ull;
- if (_rdrand64_step(&ull))
- return 1;
-#endif
- return 0;
-}
diff --git a/config.tests/common/rdrnd/rdrnd.pro b/config.tests/common/rdrnd/rdrnd.pro
deleted file mode 100644
index 37e636dc3f..0000000000
--- a/config.tests/common/rdrnd/rdrnd.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES += rdrnd.cpp
-!defined(QMAKE_CFLAGS_RDRND, "var"): error("This compiler does not support the RDRAND instruction")
-else: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_RDRND
diff --git a/config.tests/common/shani/shani.cpp b/config.tests/common/shani/shani.cpp
deleted file mode 100644
index 0fe6e87dd8..0000000000
--- a/config.tests/common/shani/shani.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the config.tests of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <immintrin.h>
-
-int main(int, char**)
-{
- __m128i a = _mm_setzero_si128();
- __m128i b = _mm_sha1rnds4_epu32(a, a, 0);
- __m128i c = _mm_sha1msg1_epu32(a, b);
- __m128i d = _mm_sha256msg2_epu32(b, c);
- (void)d;
- return 0;
-}
diff --git a/config.tests/common/shani/shani.pro b/config.tests/common/shani/shani.pro
deleted file mode 100644
index 278f49ef90..0000000000
--- a/config.tests/common/shani/shani.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = shani.cpp
-!defined(QMAKE_CFLAGS_SHANI, "var"): error("This compiler does not support Secure Hash Algorithm extensions")
-else: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SHANI
diff --git a/config.tests/x86_simd/main.cpp b/config.tests/x86_simd/main.cpp
new file mode 100644
index 0000000000..8120cb9d3f
--- /dev/null
+++ b/config.tests/x86_simd/main.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// All of our supported compilers support <immintrin.h>
+#include <immintrin.h>
+#define T(x) (QT_COMPILER_SUPPORTS_ ## x)
+
+#if !defined(__INTEL_COMPILER) && !defined(_MSC_VER) && !defined(NO_ATTRIBUTE)
+/* GCC requires attributes for a function */
+# define attribute_target(x) __attribute__((__target__(x)))
+#else
+# define attribute_target(x)
+#endif
+
+#if T(SSE2)
+attribute_target("sse2") void test_sse2()
+{
+ __m128i a = _mm_setzero_si128();
+ _mm_maskmoveu_si128(a, _mm_setzero_si128(), 0);
+}
+#endif
+
+#if T(SSE3)
+attribute_target("sse3") void test_sse3()
+{
+ __m128d a = _mm_set1_pd(6.28);
+ __m128d b = _mm_set1_pd(3.14);
+ __m128d result = _mm_addsub_pd(a, b);
+ (void) _mm_movedup_pd(result);
+}
+#endif
+
+#if T(SSSE3)
+attribute_target("ssse3") void test_ssse3()
+{
+ __m128i a = _mm_set1_epi32(42);
+ _mm_abs_epi8(a);
+ (void) _mm_sign_epi16(a, _mm_set1_epi32(64));
+}
+#endif
+
+#if T(SSE4_1)
+attribute_target("sse4.1") void test_sse4_1()
+{
+ __m128 a = _mm_setzero_ps();
+ _mm_ceil_ps(a);
+ __m128i result = _mm_mullo_epi32(_mm_set1_epi32(42), _mm_set1_epi32(64));
+ (void)result;
+}
+#endif
+
+#if T(SSE4_2)
+attribute_target("sse4.2") void test_sse4_2()
+{
+ __m128i a = _mm_setzero_si128();
+ __m128i b = _mm_set1_epi32(42);
+ (void) _mm_cmpestrm(a, 16, b, 16, 0);
+}
+#endif
+
+#if T(AESNI)
+attribute_target("aes,sse4.2") void test_aesni()
+{
+ __m128i a = _mm_setzero_si128();
+ __m128i b = _mm_aesenc_si128(a, a);
+ __m128i c = _mm_aesdec_si128(a, b);
+ (void)c;
+}
+#endif
+
+#if T(F16C)
+attribute_target("f16c") void test_f16c()
+{
+ __m128i a = _mm_setzero_si128();
+ __m128 b = _mm_cvtph_ps(a);
+ __m256 b256 = _mm256_cvtph_ps(a);
+ (void) _mm_cvtps_ph(b, 0);
+ (void) _mm256_cvtps_ph(b256, 0);
+}
+#endif
+
+#if T(RDRND)
+attribute_target("rdrnd") int test_rdrnd()
+{
+ unsigned short us;
+ unsigned int ui;
+ if (_rdrand16_step(&us))
+ return 1;
+ if (_rdrand32_step(&ui))
+ return 1;
+# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
+ unsigned long long ull;
+ if (_rdrand64_step(&ull))
+ return 1;
+# endif
+}
+#endif
+
+#if T(SHANI)
+attribute_target("sha") void test_shani()
+{
+ __m128i a = _mm_setzero_si128();
+ __m128i b = _mm_sha1rnds4_epu32(a, a, 0);
+ __m128i c = _mm_sha1msg1_epu32(a, b);
+ __m128i d = _mm_sha256msg2_epu32(b, c);
+ (void)d;
+}
+#endif
+
+#if T(AVX)
+attribute_target("avx") void test_avx()
+{
+ __m256d a = _mm256_setzero_pd();
+ __m256d b = _mm256_set1_pd(42.42);
+ (void) _mm256_add_pd(a, b);
+}
+#endif
+
+#if T(AVX2)
+attribute_target("avx2") void test_avx2()
+{
+ _mm256_zeroall();
+ __m256i a = _mm256_setzero_si256();
+ __m256i b = _mm256_and_si256(a, a);
+ (void) _mm256_add_epi8(a, b);
+}
+#endif
+
+#if T(AVX512F)
+attribute_target("avx512f") void test_avx512f(char *ptr)
+{
+ /* AVX512 Foundation */
+ __mmask16 m = ~1;
+ __m512i i;
+ __m512d d;
+ __m512 f;
+ i = _mm512_maskz_loadu_epi32(0, ptr);
+ d = _mm512_loadu_pd((double *)ptr + 64);
+ f = _mm512_loadu_ps((float *)ptr + 128);
+ _mm512_mask_storeu_epi64(ptr, m, i);
+ _mm512_mask_storeu_ps(ptr + 64, m, f);
+ _mm512_mask_storeu_pd(ptr + 128, m, d);
+}
+#endif
+
+#if T(AVX512ER)
+attribute_target("avx512er") void test_avx512er()
+{
+ /* AVX512 Exponential and Reciprocal */
+ __m512 f;
+ f = _mm512_exp2a23_round_ps(f, 8);
+}
+#endif
+
+#if T(AVX512CD)
+attribute_target("avx512cd") void test_avx512cd()
+{
+ /* AVX512 Conflict Detection */
+ __mmask16 m = ~1;
+ __m512i i;
+ i = _mm512_maskz_conflict_epi32(m, i);
+}
+#endif
+
+#if T(AVX512PF)
+attribute_target("avx512pf") void test_avx512pf(void *ptr)
+{
+ /* AVX512 Prefetch */
+ __m512i i;
+ __mmask16 m = 0xf;
+ _mm512_mask_prefetch_i64scatter_pd(ptr, m, i, 2, 2);
+}
+#endif
+
+#if T(AVX512DQ)
+attribute_target("avx512dq") void test_avx512dq()
+{
+ /* AVX512 Doubleword and Quadword support */
+ __m512i i;
+ __mmask16 m = ~1;
+ m = _mm512_movepi32_mask(i);
+}
+#endif
+
+#if T(AVX512BW)
+attribute_target("avx512bw") void test_avx512bw(char *ptr)
+{
+ /* AVX512 Byte and Word support */
+ __m512i i;
+ __mmask16 m = ~1;
+ i = _mm512_mask_loadu_epi8(i, m, ptr - 8);
+}
+#endif
+
+#if T(AVX512VL)
+attribute_target("avx512vl") void test_avx512vl(char *ptr)
+{
+ /* AVX512 Vector Length */
+ __mmask16 m = ~1;
+ __m256i i2 = _mm256_maskz_loadu_epi32(0, ptr);
+ _mm256_mask_storeu_epi32(ptr + 1, m, i2);
+}
+#endif
+
+#if T(AVX512IFMA)
+attribute_target("avx512ifma") void test_avx512ifma()
+{
+ /* AVX512 Integer Fused Multiply-Add */
+ __m512i i;
+ i = _mm512_madd52lo_epu64(i, i, i);
+}
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/config.tests/x86_simd/x86_simd.pro b/config.tests/x86_simd/x86_simd.pro
new file mode 100644
index 0000000000..5751432980
--- /dev/null
+++ b/config.tests/x86_simd/x86_simd.pro
@@ -0,0 +1,11 @@
+SOURCES = main.cpp
+for (config, SIMD) {
+ uc = $$upper($$config)
+ DEFINES += QT_COMPILER_SUPPORTS_$${uc}
+
+ add_cflags {
+ cflags = QMAKE_CFLAGS_$${uc}
+ !defined($$cflags, var): error("This compiler does not support $${uc}")
+ QMAKE_CXXFLAGS += $$eval($$cflags)
+ }
+}
diff --git a/configure.json b/configure.json
index a5a64565e1..a0b9765d18 100644
--- a/configure.json
+++ b/configure.json
@@ -218,7 +218,7 @@
},
"testTypeAliases": {
- "compile": [ "library", "architecture" ]
+ "compile": [ "library", "architecture", "x86Simd", "x86SimdAlways" ]
},
"tests": {
@@ -362,206 +362,88 @@
},
"sse2": {
"label": "SSE2 instructions",
- "type": "compile",
- "test": {
- "include": "emmintrin.h",
- "main": [
- "__m128i a = _mm_setzero_si128();",
- "_mm_maskmoveu_si128(a, _mm_setzero_si128(), 0);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_SSE2, var): error(\"This compiler does not support SSE2\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2"
- ]
- }
+ "type": "x86Simd"
},
"sse3": {
"label": "SSE3 instructions",
- "type": "compile",
- "test": {
- "include": "pmmintrin.h",
- "main": [
- "__m128d a = _mm_set1_pd(6.28);",
- "__m128d b = _mm_set1_pd(3.14);",
- "__m128d result = _mm_addsub_pd(a, b);",
- "(void) _mm_movedup_pd(result);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_SSE3, var): error(\"This compiler does not support SSE3\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE3"
- ]
- }
+ "type": "x86Simd"
},
"ssse3": {
"label": "SSSE3 instructions",
- "type": "compile",
- "test": {
- "include": "tmmintrin.h",
- "main": [
- "__m128i a = _mm_set1_epi32(42);",
- "_mm_abs_epi8(a);",
- "(void) _mm_sign_epi16(a, _mm_set1_epi32(64));"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_SSSE3, var): error(\"This compiler does not support SSSE3\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSSE3"
- ]
- }
+ "type": "x86Simd"
},
"sse4_1": {
"label": "SSE4.1 instructions",
- "type": "compile",
- "test": {
- "include": "smmintrin.h",
- "main": [
- "__m128 a = _mm_setzero_ps();",
- "_mm_ceil_ps(a);",
- "__m128i result = _mm_mullo_epi32(_mm_set1_epi32(42), _mm_set1_epi32(64));",
- "(void)result;"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_SSE4_1, var): error(\"This compiler does not support SSE4.1\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1"
- ]
- }
+ "type": "x86Simd"
},
"sse4_2": {
"label": "SSE4.2 instructions",
- "type": "compile",
- "test": {
- "include": "nmmintrin.h",
- "main": [
- "__m128i a = _mm_setzero_si128();",
- "__m128i b = _mm_set1_epi32(42);",
- "(void) _mm_cmpestrm(a, 16, b, 16, 0);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_SSE4_2, var): error(\"This compiler does not support SSE4.2\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_2"
- ]
- }
+ "type": "x86Simd"
},
"aesni": {
"label": "AES new instructions",
- "type": "compile",
- "test": "common/aesni"
+ "type": "x86Simd"
},
"f16c": {
"label": "F16C instructions",
- "type": "compile",
- "test": {
- "include": "immintrin.h",
- "main": [
- "__m128i a = _mm_setzero_si128();",
- "__m128 b = _mm_cvtph_ps(a);",
- "__m256 b256 = _mm256_cvtph_ps(a);",
- "(void) _mm_cvtps_ph(b, 0);",
- "(void) _mm256_cvtps_ph(b256, 0);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_F16C, var): error(\"This compiler does not support F16C\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_F16C"
- ]
- }
+ "type": "x86Simd"
},
"rdrnd": {
"label": "RDRAND instruction",
- "type": "compile",
- "test": "common/rdrnd"
+ "type": "x86Simd"
},
"shani": {
"label": "SHA new instructions",
- "type": "compile",
- "test": "common/shani"
+ "type": "x86Simd"
},
"avx": {
"label": "AVX instructions",
- "type": "compile",
- "test": {
- "include": "immintrin.h",
- "main": [
- "__m256d a = _mm256_setzero_pd();",
- "__m256d b = _mm256_set1_pd(42.42);",
- "(void) _mm256_add_pd(a, b);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_AVX, var): error(\"This compiler does not support AVX\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX"
- ]
- }
+ "type": "x86Simd"
},
"avx2": {
"label": "AVX2 instructions",
- "type": "compile",
- "test": {
- "include": "immintrin.h",
- "main": [
- "// AVX",
- "_mm256_zeroall();",
- "__m256i a = _mm256_setzero_si256();",
- "// AVX2",
- "__m256i b = _mm256_and_si256(a, a);",
- "(void) _mm256_add_epi8(a, b);"
- ],
- "qmake": [
- "!defined(QMAKE_CFLAGS_AVX2, var): error(\"This compiler does not support AVX2\")",
- "QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2"
- ]
- }
+ "type": "x86Simd"
},
"avx512f": {
"label": "AVX512 F instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=F"
+ "type": "x86Simd"
},
"avx512er": {
"label": "AVX512 ER instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=ER"
+ "type": "x86Simd"
},
"avx512cd": {
"label": "AVX512 CD instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=CD"
+ "type": "x86Simd"
},
"avx512pf": {
"label": "AVX512 PF instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=PF"
+ "type": "x86Simd"
},
"avx512dq": {
"label": "AVX512 DQ instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=DQ"
+ "type": "x86Simd"
},
"avx512bw": {
"label": "AVX512 BW instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=BW"
+ "type": "x86Simd"
},
"avx512vl": {
"label": "AVX512 VL instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=VL"
+ "type": "x86Simd"
},
"avx512ifma": {
"label": "AVX512 IFMA instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=IFMA"
+ "type": "x86Simd"
},
"avx512vbmi": {
"label": "AVX512 VBMI instructions",
- "type": "compile",
- "test": "avx512",
- "args": "AVX512=VBMI"
+ "type": "x86Simd"
+ },
+ "x86SimdAlways": {
+ "label": "Intrinsics without -mXXX argument",
+ "type": "x86SimdAlways",
+ "test": "x86_simd"
},
"mips_dsp": {
"label": "MIPS DSP instructions",
@@ -1111,6 +993,14 @@
{ "type": "define", "name": "QT_COMPILER_SUPPORTS_SHA", "value": 1 }
]
},
+ "x86SimdAlways": {
+ "label": "Intrinsics without -mXXX option",
+ "condition": "(arch.i386 || arch.x86_64) && tests.x86SimdAlways",
+ "output": [
+ "privateConfig",
+ { "type": "define", "name": "QT_COMPILER_SUPPORTS_SIMD_ALWAYS", "value": 1 }
+ ]
+ },
"mips_dsp": {
"label": "DSP",
"condition": "arch.mips && tests.mips_dsp",
@@ -1399,6 +1289,11 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
},
{
"type": "feature",
+ "args": "x86SimdAlways",
+ "condition": "(arch.i386 || arch.x86_64) && !config.msvc"
+ },
+ {
+ "type": "feature",
"args": "neon",
"condition": "arch.arm || arch.arm64"
},
diff --git a/configure.pri b/configure.pri
index 83c0dee141..8ce4aea9ca 100644
--- a/configure.pri
+++ b/configure.pri
@@ -395,6 +395,29 @@ defineTest(qtConfTest_buildParts) {
return(true)
}
+defineTest(qtConfTest_x86Simd) {
+ simd = $$section(1, ".", -1) # last component
+ $${1}.args = CONFIG+=add_cflags DEFINES+=NO_ATTRIBUTE SIMD=$$simd
+ $${1}.test = x86_simd
+ qtConfTest_compile($${1})
+}
+
+defineTest(qtConfTest_x86SimdAlways) {
+ configs =
+ fpfx = $${currentConfig}.features
+ tpfx = $${currentConfig}.tests
+
+ # Make a list of all passing features whose tests have type=x86Simd
+ for (f, $${tpfx}._KEYS_) {
+ !equals($${tpfx}.$${f}.type, "x86Simd"): \
+ next()
+ qtConfCheckFeature($$f)
+ equals($${fpfx}.$${f}.available, true): configs += $$f
+ }
+ $${1}.literal_args = $$system_quote(SIMD=$$join(configs, " "))
+ qtConfTest_compile($${1})
+}
+
# custom outputs
# this reloads the qmakespec as completely as reasonably possible.
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index 395c0535a9..9f5da91806 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -82,6 +82,20 @@ greaterThan(QMAKE_MSC_VER, 1909) {
MSVC_VER = 15.0
COMPAT_MKSPEC = win32-msvc2017
QMAKE_CXXFLAGS += -Zc:referenceBinding
+
+ # Only Visual Studio 2017 version 15.3 / Visual C++ 19.11 & up have support
+ # for AVX-512. We enable the switches anyway and let configure check if they
+ # work.
+ QMAKE_CFLAGS_AVX512F = -arch:AVX512
+ QMAKE_CFLAGS_AVX512ER = -arch:AVX512
+ QMAKE_CFLAGS_AVX512CD = -arch:AVX512
+ QMAKE_CFLAGS_AVX512PF = -arch:AVX512
+ QMAKE_CFLAGS_AVX512DQ = -arch:AVX512
+ QMAKE_CFLAGS_AVX512BW = -arch:AVX512
+ QMAKE_CFLAGS_AVX512VL = -arch:AVX512
+ QMAKE_CFLAGS_AVX512IFMA = -arch:AVX512
+ QMAKE_CFLAGS_AVX512VBMI = -arch:AVX512
+
# For now permissive fails as soon as UWP API comes into play. In qtbase this
# API is used in direct2d, but also in multimedia, positioning and sensors.
# We can try again with a later version of Visual Studio.
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index cdaa6329f9..6d8b6ee1a0 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -45,6 +45,7 @@
#include <QtCore/qtextstream.h>
#include <QtCore/private/qcore_unix_p.h>
+#include <QtCore/private/qlocale_tools_p.h>
#include <errno.h>
#include <sys/stat.h>
@@ -121,6 +122,7 @@ public:
inline QByteArray fileSystemType() const;
inline QByteArray device() const;
inline QByteArray options() const;
+ inline QByteArray subvolume() const;
private:
#if defined(Q_OS_BSD4)
QT_STATFSBUF *stat_buf;
@@ -136,9 +138,36 @@ private:
QByteArray m_device;
QByteArray m_options;
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
+ struct mountinfoent : public mntent {
+ // Details from proc(5) section from /proc/<pid>/mountinfo:
+ //(1) mount ID: a unique ID for the mount (may be reused after umount(2)).
+ int mount_id;
+ //(2) parent ID: the ID of the parent mount (or of self for the top of the mount tree).
+// int parent_id;
+ //(3) major:minor: the value of st_dev for files on this filesystem (see stat(2)).
+// dev_t rdev;
+ //(4) root: the pathname of the directory in the filesystem which forms the root of this mount.
+ char *subvolume;
+ //(5) mount point: the pathname of the mount point relative to the process's root directory.
+// char *mnt_dir; // in mntent
+ //(6) mount options: per-mount options.
+// char *mnt_opts; // in mntent
+ //(7) optional fields: zero or more fields of the form "tag[:value]"; see below.
+// int flags;
+ //(8) separator: the end of the optional fields is marked by a single hyphen.
+
+ //(9) filesystem type: the filesystem type in the form "type[.subtype]".
+// char *mnt_type; // in mntent
+ //(10) mount source: filesystem-specific information or "none".
+// char *mnt_fsname; // in mntent
+ //(11) super options: per-superblock options.
+ char *superopts;
+ };
+
FILE *fp;
- mntent mnt;
QByteArray buffer;
+ mountinfoent mnt;
+ bool usingMountinfo;
#elif defined(Q_OS_HAIKU)
BVolumeRoster m_volumeRoster;
@@ -239,6 +268,10 @@ inline QByteArray QStorageIterator::options() const
return QByteArray();
}
+inline QByteArray QStorageIterator::subvolume() const
+{
+ return QByteArray();
+}
#elif defined(Q_OS_SOLARIS)
static const char pathMounted[] = "/etc/mnttab";
@@ -280,6 +313,10 @@ inline QByteArray QStorageIterator::device() const
return QByteArray(mnt.mnt_mntopts);
}
+inline QByteArray QStorageIterator::subvolume() const
+{
+ return QByteArray();
+}
#elif defined(Q_OS_ANDROID)
static const QLatin1String pathMounted("/proc/mounts");
@@ -337,6 +374,10 @@ inline QByteArray QStorageIterator::options() const
return m_options;
}
+inline QByteArray QStorageIterator::subvolume() const
+{
+ return QByteArray();
+}
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
static const char pathMounted[] = "/etc/mtab";
@@ -346,13 +387,28 @@ static const int bufferSize = 1024; // 2 paths (mount point+device) and metainfo
inline QStorageIterator::QStorageIterator() :
buffer(QByteArray(bufferSize, 0))
{
- fp = ::setmntent(pathMounted, "r");
+ fp = nullptr;
+
+#ifdef Q_OS_LINUX
+ // first, try to open /proc/self/mountinfo, which has more details
+ fp = ::fopen("/proc/self/mountinfo", "re");
+#endif
+ if (fp) {
+ usingMountinfo = true;
+ } else {
+ usingMountinfo = false;
+ fp = ::setmntent(pathMounted, "r");
+ }
}
inline QStorageIterator::~QStorageIterator()
{
- if (fp)
- ::endmntent(fp);
+ if (fp) {
+ if (usingMountinfo)
+ ::fclose(fp);
+ else
+ ::endmntent(fp);
+ }
}
inline bool QStorageIterator::isValid() const
@@ -362,7 +418,127 @@ inline bool QStorageIterator::isValid() const
inline bool QStorageIterator::next()
{
- return ::getmntent_r(fp, &mnt, buffer.data(), buffer.size()) != nullptr;
+ mnt.subvolume = nullptr;
+ mnt.superopts = nullptr;
+ if (!usingMountinfo)
+ return ::getmntent_r(fp, &mnt, buffer.data(), buffer.size()) != nullptr;
+
+ // Helper function to parse paths that the kernel inserts escape sequences
+ // for. The unescaped string is left at \a src and is properly
+ // NUL-terminated. Returns a pointer to the delimiter that terminated the
+ // path, or nullptr if it failed.
+ auto parseMangledPath = [](char *src) {
+ // The kernel escapes with octal the following characters:
+ // space ' ', tab '\t', backslask '\\', and newline '\n'
+ char *dst = src;
+ while (*src) {
+ switch (*src) {
+ case ' ':
+ // Unescaped space: end of the field.
+ *dst = '\0';
+ return src;
+
+ default:
+ *dst++ = *src++;
+ break;
+
+ case '\\':
+ // It always uses exactly three octal characters.
+ ++src;
+ char c = (*src++ - '0') << 6;
+ c |= (*src++ - '0') << 3;
+ c |= (*src++ - '0');
+ *dst++ = c;
+ break;
+ }
+ }
+
+ // Found a NUL before the end of the field.
+ src = nullptr;
+ return src;
+ };
+
+ char *ptr = buffer.data();
+ if (fgets(ptr, buffer.size(), fp) == nullptr)
+ return false;
+
+ size_t len = strlen(buffer.data());
+ if (len == 0)
+ return false;
+ if (ptr[len - 1] == '\n')
+ ptr[len - 1] = '\0';
+
+ // parse the line
+ bool ok;
+ mnt.mnt_freq = 0;
+ mnt.mnt_passno = 0;
+
+ mnt.mount_id = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ if (!ptr || !ok)
+ return false;
+
+ int parent_id = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ Q_UNUSED(parent_id);
+ if (!ptr || !ok)
+ return false;
+
+ int rdevmajor = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ if (!ptr || !ok)
+ return false;
+ if (*ptr != ':')
+ return false;
+ int rdevminor = qstrtoll(ptr + 1, const_cast<const char **>(&ptr), 10, &ok);
+ if (!ptr || !ok)
+ return false;
+ Q_UNUSED(rdevmajor);
+ Q_UNUSED(rdevminor);
+
+ if (*ptr != ' ')
+ return false;
+
+ mnt.subvolume = ++ptr;
+ ptr = parseMangledPath(ptr);
+ if (!ptr)
+ return false;
+
+ // unset a subvolume of "/" -- it's not a *sub* volume
+ if (mnt.subvolume + 1 == ptr)
+ *mnt.subvolume = '\0';
+
+ mnt.mnt_dir = ++ptr;
+ ptr = parseMangledPath(ptr);
+ if (!ptr)
+ return false;
+
+ mnt.mnt_opts = ++ptr;
+ ptr = strchr(ptr, ' ');
+ if (!ptr)
+ return false;
+
+ // we don't parse the flags, so just find the separator
+ if (char *const dashed = strstr(ptr, " - ")) {
+ *ptr = '\0';
+ ptr = dashed + strlen(" - ") - 1;
+ } else {
+ return false;
+ }
+
+ mnt.mnt_type = ++ptr;
+ ptr = strchr(ptr, ' ');
+ if (!ptr)
+ return false;
+ *ptr = '\0';
+
+ mnt.mnt_fsname = ++ptr;
+ ptr = parseMangledPath(ptr);
+ if (!ptr)
+ return false;
+
+ mnt.superopts = ++ptr;
+ ptr += strcspn(ptr, " \n");
+ *ptr = '\0';
+
+ return true;
}
inline QString QStorageIterator::rootPath() const
@@ -382,9 +558,28 @@ inline QByteArray QStorageIterator::device() const
inline QByteArray QStorageIterator::options() const
{
+ // Merge the two options, starting with the superblock options and letting
+ // the per-mount options override.
+ const char *superopts = mnt.superopts;
+
+ // Both mnt_opts and superopts start with "ro" or "rw", so we can skip the
+ // superblock's field (see show_mountinfo() in fs/proc_namespace.c).
+ if (superopts && superopts[0] == 'r') {
+ if (superopts[2] == '\0') // no other superopts besides "ro" / "rw"?
+ superopts = nullptr;
+ else if (superopts[2] == ',')
+ superopts += 3;
+ }
+
+ if (superopts)
+ return QByteArray(superopts) + ',' + mnt.mnt_opts;
return QByteArray(mnt.mnt_opts);
}
+inline QByteArray QStorageIterator::subvolume() const
+{
+ return QByteArray(mnt.subvolume);
+}
#elif defined(Q_OS_HAIKU)
inline QStorageIterator::QStorageIterator()
{
@@ -447,6 +642,10 @@ inline QByteArray QStorageIterator::options() const
return QByteArray();
}
+inline QByteArray QStorageIterator::subvolume() const
+{
+ return QByteArray();
+}
#else
inline QStorageIterator::QStorageIterator()
@@ -487,31 +686,11 @@ inline QByteArray QStorageIterator::options() const
return QByteArray();
}
-#endif
-
-static QByteArray extractSubvolume(const QStorageIterator &it)
+inline QByteArray QStorageIterator::subvolume() const
{
-#ifdef Q_OS_LINUX
- if (it.fileSystemType() == "btrfs") {
- const QByteArrayList opts = it.options().split(',');
- QByteArray id;
- for (const QByteArray &opt : opts) {
- static const char subvol[] = "subvol=";
- static const char subvolid[] = "subvolid=";
- if (opt.startsWith(subvol))
- return std::move(opt).mid(strlen(subvol));
- if (opt.startsWith(subvolid))
- id = std::move(opt).mid(strlen(subvolid));
- }
-
- // if we didn't find the subvolume name, return the subvolume ID
- return id;
- }
-#else
- Q_UNUSED(it);
-#endif
return QByteArray();
}
+#endif
void QStorageInfoPrivate::initRootPath()
{
@@ -539,7 +718,7 @@ void QStorageInfoPrivate::initRootPath()
rootPath = mountDir;
device = it.device();
fileSystemType = fsName;
- subvolume = extractSubvolume(it);
+ subvolume = it.subvolume();
}
}
}
diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h
index 1d8c253f53..abc2f1efc1 100644
--- a/src/corelib/kernel/qsystemerror_p.h
+++ b/src/corelib/kernel/qsystemerror_p.h
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
-class Q_CORE_EXPORT QSystemError
+class QSystemError
{
public:
enum ErrorScope
@@ -66,51 +66,27 @@ public:
NativeError
};
- inline QSystemError(int error, ErrorScope scope);
- inline QSystemError();
+ Q_DECL_CONSTEXPR explicit QSystemError(int error, ErrorScope scope)
+ : errorCode(error), errorScope(scope)
+ {
+ }
+ Q_DECL_CONSTEXPR QSystemError() = default;
- inline QString toString() const;
- inline ErrorScope scope() const;
- inline int error() const;
+ QString toString() const { return string(errorScope, errorCode); }
+ Q_DECL_CONSTEXPR ErrorScope scope() const { return errorScope; }
+ Q_DECL_CONSTEXPR int error() const { return errorCode; }
- static QString string(ErrorScope errorScope, int errorCode);
- static QString stdString(int errorCode = -1);
+ static Q_CORE_EXPORT QString string(ErrorScope errorScope, int errorCode);
+ static Q_CORE_EXPORT QString stdString(int errorCode = -1);
#ifdef Q_OS_WIN
- static QString windowsString(int errorCode = -1);
+ static Q_CORE_EXPORT QString windowsString(int errorCode = -1);
#endif
//data members
- int errorCode;
- ErrorScope errorScope;
+ int errorCode = 0;
+ ErrorScope errorScope = NoError;
};
-QSystemError::QSystemError(int error, QSystemError::ErrorScope scope)
-: errorCode(error), errorScope(scope)
-{
-
-}
-
-QSystemError::QSystemError()
-: errorCode(0), errorScope(NoError)
-{
-
-}
-
-QString QSystemError::toString() const
-{
- return string(errorScope, errorCode);
-}
-
-QSystemError::ErrorScope QSystemError::scope() const
-{
- return errorScope;
-}
-
-int QSystemError::error() const
-{
- return errorCode;
-}
-
QT_END_NAMESPACE
#endif // QSYSTEMERROR_P_H
diff --git a/src/corelib/mimetypes/mimetypes.qrc b/src/corelib/mimetypes/mimetypes.qrc
index f0cf47cd49..19bc1d3e2a 100644
--- a/src/corelib/mimetypes/mimetypes.qrc
+++ b/src/corelib/mimetypes/mimetypes.qrc
@@ -1,5 +1,5 @@
<RCC>
- <qresource prefix="/qt-project.org/qmime">
+ <qresource prefix="/qt-project.org/qmime/packages">
<file alias="freedesktop.org.xml">mime/packages/freedesktop.org.xml</file>
</qresource>
</RCC>
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 687f0b3e03..f90fd12e3b 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -51,6 +51,7 @@
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QSet>
+#include <QtCore/QStandardPaths>
#include <QtCore/QBuffer>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
@@ -69,34 +70,102 @@ QMimeDatabasePrivate *QMimeDatabasePrivate::instance()
}
QMimeDatabasePrivate::QMimeDatabasePrivate()
- : m_provider(0), m_defaultMimeType(QLatin1String("application/octet-stream"))
+ : m_defaultMimeType(QLatin1String("application/octet-stream"))
{
}
QMimeDatabasePrivate::~QMimeDatabasePrivate()
{
- delete m_provider;
- m_provider = 0;
+ qDeleteAll(m_providers);
}
-QMimeProviderBase *QMimeDatabasePrivate::provider()
+Q_CORE_EXPORT int qmime_secondsBetweenChecks = 5; // exported for the unit test
+
+bool QMimeDatabasePrivate::shouldCheck()
+{
+ if (m_lastCheck.isValid() && m_lastCheck.elapsed() < qmime_secondsBetweenChecks * 1000)
+ return false;
+ m_lastCheck.start();
+ return true;
+}
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
+#define QT_USE_MMAP
+#endif
+
+void QMimeDatabasePrivate::loadProviders()
{
- if (!m_provider) {
- QMimeProviderBase *binaryProvider = new QMimeBinaryProvider(this);
- if (binaryProvider->isValid()) {
- m_provider = binaryProvider;
+ // We use QStandardPaths every time to check if new files appeared
+ QStringList mimeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
+ const auto fdoIterator = std::find_if(mimeDirs.constBegin(), mimeDirs.constEnd(), [](const QString &mimeDir) -> bool {
+ return QFileInfo::exists(mimeDir + QStringLiteral("/packages/freedesktop.org.xml")); }
+ );
+ if (fdoIterator == mimeDirs.constEnd())
+ mimeDirs.prepend(QLatin1String(":/qt-project.org/qmime"));
+ //qDebug() << "mime dirs:" << mimeDirs;
+
+ QVector<QMimeProviderBase *> currentProviders = m_providers;
+ m_providers.clear();
+ m_providers.reserve(mimeDirs.size());
+ for (const QString &mimeDir : qAsConst(mimeDirs)) {
+ const QString cacheFile = mimeDir + QStringLiteral("/mime.cache");
+ QFileInfo fileInfo(cacheFile);
+ // Check if we already have a provider for this dir
+ const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), [mimeDir](QMimeProviderBase *prov) { return prov->directory() == mimeDir; });
+ if (it == currentProviders.end()) {
+ QMimeProviderBase *provider = nullptr;
+#if defined(QT_USE_MMAP)
+ if (qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE") && fileInfo.exists()) {
+ provider = new QMimeBinaryProvider(this, mimeDir);
+ //qDebug() << "Created binary provider for" << mimeDir;
+ if (!provider->isValid()) {
+ delete provider;
+ provider = nullptr;
+ }
+ }
+#endif
+ if (!provider) {
+ provider = new QMimeXMLProvider(this, mimeDir);
+ //qDebug() << "Created XML provider for" << mimeDir;
+ }
+ m_providers.append(provider);
} else {
- delete binaryProvider;
- m_provider = new QMimeXMLProvider(this);
+ QMimeProviderBase *provider = *it;
+ currentProviders.erase(it);
+ provider->ensureLoaded();
+ if (!provider->isValid()) {
+ delete provider;
+ provider = new QMimeXMLProvider(this, mimeDir);
+ //qDebug() << "Created XML provider to replace binary provider for" << mimeDir;
+ }
+ m_providers.append(provider);
}
}
- return m_provider;
+ qDeleteAll(currentProviders);
}
-void QMimeDatabasePrivate::setProvider(QMimeProviderBase *theProvider)
+QVector<QMimeProviderBase *> QMimeDatabasePrivate::providers()
{
- delete m_provider;
- m_provider = theProvider;
+ Q_ASSERT(!mutex.tryLock()); // caller should have locked mutex
+ if (m_providers.isEmpty()) {
+ loadProviders();
+ m_lastCheck.start();
+ } else {
+ if (shouldCheck())
+ loadProviders();
+ }
+ return m_providers;
+}
+
+QString QMimeDatabasePrivate::resolveAlias(const QString &nameOrAlias)
+{
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ const QString ret = provider->resolveAlias(nameOrAlias);
+ if (!ret.isEmpty())
+ return ret;
+ }
+ return nameOrAlias;
}
/*!
@@ -105,7 +174,14 @@ void QMimeDatabasePrivate::setProvider(QMimeProviderBase *theProvider)
*/
QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
{
- return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias));
+ const auto allProviders = providers();
+ const QString mimeName = resolveAlias(nameOrAlias);
+ for (QMimeProviderBase *provider : allProviders) {
+ const QMimeType mime = provider->mimeTypeForName(mimeName);
+ if (mime.isValid())
+ return mime;
+ }
+ return {};
}
QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
@@ -113,11 +189,113 @@ QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
if (fileName.endsWith(QLatin1Char('/')))
return QStringList() << QLatin1String("inode/directory");
- QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName()).m_matchingMimeTypes;
+ const QString shortName = QFileInfo(fileName).fileName();
+ const QMimeGlobMatchResult result = findByFileName(shortName);
+ QStringList matchingMimeTypes = result.m_matchingMimeTypes;
matchingMimeTypes.sort(); // make it deterministic
return matchingMimeTypes;
}
+QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileName)
+{
+ QMimeGlobMatchResult result;
+ // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addFileNameMatches(fileName, result);
+ return result;
+}
+
+void QMimeDatabasePrivate::loadMimeTypePrivate(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (!mimePrivate.loaded) { // XML provider sets loaded=true, binary provider does this on demand
+ Q_ASSERT(mimePrivate.fromCache);
+ QMimeBinaryProvider::loadMimeTypePrivate(mimePrivate);
+ }
+}
+
+void QMimeDatabasePrivate::loadGenericIcon(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (mimePrivate.fromCache) {
+ mimePrivate.genericIconName.clear();
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ provider->loadGenericIcon(mimePrivate);
+ if (!mimePrivate.genericIconName.isEmpty())
+ break;
+ }
+ }
+}
+
+void QMimeDatabasePrivate::loadIcon(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (mimePrivate.fromCache) {
+ mimePrivate.iconName.clear();
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ provider->loadIcon(mimePrivate);
+ if (!mimePrivate.iconName.isEmpty())
+ break;
+ }
+ }
+}
+
+static QString fallbackParent(const QString &mimeTypeName)
+{
+ const QStringRef myGroup = mimeTypeName.leftRef(mimeTypeName.indexOf(QLatin1Char('/')));
+ // All text/* types are subclasses of text/plain.
+ if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain"))
+ return QLatin1String("text/plain");
+ // All real-file mimetypes implicitly derive from application/octet-stream
+ if (myGroup != QLatin1String("inode") &&
+ // ignore non-file extensions
+ myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri")
+ && mimeTypeName != QLatin1String("application/octet-stream")) {
+ return QLatin1String("application/octet-stream");
+ }
+ return QString();
+}
+
+QStringList QMimeDatabasePrivate::mimeParents(const QString &mimeName)
+{
+ QMutexLocker locker(&mutex);
+ return parents(mimeName);
+}
+
+QStringList QMimeDatabasePrivate::parents(const QString &mimeName)
+{
+ Q_ASSERT(!mutex.tryLock());
+ QStringList result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addParents(mimeName, result);
+ if (result.isEmpty()) {
+ const QString parent = fallbackParent(mimeName);
+ if (!parent.isEmpty())
+ result.append(parent);
+ }
+ return result;
+}
+
+QStringList QMimeDatabasePrivate::listAliases(const QString &mimeName)
+{
+ QMutexLocker locker(&mutex);
+ QStringList result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addAliases(mimeName, result);
+ return result;
+}
+
+bool QMimeDatabasePrivate::mimeInherits(const QString &mime, const QString &parent)
+{
+ QMutexLocker locker(&mutex);
+ return inherits(mime, parent);
+}
+
static inline bool isTextFile(const QByteArray &data)
{
// UTF16 byte order marks
@@ -145,7 +323,10 @@ QMimeType QMimeDatabasePrivate::findByData(const QByteArray &data, int *accuracy
}
*accuracyPtr = 0;
- QMimeType candidate = provider()->findByMagic(data, accuracyPtr);
+ QMimeType candidate;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->findByMagic(data, accuracyPtr, candidate);
if (candidate.isValid())
return candidate;
@@ -172,7 +353,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
if (fileName.endsWith(QLatin1Char('/')))
candidatesByName.addMatch(QLatin1String("inode/directory"), 100, QString());
else
- candidatesByName = provider()->findByFileName(QFileInfo(fileName).fileName());
+ candidatesByName = findByFileName(QFileInfo(fileName).fileName());
if (candidatesByName.m_allMatchingMimeTypes.count() == 1) {
*accuracyPtr = 100;
const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0));
@@ -222,21 +403,25 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
QList<QMimeType> QMimeDatabasePrivate::allMimeTypes()
{
- return provider()->allMimeTypes();
+ QList<QMimeType> result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addAllMimeTypes(result);
+ return result;
}
bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
{
- const QString resolvedParent = provider()->resolveAlias(parent);
- //Q_ASSERT(provider()->resolveAlias(mime) == mime);
+ const QString resolvedParent = resolveAlias(parent);
std::stack<QString, QStringList> toCheck;
toCheck.push(mime);
while (!toCheck.empty()) {
if (toCheck.top() == resolvedParent)
return true;
- const auto parents = provider()->parents(toCheck.top());
+ const QString mimeName = toCheck.top();
toCheck.pop();
- for (const QString &par : parents)
+ const auto parentList = parents(mimeName);
+ for (const QString &par : parentList)
toCheck.push(par);
}
return false;
@@ -460,7 +645,7 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
QString QMimeDatabase::suffixForFileName(const QString &fileName) const
{
QMutexLocker locker(&d->mutex);
- return d->provider()->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
+ return d->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
}
/*!
@@ -550,6 +735,7 @@ QMimeType QMimeDatabase::mimeTypeForUrl(const QUrl &url) const
*/
QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const
{
+ QMutexLocker locker(&d->mutex);
int accuracy = 0;
const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly);
const QMimeType result = d->mimeTypeForFileNameAndData(fileName, device, &accuracy);
@@ -576,6 +762,7 @@ QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, QIO
*/
QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const
{
+ QMutexLocker locker(&d->mutex);
QBuffer buffer(const_cast<QByteArray *>(&data));
buffer.open(QIODevice::ReadOnly);
int accuracy = 0;
diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
index 3f63f5f103..1c38f46115 100644
--- a/src/corelib/mimetypes/qmimedatabase_p.h
+++ b/src/corelib/mimetypes/qmimedatabase_p.h
@@ -59,7 +59,9 @@
#include "qmimetype_p.h"
#include "qmimeglobpattern_p.h"
+#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -77,22 +79,37 @@ public:
static QMimeDatabasePrivate *instance();
- QMimeProviderBase *provider();
- void setProvider(QMimeProviderBase *theProvider);
-
inline QString defaultMimeType() const { return m_defaultMimeType; }
bool inherits(const QString &mime, const QString &parent);
QList<QMimeType> allMimeTypes();
-
+ QString resolveAlias(const QString &nameOrAlias);
+ QStringList parents(const QString &mimeName);
QMimeType mimeTypeForName(const QString &nameOrAlias);
QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr);
QMimeType findByData(const QByteArray &data, int *priorityPtr);
QStringList mimeTypeForFileName(const QString &fileName);
+ QMimeGlobMatchResult findByFileName(const QString &fileName);
+
+ // API for QMimeType. Takes care of locking the mutex.
+ void loadMimeTypePrivate(QMimeTypePrivate &mimePrivate);
+ void loadGenericIcon(QMimeTypePrivate &mimePrivate);
+ void loadIcon(QMimeTypePrivate &mimePrivate);
+ QStringList mimeParents(const QString &mimeName);
+ QStringList listAliases(const QString &mimeName);
+ bool mimeInherits(const QString &mime, const QString &parent);
- mutable QMimeProviderBase *m_provider;
+private:
+ QVector<QMimeProviderBase *> providers();
+ bool shouldCheck();
+ void loadProviders();
+
+ mutable QVector<QMimeProviderBase *> m_providers;
+ QElapsedTimer m_lastCheck;
+
+public:
const QString m_defaultMimeType;
QMutex mutex;
};
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index a4d2b046fa..e7b2b879a1 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -206,10 +206,9 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
}
}
-QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName) const
+void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const
{
// First try the high weight matches (>50), if any.
- QMimeGlobMatchResult result;
m_highWeightGlobs.match(result, fileName);
// Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
@@ -230,8 +229,6 @@ QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName
// Finally, try the low weight matches (<=50)
m_lowWeightGlobs.match(result, fileName);
-
- return result;
}
void QMimeAllGlobPatterns::clear()
diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h
index 21332e71bc..103729c4ff 100644
--- a/src/corelib/mimetypes/qmimeglobpattern_p.h
+++ b/src/corelib/mimetypes/qmimeglobpattern_p.h
@@ -152,7 +152,7 @@ public:
void addGlob(const QMimeGlobPattern &glob);
void removeMimeType(const QString &mimeType);
- QMimeGlobMatchResult matchingGlobs(const QString &fileName) const;
+ void matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const;
void clear();
PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain"
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 5bbf1bba9d..6356a3581b 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -65,7 +65,7 @@ static const char magicRuleTypes_string[] =
"\0";
static const int magicRuleTypes_indices[] = {
- 0, 8, 15, 22, 29, 35, 41, 50, 59, 65, 0
+ 0, 8, 15, 22, 29, 35, 41, 50, 59, 64, 0
};
QMimeMagicRule::Type QMimeMagicRule::type(const QByteArray &theTypeName)
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index ed7ebb2ef5..ec0a6bf0ef 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -61,46 +61,18 @@ static void initResources()
QT_BEGIN_NAMESPACE
-static QString fallbackParent(const QString &mimeTypeName)
-{
- const QStringRef myGroup = mimeTypeName.leftRef(mimeTypeName.indexOf(QLatin1Char('/')));
- // All text/* types are subclasses of text/plain.
- if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain"))
- return QLatin1String("text/plain");
- // All real-file mimetypes implicitly derive from application/octet-stream
- if (myGroup != QLatin1String("inode") &&
- // ignore non-file extensions
- myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri")
- && mimeTypeName != QLatin1String("application/octet-stream")) {
- return QLatin1String("application/octet-stream");
- }
- return QString();
-}
-
-QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db)
- : m_db(db)
+QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory)
+ : m_db(db), m_directory(directory)
{
}
-Q_CORE_EXPORT int qmime_secondsBetweenChecks = 5; // exported for the unit test
-bool QMimeProviderBase::shouldCheck()
-{
- if (m_lastCheck.isValid() && m_lastCheck.elapsed() < qmime_secondsBetweenChecks * 1000)
- return false;
- m_lastCheck.start();
- return true;
-}
-
-QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db)
- : QMimeProviderBase(db), m_mimetypeListLoaded(false)
+QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
+ : QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
{
+ ensureLoaded();
}
-#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
-#define QT_USE_MMAP
-#endif
-
struct QMimeBinaryProvider::CacheFile
{
CacheFile(const QString &fileName);
@@ -154,7 +126,6 @@ bool QMimeBinaryProvider::CacheFile::load()
bool QMimeBinaryProvider::CacheFile::reload()
{
- //qDebug() << "reload!" << file->fileName();
m_valid = false;
if (file.isOpen()) {
file.close();
@@ -163,18 +134,14 @@ bool QMimeBinaryProvider::CacheFile::reload()
return load();
}
-QMimeBinaryProvider::CacheFile *QMimeBinaryProvider::CacheFileList::findCacheFile(const QString &fileName) const
+QMimeBinaryProvider::~QMimeBinaryProvider()
{
- for (const_iterator it = begin(); it != end(); ++it) {
- if ((*it)->file.fileName() == fileName)
- return *it;
- }
- return 0;
+ delete m_cacheFile;
}
-QMimeBinaryProvider::~QMimeBinaryProvider()
+bool QMimeBinaryProvider::isValid()
{
- qDeleteAll(m_cacheFiles);
+ return m_cacheFile != nullptr;
}
// Position of the "list offsets" values, at the beginning of the mime.cache file
@@ -190,79 +157,33 @@ enum {
PosGenericIconsListOffset = 36
};
-bool QMimeBinaryProvider::isValid()
+bool QMimeBinaryProvider::checkCacheChanged()
{
-#if defined(QT_USE_MMAP)
- if (!qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE"))
- return false;
-
- Q_ASSERT(m_cacheFiles.isEmpty()); // this method is only ever called once
- checkCache();
-
- if (m_cacheFiles.count() > 1)
+ QFileInfo fileInfo(m_cacheFile->file);
+ if (fileInfo.lastModified() > m_cacheFile->m_mtime) {
+ // Deletion can't happen by just running update-mime-database.
+ // But the user could use rm -rf :-)
+ m_cacheFile->reload(); // will mark itself as invalid on failure
return true;
- if (m_cacheFiles.isEmpty())
- return false;
-
- // We found exactly one file; is it the user-modified mimes, or a system file?
- const QString foundFile = m_cacheFiles.constFirst()->file.fileName();
- const QString localCacheFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/mime.cache");
-
- return foundFile != localCacheFile;
-#else
- return false;
-#endif
-}
-
-bool QMimeBinaryProvider::CacheFileList::checkCacheChanged()
-{
- bool somethingChanged = false;
- for (CacheFile *cacheFile : qAsConst(*this)) {
- QFileInfo fileInfo(cacheFile->file);
- if (!fileInfo.exists() || fileInfo.lastModified() > cacheFile->m_mtime) {
- // Deletion can't happen by just running update-mime-database.
- // But the user could use rm -rf :-)
- cacheFile->reload(); // will mark itself as invalid on failure
- somethingChanged = true;
- }
- }
- if (somethingChanged) {
- auto deleteIfNoLongerValid = [](CacheFile *cacheFile) -> bool {
- const bool invalid = !cacheFile->isValid();
- if (invalid)
- delete cacheFile;
- return invalid;
- };
- erase(std::remove_if(begin(), end(), deleteIfNoLongerValid), end());
}
- return somethingChanged;
+ return false;
}
-void QMimeBinaryProvider::checkCache()
+void QMimeBinaryProvider::ensureLoaded()
{
- if (!shouldCheck())
- return;
-
- // First iterate over existing known cache files and check for uptodate
- if (m_cacheFiles.checkCacheChanged())
- m_mimetypeListLoaded = false;
-
- // Then check if new cache files appeared
- const QStringList cacheFileNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/mime.cache"));
- if (cacheFileNames != m_cacheFileNames) {
- for (const QString &cacheFileName : cacheFileNames) {
- CacheFile *cacheFile = m_cacheFiles.findCacheFile(cacheFileName);
- if (!cacheFile) {
- //qDebug() << "new file:" << cacheFileName;
- cacheFile = new CacheFile(cacheFileName);
- if (cacheFile->isValid()) // verify version
- m_cacheFiles.append(cacheFile);
- else
- delete cacheFile;
- }
- }
- m_cacheFileNames = cacheFileNames;
+ if (!m_cacheFile) {
+ const QString cacheFileName = m_directory + QLatin1String("/mime.cache");
+ m_cacheFile = new CacheFile(cacheFileName);
m_mimetypeListLoaded = false;
+ } else {
+ if (checkCacheChanged())
+ m_mimetypeListLoaded = false;
+ else
+ return; // nothing to do
+ }
+ if (!m_cacheFile->isValid()) { // verify existence and version
+ delete m_cacheFile;
+ m_cacheFile = nullptr;
}
}
@@ -270,6 +191,7 @@ static QMimeType mimeTypeForNameUnchecked(const QString &name)
{
QMimeTypePrivate data;
data.name = name;
+ data.fromCache = true;
// The rest is retrieved on demand.
// comment and globPatterns: in loadMimeTypePrivate
// iconName: in loadIcon
@@ -279,7 +201,6 @@ static QMimeType mimeTypeForNameUnchecked(const QString &name)
QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
{
- checkCache();
if (!m_mimetypeListLoaded)
loadMimeTypeList();
if (!m_mimetypeNames.contains(name))
@@ -287,28 +208,23 @@ QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
return mimeTypeForNameUnchecked(name);
}
-QMimeGlobMatchResult QMimeBinaryProvider::findByFileName(const QString &fileName)
+void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
{
- checkCache();
- QMimeGlobMatchResult result;
if (fileName.isEmpty())
- return result;
+ return;
+ Q_ASSERT(m_cacheFile);
const QString lowerFileName = fileName.toLower();
- // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- // Check literals (e.g. "Makefile")
- matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName);
- // Check complex globs (e.g. "callgrind.out[0-9]*")
- matchGlobList(result, cacheFile, cacheFile->getUint32(PosGlobListOffset), fileName);
- // Check the very common *.txt cases with the suffix tree
- const int reverseSuffixTreeOffset = cacheFile->getUint32(PosReverseSuffixTreeOffset);
- const int numRoots = cacheFile->getUint32(reverseSuffixTreeOffset);
- const int firstRootOffset = cacheFile->getUint32(reverseSuffixTreeOffset + 4);
- matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
- if (result.m_matchingMimeTypes.isEmpty())
- matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
- }
- return result;
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+ // Check complex globs (e.g. "callgrind.out[0-9]*")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
+ if (result.m_matchingMimeTypes.isEmpty())
+ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
}
void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
@@ -406,124 +322,106 @@ bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFi
return false;
}
-QMimeType QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
-{
- checkCache();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int magicListOffset = cacheFile->getUint32(PosMagicListOffset);
- const int numMatches = cacheFile->getUint32(magicListOffset);
- //const int maxExtent = cacheFile->getUint32(magicListOffset + 4);
- const int firstMatchOffset = cacheFile->getUint32(magicListOffset + 8);
-
- for (int i = 0; i < numMatches; ++i) {
- const int off = firstMatchOffset + i * 16;
- const int numMatchlets = cacheFile->getUint32(off + 8);
- const int firstMatchletOffset = cacheFile->getUint32(off + 12);
- if (matchMagicRule(cacheFile, numMatchlets, firstMatchletOffset, data)) {
- const int mimeTypeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
- *accuracyPtr = cacheFile->getUint32(off);
- // Return the first match. We have no rules for conflicting magic data...
- // (mime.cache itself is sorted, but what about local overrides with a lower prio?)
- return mimeTypeForNameUnchecked(QLatin1String(mimeType));
- }
+void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
+{
+ const int magicListOffset = m_cacheFile->getUint32(PosMagicListOffset);
+ const int numMatches = m_cacheFile->getUint32(magicListOffset);
+ //const int maxExtent = cacheFile->getUint32(magicListOffset + 4);
+ const int firstMatchOffset = m_cacheFile->getUint32(magicListOffset + 8);
+
+ for (int i = 0; i < numMatches; ++i) {
+ const int off = firstMatchOffset + i * 16;
+ const int numMatchlets = m_cacheFile->getUint32(off + 8);
+ const int firstMatchletOffset = m_cacheFile->getUint32(off + 12);
+ if (matchMagicRule(m_cacheFile, numMatchlets, firstMatchletOffset, data)) {
+ const int mimeTypeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeTypeOffset);
+ *accuracyPtr = m_cacheFile->getUint32(off);
+ // Return the first match. We have no rules for conflicting magic data...
+ // (mime.cache itself is sorted, but what about local overrides with a lower prio?)
+ candidate = mimeTypeForNameUnchecked(QLatin1String(mimeType));
+ return;
}
}
- return QMimeType();
}
-QStringList QMimeBinaryProvider::parents(const QString &mime)
+void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
{
- checkCache();
const QByteArray mimeStr = mime.toLatin1();
- QStringList result;
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int parentListOffset = cacheFile->getUint32(PosParentListOffset);
- const int numEntries = cacheFile->getUint32(parentListOffset);
-
- int begin = 0;
- int end = numEntries - 1;
- while (begin <= end) {
- const int medium = (begin + end) / 2;
- const int off = parentListOffset + 4 + 8 * medium;
- const int mimeOffset = cacheFile->getUint32(off);
- const char *aMime = cacheFile->getCharStar(mimeOffset);
- const int cmp = qstrcmp(aMime, mimeStr);
- if (cmp < 0) {
- begin = medium + 1;
- } else if (cmp > 0) {
- end = medium - 1;
- } else {
- const int parentsOffset = cacheFile->getUint32(off + 4);
- const int numParents = cacheFile->getUint32(parentsOffset);
- for (int i = 0; i < numParents; ++i) {
- const int parentOffset = cacheFile->getUint32(parentsOffset + 4 + 4 * i);
- const char *aParent = cacheFile->getCharStar(parentOffset);
- result.append(QString::fromLatin1(aParent));
- }
- break;
+ const int parentListOffset = m_cacheFile->getUint32(PosParentListOffset);
+ const int numEntries = m_cacheFile->getUint32(parentListOffset);
+
+ int begin = 0;
+ int end = numEntries - 1;
+ while (begin <= end) {
+ const int medium = (begin + end) / 2;
+ const int off = parentListOffset + 4 + 8 * medium;
+ const int mimeOffset = m_cacheFile->getUint32(off);
+ const char *aMime = m_cacheFile->getCharStar(mimeOffset);
+ const int cmp = qstrcmp(aMime, mimeStr);
+ if (cmp < 0) {
+ begin = medium + 1;
+ } else if (cmp > 0) {
+ end = medium - 1;
+ } else {
+ const int parentsOffset = m_cacheFile->getUint32(off + 4);
+ const int numParents = m_cacheFile->getUint32(parentsOffset);
+ for (int i = 0; i < numParents; ++i) {
+ const int parentOffset = m_cacheFile->getUint32(parentsOffset + 4 + 4 * i);
+ const char *aParent = m_cacheFile->getCharStar(parentOffset);
+ const QString strParent = QString::fromLatin1(aParent);
+ if (!result.contains(strParent))
+ result.append(strParent);
}
+ break;
}
}
- if (result.isEmpty()) {
- const QString parent = fallbackParent(mime);
- if (!parent.isEmpty())
- result.append(parent);
- }
- return result;
}
QString QMimeBinaryProvider::resolveAlias(const QString &name)
{
- checkCache();
const QByteArray input = name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
- const int numEntries = cacheFile->getUint32(aliasListOffset);
- int begin = 0;
- int end = numEntries - 1;
- while (begin <= end) {
- const int medium = (begin + end) / 2;
- const int off = aliasListOffset + 4 + 8 * medium;
- const int aliasOffset = cacheFile->getUint32(off);
- const char *alias = cacheFile->getCharStar(aliasOffset);
- const int cmp = qstrcmp(alias, input);
- if (cmp < 0) {
- begin = medium + 1;
- } else if (cmp > 0) {
- end = medium - 1;
- } else {
- const int mimeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeOffset);
- return QLatin1String(mimeType);
- }
+ const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
+ const int numEntries = m_cacheFile->getUint32(aliasListOffset);
+ int begin = 0;
+ int end = numEntries - 1;
+ while (begin <= end) {
+ const int medium = (begin + end) / 2;
+ const int off = aliasListOffset + 4 + 8 * medium;
+ const int aliasOffset = m_cacheFile->getUint32(off);
+ const char *alias = m_cacheFile->getCharStar(aliasOffset);
+ const int cmp = qstrcmp(alias, input);
+ if (cmp < 0) {
+ begin = medium + 1;
+ } else if (cmp > 0) {
+ end = medium - 1;
+ } else {
+ const int mimeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
+ return QLatin1String(mimeType);
}
}
-
return name;
}
-QStringList QMimeBinaryProvider::listAliases(const QString &name)
+void QMimeBinaryProvider::addAliases(const QString &name, QStringList &result)
{
- checkCache();
- QStringList result;
const QByteArray input = name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
- const int numEntries = cacheFile->getUint32(aliasListOffset);
- for (int pos = 0; pos < numEntries; ++pos) {
- const int off = aliasListOffset + 4 + 8 * pos;
- const int mimeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeOffset);
-
- if (input == mimeType) {
- const int aliasOffset = cacheFile->getUint32(off);
- const char *alias = cacheFile->getCharStar(aliasOffset);
- result.append(QString::fromLatin1(alias));
- }
+ const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
+ const int numEntries = m_cacheFile->getUint32(aliasListOffset);
+ for (int pos = 0; pos < numEntries; ++pos) {
+ const int off = aliasListOffset + 4 + 8 * pos;
+ const int mimeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
+
+ if (input == mimeType) {
+ const int aliasOffset = m_cacheFile->getUint32(off);
+ const char *alias = m_cacheFile->getCharStar(aliasOffset);
+ const QString strAlias = QString::fromLatin1(alias);
+ if (!result.contains(strAlias))
+ result.append(strAlias);
}
}
- return result;
}
void QMimeBinaryProvider::loadMimeTypeList()
@@ -533,31 +431,30 @@ void QMimeBinaryProvider::loadMimeTypeList()
m_mimetypeNames.clear();
// Unfortunately mime.cache doesn't have a full list of all mimetypes.
// So we have to parse the plain-text files called "types".
- const QStringList typesFilenames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/types"));
- for (const QString &typeFilename : typesFilenames) {
- QFile file(typeFilename);
- if (file.open(QIODevice::ReadOnly)) {
- QTextStream stream(&file);
- stream.setCodec("ISO 8859-1");
- QString line;
- while (stream.readLineInto(&line))
- m_mimetypeNames.insert(line);
- }
+ QFile file(m_directory + QStringLiteral("/types"));
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&file);
+ stream.setCodec("ISO 8859-1");
+ QString line;
+ while (stream.readLineInto(&line))
+ m_mimetypeNames.insert(line);
}
}
}
-QList<QMimeType> QMimeBinaryProvider::allMimeTypes()
+void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
{
- QList<QMimeType> result;
loadMimeTypeList();
- result.reserve(m_mimetypeNames.count());
-
- for (QSet<QString>::const_iterator it = m_mimetypeNames.constBegin();
- it != m_mimetypeNames.constEnd(); ++it)
- result.append(mimeTypeForNameUnchecked(*it));
-
- return result;
+ if (result.isEmpty()) {
+ result.reserve(m_mimetypeNames.count());
+ for (const QString &name : m_mimetypeNames)
+ result.append(mimeTypeForNameUnchecked(name));
+ } else {
+ for (const QString &name : m_mimetypeNames)
+ if (std::find_if(result.constBegin(), result.constEnd(), [name](const QMimeType &mime) -> bool { return mime.name() == name; })
+ == result.constEnd())
+ result.append(mimeTypeForNameUnchecked(name));
+ }
}
void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
@@ -681,36 +578,29 @@ QLatin1String QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posList
void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data)
{
- checkCache();
const QByteArray inputMime = data.name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const QLatin1String icon = iconForMime(cacheFile, PosIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.iconName = icon;
- return;
- }
+ const QLatin1String icon = iconForMime(m_cacheFile, PosIconsListOffset, inputMime);
+ if (!icon.isEmpty()) {
+ data.iconName = icon;
}
}
void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
{
- checkCache();
const QByteArray inputMime = data.name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const QLatin1String icon = iconForMime(cacheFile, PosGenericIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.genericIconName = icon;
- return;
- }
+ const QLatin1String icon = iconForMime(m_cacheFile, PosGenericIconsListOffset, inputMime);
+ if (!icon.isEmpty()) {
+ data.genericIconName = icon;
}
}
////
-QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db)
- : QMimeProviderBase(db), m_loaded(false)
+QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory)
+ : QMimeProviderBase(db, directory)
{
initResources();
+ ensureLoaded();
}
QMimeXMLProvider::~QMimeXMLProvider()
@@ -719,81 +609,63 @@ QMimeXMLProvider::~QMimeXMLProvider()
bool QMimeXMLProvider::isValid()
{
+ // If you change this method, adjust the logic in QMimeDatabasePrivate::loadProviders,
+ // which assumes isValid==false is only possible in QMimeBinaryProvider.
return true;
}
QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
{
- ensureLoaded();
-
return m_nameMimeTypeMap.value(name);
}
-QMimeGlobMatchResult QMimeXMLProvider::findByFileName(const QString &fileName)
+void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
{
- ensureLoaded();
-
- return m_mimeTypeGlobs.matchingGlobs(fileName);
+ m_mimeTypeGlobs.matchingGlobs(fileName, result);
}
-QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
+void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
{
- ensureLoaded();
-
- QString candidate;
-
+ QString candidateName;
+ bool foundOne = false;
for (const QMimeMagicRuleMatcher &matcher : qAsConst(m_magicMatchers)) {
if (matcher.matches(data)) {
const int priority = matcher.priority();
if (priority > *accuracyPtr) {
*accuracyPtr = priority;
- candidate = matcher.mimetype();
+ candidateName = matcher.mimetype();
+ foundOne = true;
}
}
}
- return mimeTypeForName(candidate);
+ if (foundOne)
+ candidate = mimeTypeForName(candidateName);
}
void QMimeXMLProvider::ensureLoaded()
{
- if (!m_loaded || shouldCheck()) {
- bool fdoXmlFound = false;
- QStringList allFiles;
-
- const QStringList packageDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), QStandardPaths::LocateDirectory);
- //qDebug() << "packageDirs=" << packageDirs;
- for (const QString &packageDir : packageDirs) {
- QDir dir(packageDir);
- const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
- //qDebug() << static_cast<const void *>(this) << packageDir << files;
- if (!fdoXmlFound)
- fdoXmlFound = files.contains(QLatin1String("freedesktop.org.xml"));
- QStringList::const_iterator endIt(files.constEnd());
- for (QStringList::const_iterator it(files.constBegin()); it != endIt; ++it) {
- allFiles.append(packageDir + QLatin1Char('/') + *it);
- }
- }
-
- if (!fdoXmlFound) {
- // We could instead install the file as part of installing Qt?
- allFiles.prepend(QLatin1String(":/qt-project.org/qmime/freedesktop.org.xml"));
- }
+ QStringList allFiles;
+ const QString packageDir = m_directory + QStringLiteral("/packages");
+ QDir dir(packageDir);
+ const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
+ allFiles.reserve(files.count());
+ for (const QString &xmlFile : files)
+ allFiles.append(packageDir + QLatin1Char('/') + xmlFile);
- if (m_allFiles == allFiles)
- return;
- m_allFiles = allFiles;
+ if (m_allFiles == allFiles)
+ return;
+ m_allFiles = allFiles;
- m_nameMimeTypeMap.clear();
- m_aliases.clear();
- m_parents.clear();
- m_mimeTypeGlobs.clear();
- m_magicMatchers.clear();
+ m_nameMimeTypeMap.clear();
+ m_aliases.clear();
+ m_parents.clear();
+ m_mimeTypeGlobs.clear();
+ m_magicMatchers.clear();
- //qDebug() << "Loading" << m_allFiles;
+ //qDebug() << "Loading" << m_allFiles;
- for (const QString &file : qAsConst(allFiles))
- load(file);
- }
+ for (const QString &file : qAsConst(allFiles))
+ load(file);
}
void QMimeXMLProvider::load(const QString &fileName)
@@ -805,8 +677,6 @@ void QMimeXMLProvider::load(const QString &fileName)
bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage)
{
- m_loaded = true;
-
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
@@ -828,19 +698,16 @@ void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob)
void QMimeXMLProvider::addMimeType(const QMimeType &mt)
{
+ Q_ASSERT(!mt.d.data()->fromCache);
m_nameMimeTypeMap.insert(mt.name(), mt);
}
-QStringList QMimeXMLProvider::parents(const QString &mime)
+void QMimeXMLProvider::addParents(const QString &mime, QStringList &result)
{
- ensureLoaded();
- QStringList result = m_parents.value(mime);
- if (result.isEmpty()) {
- const QString parent = fallbackParent(mime);
- if (!parent.isEmpty())
+ for (const QString &parent : m_parents.value(mime)) {
+ if (!result.contains(parent))
result.append(parent);
}
- return result;
}
void QMimeXMLProvider::addParent(const QString &child, const QString &parent)
@@ -848,16 +715,20 @@ void QMimeXMLProvider::addParent(const QString &child, const QString &parent)
m_parents[child].append(parent);
}
-QStringList QMimeXMLProvider::listAliases(const QString &name)
+void QMimeXMLProvider::addAliases(const QString &name, QStringList &result)
{
- ensureLoaded();
// Iterate through the whole hash. This method is rarely used.
- return m_aliases.keys(name);
+ for (auto it = m_aliases.constBegin(), end = m_aliases.constEnd() ; it != end ; ++it) {
+ if (it.value() == name) {
+ if (!result.contains(it.key()))
+ result.append(it.key());
+ }
+ }
+
}
QString QMimeXMLProvider::resolveAlias(const QString &name)
{
- ensureLoaded();
return m_aliases.value(name, name);
}
@@ -866,10 +737,18 @@ void QMimeXMLProvider::addAlias(const QString &alias, const QString &name)
m_aliases.insert(alias, name);
}
-QList<QMimeType> QMimeXMLProvider::allMimeTypes()
+void QMimeXMLProvider::addAllMimeTypes(QList<QMimeType> &result)
{
- ensureLoaded();
- return m_nameMimeTypeMap.values();
+ if (result.isEmpty()) { // fast path
+ result = m_nameMimeTypeMap.values();
+ } else {
+ for (auto it = m_nameMimeTypeMap.constBegin(), end = m_nameMimeTypeMap.constEnd() ; it != end ; ++it) {
+ const QString newMime = it.key();
+ if (std::find_if(result.constBegin(), result.constEnd(), [newMime](const QMimeType &mime) -> bool { return mime.name() == newMime; })
+ == result.constEnd())
+ result.append(it.value());
+ }
+ }
}
void QMimeXMLProvider::addMagicMatcher(const QMimeMagicRuleMatcher &matcher)
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index 3eae672823..b2be545cf8 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -59,7 +59,6 @@
#include "qmimeglobpattern_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qset.h>
-#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
@@ -68,25 +67,25 @@ class QMimeMagicRuleMatcher;
class QMimeProviderBase
{
public:
- QMimeProviderBase(QMimeDatabasePrivate *db);
+ QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory);
virtual ~QMimeProviderBase() {}
virtual bool isValid() = 0;
virtual QMimeType mimeTypeForName(const QString &name) = 0;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) = 0;
- virtual QStringList parents(const QString &mime) = 0;
+ virtual void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) = 0;
+ virtual void addParents(const QString &mime, QStringList &result) = 0;
virtual QString resolveAlias(const QString &name) = 0;
- virtual QStringList listAliases(const QString &name) = 0;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) = 0;
- virtual QList<QMimeType> allMimeTypes() = 0;
- virtual void loadMimeTypePrivate(QMimeTypePrivate &) {}
+ virtual void addAliases(const QString &name, QStringList &result) = 0;
+ virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) = 0;
+ virtual void addAllMimeTypes(QList<QMimeType> &result) = 0;
virtual void loadIcon(QMimeTypePrivate &) {}
virtual void loadGenericIcon(QMimeTypePrivate &) {}
+ virtual void ensureLoaded() {}
+
+ QString directory() const { return m_directory; }
QMimeDatabasePrivate *m_db;
-protected:
- bool shouldCheck();
- QElapsedTimer m_lastCheck;
+ QString m_directory;
};
/*
@@ -95,20 +94,21 @@ protected:
class QMimeBinaryProvider : public QMimeProviderBase
{
public:
- QMimeBinaryProvider(QMimeDatabasePrivate *db);
+ QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory);
virtual ~QMimeBinaryProvider();
virtual bool isValid() override;
virtual QMimeType mimeTypeForName(const QString &name) override;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) override;
- virtual QStringList parents(const QString &mime) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
virtual QString resolveAlias(const QString &name) override;
- virtual QStringList listAliases(const QString &name) override;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) override;
- virtual QList<QMimeType> allMimeTypes() override;
- virtual void loadMimeTypePrivate(QMimeTypePrivate &) override;
+ void addAliases(const QString &name, QStringList &result) override;
+ void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
+ void addAllMimeTypes(QList<QMimeType> &result) override;
+ static void loadMimeTypePrivate(QMimeTypePrivate &);
virtual void loadIcon(QMimeTypePrivate &) override;
virtual void loadGenericIcon(QMimeTypePrivate &) override;
+ void ensureLoaded() override;
private:
struct CacheFile;
@@ -118,15 +118,9 @@ private:
bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data);
QLatin1String iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
void loadMimeTypeList();
- void checkCache();
-
- class CacheFileList : public QList<CacheFile *>
- {
- public:
- CacheFile *findCacheFile(const QString &fileName) const;
- bool checkCacheChanged();
- };
- CacheFileList m_cacheFiles;
+ bool checkCacheChanged();
+
+ CacheFile *m_cacheFile = nullptr;
QStringList m_cacheFileNames;
QSet<QString> m_mimetypeNames;
bool m_mimetypeListLoaded;
@@ -138,17 +132,18 @@ private:
class QMimeXMLProvider : public QMimeProviderBase
{
public:
- QMimeXMLProvider(QMimeDatabasePrivate *db);
+ QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
~QMimeXMLProvider();
virtual bool isValid() override;
virtual QMimeType mimeTypeForName(const QString &name) override;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) override;
- virtual QStringList parents(const QString &mime) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
virtual QString resolveAlias(const QString &name) override;
- virtual QStringList listAliases(const QString &name) override;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) override;
- virtual QList<QMimeType> allMimeTypes() override;
+ void addAliases(const QString &name, QStringList &result) override;
+ void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
+ void addAllMimeTypes(QList<QMimeType> &result) override;
+ void ensureLoaded() override;
bool load(const QString &fileName, QString *errorMessage);
@@ -160,11 +155,8 @@ public:
void addMagicMatcher(const QMimeMagicRuleMatcher &matcher);
private:
- void ensureLoaded();
void load(const QString &fileName);
- bool m_loaded;
-
typedef QHash<QString, QMimeType> NameMimeTypeMap;
NameMimeTypeMap m_nameMimeTypeMap;
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index 28113babfe..8f6237c1cb 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
QMimeTypePrivate::QMimeTypePrivate()
- : loaded(false)
+ : loaded(false), fromCache(false)
{}
QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other)
@@ -76,7 +76,6 @@ void QMimeTypePrivate::clear()
genericIconName.clear();
iconName.clear();
globPatterns.clear();
- loaded = false;
}
void QMimeTypePrivate::addGlobPattern(const QString &pattern)
@@ -256,7 +255,7 @@ QString QMimeType::name() const
*/
QString QMimeType::comment() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QStringList languageList;
languageList << QLocale().name();
@@ -296,7 +295,7 @@ QString QMimeType::comment() const
*/
QString QMimeType::genericIconName() const
{
- QMimeDatabasePrivate::instance()->provider()->loadGenericIcon(*d);
+ QMimeDatabasePrivate::instance()->loadGenericIcon(*d);
if (d->genericIconName.isEmpty()) {
// From the spec:
// If the generic icon name is empty (not specified by the mimetype definition)
@@ -324,7 +323,7 @@ QString QMimeType::genericIconName() const
*/
QString QMimeType::iconName() const
{
- QMimeDatabasePrivate::instance()->provider()->loadIcon(*d);
+ QMimeDatabasePrivate::instance()->loadIcon(*d);
if (d->iconName.isEmpty()) {
// Make default icon name from the mimetype name
d->iconName = name();
@@ -344,7 +343,7 @@ QString QMimeType::iconName() const
*/
QStringList QMimeType::globPatterns() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
return d->globPatterns;
}
@@ -368,12 +367,12 @@ QStringList QMimeType::globPatterns() const
*/
QStringList QMimeType::parentMimeTypes() const
{
- return QMimeDatabasePrivate::instance()->provider()->parents(d->name);
+ return QMimeDatabasePrivate::instance()->mimeParents(d->name);
}
static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
{
- const QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime);
+ const QStringList parents = QMimeDatabasePrivate::instance()->mimeParents(mime);
for (const QString &parent : parents) {
// I would use QSet, but since order matters I better not
if (!allParents.contains(parent))
@@ -425,7 +424,7 @@ QStringList QMimeType::allAncestors() const
*/
QStringList QMimeType::aliases() const
{
- return QMimeDatabasePrivate::instance()->provider()->listAliases(d->name);
+ return QMimeDatabasePrivate::instance()->listAliases(d->name);
}
/*!
@@ -439,7 +438,7 @@ QStringList QMimeType::aliases() const
*/
QStringList QMimeType::suffixes() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QStringList result;
for (const QString &pattern : qAsConst(d->globPatterns)) {
@@ -480,7 +479,7 @@ QString QMimeType::preferredSuffix() const
*/
QString QMimeType::filterString() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QString filter;
if (!d->globPatterns.empty()) {
@@ -508,7 +507,7 @@ bool QMimeType::inherits(const QString &mimeTypeName) const
{
if (d->name == mimeTypeName)
return true;
- return QMimeDatabasePrivate::instance()->inherits(d->name, mimeTypeName);
+ return QMimeDatabasePrivate::instance()->mimeInherits(d->name, mimeTypeName);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h
index b0bfad2f65..aa38a1adf5 100644
--- a/src/corelib/mimetypes/qmimetype_p.h
+++ b/src/corelib/mimetypes/qmimetype_p.h
@@ -74,6 +74,7 @@ public:
void addGlobPattern(const QString &pattern);
bool loaded; // QSharedData leaves a 4 byte gap, so don't put 8 byte members first
+ bool fromCache; // true if this comes from the binary provider
QString name;
LocaleHash localeComments;
QString genericIconName;
@@ -94,6 +95,7 @@ QT_END_NAMESPACE
{ \
QMimeTypePrivate qMimeTypeData; \
qMimeTypeData.name = name; \
+ qMimeTypeData.loaded = true; \
qMimeTypeData.genericIconName = genericIconName; \
qMimeTypeData.iconName = iconName; \
qMimeTypeData.globPatterns = globPatterns; \
@@ -112,6 +114,7 @@ QT_END_NAMESPACE
) \
{ \
QMimeTypePrivate qMimeTypeData; \
+ qMimeTypeData.loaded = true; \
qMimeTypeData.name = std::move(name); \
qMimeTypeData.genericIconName = std::move(genericIconName); \
qMimeTypeData.iconName = std::move(iconName); \
diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
index 5ecd339908..0a55560ab0 100644
--- a/src/corelib/mimetypes/qmimetypeparser.cpp
+++ b/src/corelib/mimetypes/qmimetypeparser.cpp
@@ -201,6 +201,7 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
return false;
#else
QMimeTypePrivate data;
+ data.loaded = true;
int priority = 50;
QStack<QMimeMagicRule *> currentRules; // stack for the nesting of rules
QList<QMimeMagicRule> rules; // toplevel rules
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index a462d7bb58..fafc3e37b0 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -164,11 +164,7 @@
# if !defined(__MIPS_DSPR2__) && defined(__mips_dspr2) && defined(Q_PROCESSOR_MIPS_32)
# define __MIPS_DSPR2__
# endif
-#elif (defined(Q_CC_INTEL) || defined(Q_CC_MSVC) \
- || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && Q_CC_GNU >= 409) \
- || (defined(Q_CC_CLANG) && Q_CC_CLANG >= 308)) \
- && !defined(QT_BOOTSTRAPPED)
-# define QT_COMPILER_SUPPORTS_SIMD_ALWAYS
+#elif defined(Q_PROCESSOR_X86) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
/* GCC requires attributes for a function */
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index cd3966fb47..c8ba86bc9a 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -747,8 +747,7 @@ QString QPlatformTheme::removeMnemonics(const QString &original)
int currPos = 0;
int l = original.length();
while (l) {
- if (original.at(currPos) == QLatin1Char('&')
- && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ if (original.at(currPos) == QLatin1Char('&')) {
++currPos;
--l;
if (l == 0)
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index c6ae7c1b79..2067c86023 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -596,8 +596,7 @@ static QString qt_mac_removeMnemonics(const QString &original)
int currPos = 0;
int l = original.length();
while (l) {
- if (original.at(currPos) == QLatin1Char('&')
- && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ if (original.at(currPos) == QLatin1Char('&')) {
++currPos;
--l;
if (l == 0)
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 8883b6360f..b1a49b7d98 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -148,7 +148,7 @@ void tst_QMimeDatabase::initTestCase()
qDebug() << "\nGlobal XDG_DATA_DIRS: " << m_globalXdgDir;
const QString freeDesktopXml = QStringLiteral("freedesktop.org.xml");
- const QString xmlFileName = QLatin1String(RESOURCE_PREFIX) + freeDesktopXml;
+ const QString xmlFileName = QLatin1String(RESOURCE_PREFIX "packages/") + freeDesktopXml;
const QString xmlTargetFileName = globalPackageDir + QLatin1Char('/') + freeDesktopXml;
QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
#endif
@@ -1042,17 +1042,21 @@ void tst_QMimeDatabase::installNewLocalMimeType()
QCOMPARE(db.mimeTypeForFile(qmlTestFile).name(),
QString::fromLatin1("text/x-qml"));
- // Now test removing the local mimetypes again (note, this leaves a mostly-empty mime.cache file)
- for (int i = 0; i < m_additionalMimeFileNames.size(); ++i)
- QFile::remove(destDir + m_additionalMimeFileNames.at(i));
+ // Now test removing local mimetypes
+ for (int i = 1 ; i <= 3 ; ++i)
+ QFile::remove(destDir + QStringLiteral("invalid-magic%1.xml").arg(i));
if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(m_localMimeDir))
QSKIP("shared-mime-info not found, skipping mime.cache test");
- QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
- QString::fromLatin1("application/octet-stream"));
- QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/invalid-magic1")).isValid()); // deleted
+ QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); // still present
- // And now the user goes wild and uses rm -rf
+ // The user deletes the cache -> the XML provider makes things still work
QFile::remove(m_localMimeDir + QString::fromLatin1("/mime.cache"));
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/invalid-magic1")).isValid()); // deleted
+ QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); // still present
+
+ // Finally, the user deletes the whole local dir
+ QVERIFY2(QDir(m_localMimeDir).removeRecursively(), qPrintable(m_localMimeDir + ": " + qt_error_string()));
QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
QString::fromLatin1("application/octet-stream"));
QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
index 7c1cd5b66b..f2108ab518 100644
--- a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
+++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
@@ -6,4 +6,7 @@ QT = core network testlib
TARGET = tst_qsslcertificate
+RESOURCES += \
+ qsslcertificate.qrc
+
TESTDATA += certificates/* more-certificates/* verify-certs/* pkcs12/*
diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.qrc b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.qrc
new file mode 100644
index 0000000000..fe5d510120
--- /dev/null
+++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.qrc
@@ -0,0 +1,79 @@
+<RCC>
+ <qresource prefix="/">
+ <file>certificates/ca-cert.pem</file>
+ <file>certificates/ca-cert.pem.digest-md5</file>
+ <file>certificates/ca-cert.pem.digest-sha1</file>
+ <file>certificates/cert-ss-san-utf8.pem</file>
+ <file>certificates/cert-ss-san-utf8.pem.san</file>
+ <file>certificates/cert-ss-san.pem</file>
+ <file>certificates/cert-ss-san.pem.san</file>
+ <file>certificates/cert-ss.der</file>
+ <file>certificates/cert-ss.der.pubkey</file>
+ <file>certificates/cert-ss.pem</file>
+ <file>certificates/cert-ss.pem.digest-md5</file>
+ <file>certificates/cert-ss.pem.digest-sha1</file>
+ <file>certificates/cert-ss.pem.pubkey</file>
+ <file>certificates/cert.der</file>
+ <file>certificates/cert.der.pubkey</file>
+ <file>certificates/cert.pem</file>
+ <file>certificates/cert.pem.digest-md5</file>
+ <file>certificates/cert.pem.digest-sha1</file>
+ <file>certificates/cert.pem.pubkey</file>
+ <file>certificates/dsa-cert-ss.der.pubkey</file>
+ <file>certificates/dsa-cert-ss.pem</file>
+ <file>certificates/dsa-cert-ss.pem.digest-md5</file>
+ <file>certificates/dsa-cert-ss.pem.digest-sha1</file>
+ <file>certificates/dsa-cert-ss.pem.pubkey</file>
+ <file>certificates/ec-cert-ss.der.pubkey</file>
+ <file>certificates/ec-cert-ss.pem</file>
+ <file>certificates/ec-cert-ss.pem.digest-md5</file>
+ <file>certificates/ec-cert-ss.pem.digest-sha1</file>
+ <file>certificates/ec-cert-ss.pem.pubkey</file>
+ <file>certificates/gencertificates.sh</file>
+ <file>certificates/san.cnf</file>
+ <file>more-certificates/badguy-nul-cn.crt</file>
+ <file>more-certificates/badguy-nul-san.crt</file>
+ <file>more-certificates/blacklisted-anssi-tresor.pem</file>
+ <file>more-certificates/blacklisted-google.com-diginotar.pem</file>
+ <file>more-certificates/blacklisted-nic-india-2007.pem</file>
+ <file>more-certificates/blacklisted-nic-india-2011.pem</file>
+ <file>more-certificates/blacklisted-nic-india-2014.pem</file>
+ <file>more-certificates/blacklisted-turktrust-e-islem.kktcmerkezbankasi.org.pem</file>
+ <file>more-certificates/blacklisted-turktrust-ego.gov.tr.pem</file>
+ <file>more-certificates/blacklisted1.pem</file>
+ <file>more-certificates/blacklisted2.pem</file>
+ <file>more-certificates/blacklisted3.pem</file>
+ <file>more-certificates/blacklisted4.pem</file>
+ <file>more-certificates/blacklisted5.pem</file>
+ <file>more-certificates/blacklisted6.pem</file>
+ <file>more-certificates/blacklisted7.pem</file>
+ <file>more-certificates/blacklisted8.pem</file>
+ <file>more-certificates/blacklisted9.pem</file>
+ <file>more-certificates/cert-large-expiration-date.pem</file>
+ <file>more-certificates/cert-large-expiration-date.txt.0.9.8</file>
+ <file>more-certificates/cert-large-expiration-date.txt.1.0.0</file>
+ <file>more-certificates/cert-large-expiration-date.txt.1.0.1</file>
+ <file>more-certificates/cert-large-expiration-date.txt.1.0.1c</file>
+ <file>more-certificates/cert-large-serial-number.pem</file>
+ <file>more-certificates/malformed-just-begin-no-newline.pem</file>
+ <file>more-certificates/malformed-just-begin.pem</file>
+ <file>more-certificates/natwest-banking.pem</file>
+ <file>more-certificates/no-ending-newline.pem</file>
+ <file>more-certificates/test-cn-two-cns-cert.pem</file>
+ <file>more-certificates/test-cn-with-drink-cert.pem</file>
+ <file>more-certificates/trailing-whitespace.pem</file>
+ <file>pkcs12/inter.crt</file>
+ <file>pkcs12/leaf-nokey.p12</file>
+ <file>pkcs12/leaf.crt</file>
+ <file>pkcs12/leaf.key</file>
+ <file>pkcs12/leaf.p12</file>
+ <file>pkcs12/README</file>
+ <file>verify-certs/cacert.pem</file>
+ <file>verify-certs/README</file>
+ <file>verify-certs/test-addons-mozilla-org-cert.pem</file>
+ <file>verify-certs/test-intermediate-ca-cert.pem</file>
+ <file>verify-certs/test-intermediate-is-ca-cert.pem</file>
+ <file>verify-certs/test-intermediate-not-ca-cert.pem</file>
+ <file>verify-certs/test-ocsp-good-cert.pem</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
index 064efc120b..d845315e85 100644
--- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
+++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp
@@ -57,11 +57,8 @@ class tst_QSslCertificate : public QObject
void compareCertificates(const QSslCertificate & cert1, const QSslCertificate & cert2);
#endif
- QString oldCurrentDir;
-
public slots:
void initTestCase();
- void cleanupTestCase();
#ifndef QT_NO_SSL
private slots:
@@ -111,23 +108,11 @@ private slots:
// ### add tests for certificate bundles (multiple certificates concatenated into a single
// structure); both PEM and DER formatted
#endif
-private:
- QString testDataDir;
};
void tst_QSslCertificate::initTestCase()
{
- testDataDir = QFileInfo(QFINDTESTDATA("certificates")).absolutePath();
- if (testDataDir.isEmpty())
- testDataDir = QCoreApplication::applicationDirPath();
-
- if (QDir::current().absolutePath() != testDataDir) {
- oldCurrentDir = QDir::current().absolutePath();
- QVERIFY2(QDir::setCurrent(testDataDir),
- qPrintable(QString("Cannot change directory to %1").arg(testDataDir)));
- }
-
- QDir dir(testDataDir + "/certificates");
+ QDir dir(":/certificates");
QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
QRegExp rxCert(QLatin1String("^.+\\.(pem|der)$"));
QRegExp rxSan(QLatin1String("^(.+\\.(?:pem|der))\\.san$"));
@@ -151,13 +136,6 @@ void tst_QSslCertificate::initTestCase()
}
}
-void tst_QSslCertificate::cleanupTestCase()
-{
- if (!oldCurrentDir.isEmpty()) {
- QDir::setCurrent(oldCurrentDir);
- }
-}
-
#ifndef QT_NO_SSL
void tst_QSslCertificate::hash()
@@ -232,7 +210,7 @@ void tst_QSslCertificate::constructor_device()
if (!QSslSocket::supportsSsl())
return;
- QFile f(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ QFile f(":/verify-certs/test-ocsp-good-cert.pem");
bool ok = f.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -241,7 +219,7 @@ void tst_QSslCertificate::constructor_device()
f.close();
// Check opening a DER as a PEM fails
- QFile f2(testDataDir + "/certificates/cert.der");
+ QFile f2(":/certificates/cert.der");
ok = f2.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -250,7 +228,7 @@ void tst_QSslCertificate::constructor_device()
f2.close();
// Check opening a DER as a DER works
- QFile f3(testDataDir + "/certificates/cert.der");
+ QFile f3(":/certificates/cert.der");
ok = f3.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -259,7 +237,7 @@ void tst_QSslCertificate::constructor_device()
f3.close();
// Check opening a PEM as a DER fails
- QFile f4(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ QFile f4(":/verify-certs/test-ocsp-good-cert.pem");
ok = f4.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -445,7 +423,7 @@ void tst_QSslCertificate::subjectAlternativeNames()
void tst_QSslCertificate::utf8SubjectNames()
{
- QSslCertificate cert = QSslCertificate::fromPath("certificates/cert-ss-san-utf8.pem", QSsl::Pem,
+ QSslCertificate cert = QSslCertificate::fromPath(":/certificates/cert-ss-san-utf8.pem", QSsl::Pem,
QRegExp::FixedString).first();
QVERIFY(!cert.isNull());
@@ -568,60 +546,60 @@ void tst_QSslCertificate::fromPath_data()
QTest::newRow("empty regexp der") << QString() << int(QRegExp::RegExp) << false << 0;
QTest::newRow("empty wildcard pem") << QString() << int(QRegExp::Wildcard) << true << 0;
QTest::newRow("empty wildcard der") << QString() << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"certificates\" fixed pem") << QString("certificates") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"certificates\" fixed der") << QString("certificates") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"certificates\" regexp pem") << QString("certificates") << int(QRegExp::RegExp) << true << 0;
- QTest::newRow("\"certificates\" regexp der") << QString("certificates") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"certificates\" wildcard pem") << QString("certificates") << int(QRegExp::Wildcard) << true << 0;
- QTest::newRow("\"certificates\" wildcard der") << QString("certificates") << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"certificates/cert.pem\" fixed pem") << QString("certificates/cert.pem") << int(QRegExp::FixedString) << true << 1;
- QTest::newRow("\"certificates/cert.pem\" fixed der") << QString("certificates/cert.pem") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"certificates/cert.pem\" regexp pem") << QString("certificates/cert.pem") << int(QRegExp::RegExp) << true << 1;
- QTest::newRow("\"certificates/cert.pem\" regexp der") << QString("certificates/cert.pem") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"certificates/cert.pem\" wildcard pem") << QString("certificates/cert.pem") << int(QRegExp::Wildcard) << true << 1;
- QTest::newRow("\"certificates/cert.pem\" wildcard der") << QString("certificates/cert.pem") << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"certificates/*\" fixed pem") << QString("certificates/*") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"certificates/*\" fixed der") << QString("certificates/*") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"certificates/*\" regexp pem") << QString("certificates/*") << int(QRegExp::RegExp) << true << 0;
- QTest::newRow("\"certificates/*\" regexp der") << QString("certificates/*") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"certificates/*\" wildcard pem") << QString("certificates/*") << int(QRegExp::Wildcard) << true << 7;
- QTest::newRow("\"certificates/ca*\" wildcard pem") << QString("certificates/ca*") << int(QRegExp::Wildcard) << true << 1;
- QTest::newRow("\"certificates/cert*\" wildcard pem") << QString("certificates/cert*") << int(QRegExp::Wildcard) << true << 4;
- QTest::newRow("\"certificates/cert-[sure]*\" wildcard pem") << QString("certificates/cert-[sure]*") << int(QRegExp::Wildcard) << true << 3;
- QTest::newRow("\"certificates/cert-[not]*\" wildcard pem") << QString("certificates/cert-[not]*") << int(QRegExp::Wildcard) << true << 0;
- QTest::newRow("\"certificates/*\" wildcard der") << QString("certificates/*") << int(QRegExp::Wildcard) << false << 2;
- QTest::newRow("\"c*/c*.pem\" fixed pem") << QString("c*/c*.pem") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"c*/c*.pem\" fixed der") << QString("c*/c*.pem") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"c*/c*.pem\" regexp pem") << QString("c*/c*.pem") << int(QRegExp::RegExp) << true << 0;
- QTest::newRow("\"c*/c*.pem\" regexp der") << QString("c*/c*.pem") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << true << 5;
- QTest::newRow("\"c*/c*.pem\" wildcard der") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"d*/c*.pem\" fixed pem") << QString("d*/c*.pem") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"d*/c*.pem\" fixed der") << QString("d*/c*.pem") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"d*/c*.pem\" regexp pem") << QString("d*/c*.pem") << int(QRegExp::RegExp) << true << 0;
- QTest::newRow("\"d*/c*.pem\" regexp der") << QString("d*/c*.pem") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"d*/c*.pem\" wildcard pem") << QString("d*/c*.pem") << int(QRegExp::Wildcard) << true << 0;
- QTest::newRow("\"d*/c*.pem\" wildcard der") << QString("d*/c*.pem") << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"c.*/c.*.pem\" fixed pem") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"c.*/c.*.pem\" fixed der") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << true << 5;
- QTest::newRow("\"c.*/c.*.pem\" regexp der") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"c.*/c.*.pem\" wildcard pem") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0;
- QTest::newRow("\"c.*/c.*.pem\" wildcard der") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0;
- QTest::newRow("\"d.*/c.*.pem\" fixed pem") << QString("d.*/c.*.pem") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("\"d.*/c.*.pem\" fixed der") << QString("d.*/c.*.pem") << int(QRegExp::FixedString) << false << 0;
- QTest::newRow("\"d.*/c.*.pem\" regexp pem") << QString("d.*/c.*.pem") << int(QRegExp::RegExp) << true << 0;
- QTest::newRow("\"d.*/c.*.pem\" regexp der") << QString("d.*/c.*.pem") << int(QRegExp::RegExp) << false << 0;
- QTest::newRow("\"d.*/c.*.pem\" wildcard pem") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0;
- QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"certificates\" fixed pem") << QString(":/certificates") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"certificates\" fixed der") << QString(":/certificates") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"certificates\" regexp pem") << QString(":/certificates") << int(QRegExp::RegExp) << true << 0;
+ QTest::newRow("\"certificates\" regexp der") << QString(":/certificates") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"certificates\" wildcard pem") << QString(":/certificates") << int(QRegExp::Wildcard) << true << 0;
+ QTest::newRow("\"certificates\" wildcard der") << QString(":/certificates") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"certificates/cert.pem\" fixed pem") << QString(":/certificates/cert.pem") << int(QRegExp::FixedString) << true << 1;
+ QTest::newRow("\"certificates/cert.pem\" fixed der") << QString(":/certificates/cert.pem") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"certificates/cert.pem\" regexp pem") << QString(":/certificates/cert.pem") << int(QRegExp::RegExp) << true << 1;
+ QTest::newRow("\"certificates/cert.pem\" regexp der") << QString(":/certificates/cert.pem") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"certificates/cert.pem\" wildcard pem") << QString(":/certificates/cert.pem") << int(QRegExp::Wildcard) << true << 1;
+ QTest::newRow("\"certificates/cert.pem\" wildcard der") << QString(":/certificates/cert.pem") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"certificates/*\" fixed pem") << QString(":/certificates/*") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"certificates/*\" fixed der") << QString(":/certificates/*") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"certificates/*\" regexp pem") << QString(":/certificates/*") << int(QRegExp::RegExp) << true << 0;
+ QTest::newRow("\"certificates/*\" regexp der") << QString(":/certificates/*") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"certificates/*\" wildcard pem") << QString(":/certificates/*") << int(QRegExp::Wildcard) << true << 7;
+ QTest::newRow("\"certificates/ca*\" wildcard pem") << QString(":/certificates/ca*") << int(QRegExp::Wildcard) << true << 1;
+ QTest::newRow("\"certificates/cert*\" wildcard pem") << QString(":/certificates/cert*") << int(QRegExp::Wildcard) << true << 4;
+ QTest::newRow("\"certificates/cert-[sure]*\" wildcard pem") << QString(":/certificates/cert-[sure]*") << int(QRegExp::Wildcard) << true << 3;
+ QTest::newRow("\"certificates/cert-[not]*\" wildcard pem") << QString(":/certificates/cert-[not]*") << int(QRegExp::Wildcard) << true << 0;
+ QTest::newRow("\"certificates/*\" wildcard der") << QString(":/certificates/*") << int(QRegExp::Wildcard) << false << 2;
+ QTest::newRow("\"c*/c*.pem\" fixed pem") << QString(":/c*/c*.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"c*/c*.pem\" fixed der") << QString(":/c*/c*.pem") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"c*/c*.pem\" regexp pem") << QString(":/c*/c*.pem") << int(QRegExp::RegExp) << true << 0;
+ QTest::newRow("\"c*/c*.pem\" regexp der") << QString(":/c*/c*.pem") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString(":/c*/c*.pem") << int(QRegExp::Wildcard) << true << 5;
+ QTest::newRow("\"c*/c*.pem\" wildcard der") << QString(":/c*/c*.pem") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"d*/c*.pem\" fixed pem") << QString(":/d*/c*.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"d*/c*.pem\" fixed der") << QString(":/d*/c*.pem") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"d*/c*.pem\" regexp pem") << QString(":/d*/c*.pem") << int(QRegExp::RegExp) << true << 0;
+ QTest::newRow("\"d*/c*.pem\" regexp der") << QString(":/d*/c*.pem") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"d*/c*.pem\" wildcard pem") << QString(":/d*/c*.pem") << int(QRegExp::Wildcard) << true << 0;
+ QTest::newRow("\"d*/c*.pem\" wildcard der") << QString(":/d*/c*.pem") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"c.*/c.*.pem\" fixed pem") << QString(":/c.*/c.*.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"c.*/c.*.pem\" fixed der") << QString(":/c.*/c.*.pem") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString(":/c.*/c.*.pem") << int(QRegExp::RegExp) << true << 5;
+ QTest::newRow("\"c.*/c.*.pem\" regexp der") << QString(":/c.*/c.*.pem") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"c.*/c.*.pem\" wildcard pem") << QString(":/c.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0;
+ QTest::newRow("\"c.*/c.*.pem\" wildcard der") << QString(":/c.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0;
+ QTest::newRow("\"d.*/c.*.pem\" fixed pem") << QString(":/d.*/c.*.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("\"d.*/c.*.pem\" fixed der") << QString(":/d.*/c.*.pem") << int(QRegExp::FixedString) << false << 0;
+ QTest::newRow("\"d.*/c.*.pem\" regexp pem") << QString(":/d.*/c.*.pem") << int(QRegExp::RegExp) << true << 0;
+ QTest::newRow("\"d.*/c.*.pem\" regexp der") << QString(":/d.*/c.*.pem") << int(QRegExp::RegExp) << false << 0;
+ QTest::newRow("\"d.*/c.*.pem\" wildcard pem") << QString(":/d.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0;
+ QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString(":/d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0;
#ifdef Q_OS_LINUX
- QTest::newRow("absolute path wildcard pem") << (testDataDir + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 7;
+ QTest::newRow("absolute path wildcard pem") << (":/certificates/*.pem") << int(QRegExp::Wildcard) << true << 7;
#endif
- QTest::newRow("trailing-whitespace") << QString("more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1;
- QTest::newRow("no-ending-newline") << QString("more-certificates/no-ending-newline.pem") << int(QRegExp::FixedString) << true << 1;
- QTest::newRow("malformed-just-begin") << QString("more-certificates/malformed-just-begin.pem") << int(QRegExp::FixedString) << true << 0;
- QTest::newRow("malformed-just-begin-no-newline") << QString("more-certificates/malformed-just-begin-no-newline.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("trailing-whitespace") << QString(":/more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1;
+ QTest::newRow("no-ending-newline") << QString(":/more-certificates/no-ending-newline.pem") << int(QRegExp::FixedString) << true << 1;
+ QTest::newRow("malformed-just-begin") << QString(":/more-certificates/malformed-just-begin.pem") << int(QRegExp::FixedString) << true << 0;
+ QTest::newRow("malformed-just-begin-no-newline") << QString(":/more-certificates/malformed-just-begin-no-newline.pem") << int(QRegExp::FixedString) << true << 0;
}
void tst_QSslCertificate::fromPath()
@@ -722,7 +700,7 @@ void tst_QSslCertificate::certInfo()
"dc:c2:eb:b7:bb:50:18:05:ba:ad:af:08:49:fe:98:63"
"55:ba:e7:fb:95:5d:91";
- QSslCertificate cert = QSslCertificate::fromPath("certificates/cert.pem", QSsl::Pem,
+ QSslCertificate cert = QSslCertificate::fromPath(":/certificates/cert.pem", QSsl::Pem,
QRegExp::FixedString).first();
QVERIFY(!cert.isNull());
@@ -779,7 +757,7 @@ void tst_QSslCertificate::certInfo()
void tst_QSslCertificate::certInfoQByteArray()
{
- QSslCertificate cert = QSslCertificate::fromPath("certificates/cert.pem", QSsl::Pem,
+ QSslCertificate cert = QSslCertificate::fromPath(":/certificates/cert.pem", QSsl::Pem,
QRegExp::FixedString).first();
QVERIFY(!cert.isNull());
@@ -828,11 +806,11 @@ void tst_QSslCertificate::task256066toPem()
void tst_QSslCertificate::nulInCN()
{
-#ifdef QT_SECURETRANSPORT
+#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT)
QSKIP("Generic QSslCertificatePrivate fails this test");
#endif
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/badguy-nul-cn.crt");
+ QSslCertificate::fromPath(":/more-certificates/badguy-nul-cn.crt");
QCOMPARE(certList.size(), 1);
const QSslCertificate &cert = certList.at(0);
@@ -847,11 +825,11 @@ void tst_QSslCertificate::nulInCN()
void tst_QSslCertificate::nulInSan()
{
-#ifdef QT_SECURETRANSPORT
+#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT)
QSKIP("Generic QSslCertificatePrivate fails this test");
#endif
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/badguy-nul-san.crt");
+ QSslCertificate::fromPath(":/more-certificates/badguy-nul-san.crt");
QCOMPARE(certList.size(), 1);
const QSslCertificate &cert = certList.at(0);
@@ -871,7 +849,7 @@ void tst_QSslCertificate::nulInSan()
void tst_QSslCertificate::largeSerialNumber()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-serial-number.pem");
+ QSslCertificate::fromPath(":/more-certificates/cert-large-serial-number.pem");
QCOMPARE(certList.size(), 1);
@@ -883,7 +861,7 @@ void tst_QSslCertificate::largeSerialNumber()
void tst_QSslCertificate::largeExpirationDate() // QTBUG-12489
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-expiration-date.pem");
+ QSslCertificate::fromPath(":/more-certificates/cert-large-expiration-date.pem");
QCOMPARE(certList.size(), 1);
@@ -896,8 +874,8 @@ void tst_QSslCertificate::largeExpirationDate() // QTBUG-12489
void tst_QSslCertificate::blacklistedCertificates()
{
- QList<QSslCertificate> blacklistedCerts = QSslCertificate::fromPath("more-certificates/blacklisted*.pem", QSsl::Pem, QRegExp::Wildcard);
- QVERIFY2(blacklistedCerts.count() > 0, "Please run this test from the source directory");
+ QList<QSslCertificate> blacklistedCerts = QSslCertificate::fromPath(":/more-certificates/blacklisted*.pem", QSsl::Pem, QRegExp::Wildcard);
+ QVERIFY(blacklistedCerts.count() > 0);
for (int a = 0; a < blacklistedCerts.count(); a++) {
QVERIFY(blacklistedCerts.at(a).isBlacklisted());
}
@@ -905,34 +883,34 @@ void tst_QSslCertificate::blacklistedCertificates()
void tst_QSslCertificate::selfsignedCertificates()
{
- QVERIFY(QSslCertificate::fromPath(testDataDir + "/certificates/cert-ss.pem").first().isSelfSigned());
- QVERIFY(!QSslCertificate::fromPath(testDataDir + "/certificates/cert.pem").first().isSelfSigned());
+ QVERIFY(QSslCertificate::fromPath(":/certificates/cert-ss.pem").first().isSelfSigned());
+ QVERIFY(!QSslCertificate::fromPath(":/certificates/cert.pem").first().isSelfSigned());
QVERIFY(!QSslCertificate().isSelfSigned());
}
void tst_QSslCertificate::toText()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-expiration-date.pem");
+ QSslCertificate::fromPath(":/more-certificates/cert-large-expiration-date.pem");
QCOMPARE(certList.size(), 1);
const QSslCertificate &cert = certList.at(0);
// Openssl's cert dump method changed slightly between 0.9.8, 1.0.0 and 1.01 versions, so we want it to match any output
- QFile f098(testDataDir + "/more-certificates/cert-large-expiration-date.txt.0.9.8");
+ QFile f098(":/more-certificates/cert-large-expiration-date.txt.0.9.8");
QVERIFY(f098.open(QIODevice::ReadOnly | QFile::Text));
QByteArray txt098 = f098.readAll();
- QFile f100(testDataDir + "/more-certificates/cert-large-expiration-date.txt.1.0.0");
+ QFile f100(":/more-certificates/cert-large-expiration-date.txt.1.0.0");
QVERIFY(f100.open(QIODevice::ReadOnly | QFile::Text));
QByteArray txt100 = f100.readAll();
- QFile f101(testDataDir + "/more-certificates/cert-large-expiration-date.txt.1.0.1");
+ QFile f101(":/more-certificates/cert-large-expiration-date.txt.1.0.1");
QVERIFY(f101.open(QIODevice::ReadOnly | QFile::Text));
QByteArray txt101 = f101.readAll();
- QFile f101c(testDataDir + "/more-certificates/cert-large-expiration-date.txt.1.0.1c");
+ QFile f101c(":/more-certificates/cert-large-expiration-date.txt.1.0.1c");
QVERIFY(f101c.open(QIODevice::ReadOnly | QFile::Text));
QByteArray txt101c = f101c.readAll();
@@ -950,8 +928,8 @@ void tst_QSslCertificate::toText()
void tst_QSslCertificate::multipleCommonNames()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/test-cn-two-cns-cert.pem");
- QVERIFY2(certList.count() > 0, "Please run this test from the source directory");
+ QSslCertificate::fromPath(":/more-certificates/test-cn-two-cns-cert.pem");
+ QVERIFY(certList.count() > 0);
QStringList commonNames = certList[0].subjectInfo(QSslCertificate::CommonName);
QVERIFY(commonNames.contains(QString("www.example.com")));
@@ -961,15 +939,15 @@ void tst_QSslCertificate::multipleCommonNames()
void tst_QSslCertificate::subjectAndIssuerAttributes()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/test-cn-with-drink-cert.pem");
- QVERIFY2(certList.count() > 0, "Please run this test from the source directory");
+ QSslCertificate::fromPath(":/more-certificates/test-cn-with-drink-cert.pem");
+ QVERIFY(certList.count() > 0);
QList<QByteArray> attributes = certList[0].subjectInfoAttributes();
QVERIFY(attributes.contains(QByteArray("favouriteDrink")));
attributes.clear();
- certList = QSslCertificate::fromPath(testDataDir + "/more-certificates/natwest-banking.pem");
- QVERIFY2(certList.count() > 0, "Please run this test from the source directory");
+ certList = QSslCertificate::fromPath(":/more-certificates/natwest-banking.pem");
+ QVERIFY(certList.count() > 0);
attributes = certList[0].subjectInfoAttributes();
QVERIFY(attributes.contains(QByteArray("1.3.6.1.4.1.311.60.2.1.3")));
@@ -999,17 +977,17 @@ void tst_QSslCertificate::verify()
errors.clear();
// Verify a valid cert signed by a CA
- QList<QSslCertificate> caCerts = QSslCertificate::fromPath(testDataDir + "/verify-certs/cacert.pem");
+ QList<QSslCertificate> caCerts = QSslCertificate::fromPath(":/verify-certs/cacert.pem");
QSslSocket::addDefaultCaCertificate(caCerts.first());
- toVerify = QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ toVerify = QSslCertificate::fromPath(":/verify-certs/test-ocsp-good-cert.pem");
errors = QSslCertificate::verify(toVerify);
VERIFY_VERBOSE(errors.count() == 0);
errors.clear();
// Test a blacklisted certificate
- toVerify = QSslCertificate::fromPath(testDataDir + "/verify-certs/test-addons-mozilla-org-cert.pem");
+ toVerify = QSslCertificate::fromPath(":/verify-certs/test-addons-mozilla-org-cert.pem");
errors = QSslCertificate::verify(toVerify);
bool foundBlack = false;
foreach (const QSslError &error, errors) {
@@ -1022,7 +1000,7 @@ void tst_QSslCertificate::verify()
errors.clear();
// This one is expired and untrusted
- toVerify = QSslCertificate::fromPath(testDataDir + "/more-certificates/cert-large-serial-number.pem");
+ toVerify = QSslCertificate::fromPath(":/more-certificates/cert-large-serial-number.pem");
errors = QSslCertificate::verify(toVerify);
VERIFY_VERBOSE(errors.contains(QSslError(QSslError::SelfSignedCertificate, toVerify[0])));
VERIFY_VERBOSE(errors.contains(QSslError(QSslError::CertificateExpired, toVerify[0])));
@@ -1030,15 +1008,15 @@ void tst_QSslCertificate::verify()
toVerify.clear();
// This one is signed by a valid cert, but the signer is not a valid CA
- toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-not-ca-cert.pem").first();
- toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem").first();
+ toVerify << QSslCertificate::fromPath(":/verify-certs/test-intermediate-not-ca-cert.pem").first();
+ toVerify << QSslCertificate::fromPath(":/verify-certs/test-ocsp-good-cert.pem").first();
errors = QSslCertificate::verify(toVerify);
VERIFY_VERBOSE(errors.contains(QSslError(QSslError::InvalidCaCertificate, toVerify[1])));
toVerify.clear();
// This one is signed by a valid cert, and the signer is a valid CA
- toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-is-ca-cert.pem").first();
- toVerify << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-intermediate-ca-cert.pem").first();
+ toVerify << QSslCertificate::fromPath(":/verify-certs/test-intermediate-is-ca-cert.pem").first();
+ toVerify << QSslCertificate::fromPath(":/verify-certs/test-intermediate-ca-cert.pem").first();
errors = QSslCertificate::verify(toVerify);
VERIFY_VERBOSE(errors.count() == 0);
@@ -1068,8 +1046,8 @@ QString tst_QSslCertificate::toString(const QList<QSslError>& errors)
void tst_QSslCertificate::extensions()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/more-certificates/natwest-banking.pem");
- QVERIFY2(certList.count() > 0, "Please run this test from the source directory");
+ QSslCertificate::fromPath(":/more-certificates/natwest-banking.pem");
+ QVERIFY(certList.count() > 0);
QSslCertificate cert = certList[0];
QList<QSslCertificateExtension> extensions = cert.extensions();
@@ -1166,8 +1144,8 @@ void tst_QSslCertificate::extensions()
void tst_QSslCertificate::extensionsCritical()
{
QList<QSslCertificate> certList =
- QSslCertificate::fromPath(testDataDir + "/verify-certs/test-addons-mozilla-org-cert.pem");
- QVERIFY2(certList.count() > 0, "Please run this test from the source directory");
+ QSslCertificate::fromPath(":/verify-certs/test-addons-mozilla-org-cert.pem");
+ QVERIFY(certList.count() > 0);
QSslCertificate cert = certList[0];
QList<QSslCertificateExtension> extensions = cert.extensions();
@@ -1249,7 +1227,7 @@ void tst_QSslCertificate::threadSafeConstMethods()
if (!QSslSocket::supportsSsl())
return;
- QByteArray encoded = readFile(testDataDir + "/certificates/cert.pem");
+ QByteArray encoded = readFile(":/certificates/cert.pem");
QSslCertificate certificate(encoded);
QVERIFY(!certificate.isNull());
@@ -1287,12 +1265,12 @@ void tst_QSslCertificate::version_data()
QTest::newRow("null certificate") << QSslCertificate() << QByteArray();
QList<QSslCertificate> certs;
- certs << QSslCertificate::fromPath(testDataDir + "/verify-certs/test-ocsp-good-cert.pem");
+ certs << QSslCertificate::fromPath(":/verify-certs/test-ocsp-good-cert.pem");
QTest::newRow("v3 certificate") << certs.first() << QByteArrayLiteral("3");
certs.clear();
- certs << QSslCertificate::fromPath(testDataDir + "/certificates/cert.pem");
+ certs << QSslCertificate::fromPath(":/certificates/cert.pem");
QTest::newRow("v1 certificate") << certs.first() << QByteArrayLiteral("1");
}
@@ -1314,7 +1292,7 @@ void tst_QSslCertificate::pkcs12()
return;
}
- QFile f(testDataDir + QLatin1String("/pkcs12/leaf.p12"));
+ QFile f(QLatin1String(":/pkcs12/leaf.p12"));
bool ok = f.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -1329,12 +1307,12 @@ void tst_QSslCertificate::pkcs12()
QVERIFY(ok);
f.close();
- QList<QSslCertificate> leafCert = QSslCertificate::fromPath(testDataDir + QLatin1String("/pkcs12/leaf.crt"));
+ QList<QSslCertificate> leafCert = QSslCertificate::fromPath(QLatin1String(":/pkcs12/leaf.crt"));
QVERIFY(!leafCert.isEmpty());
QCOMPARE(cert, leafCert.first());
- QFile f2(testDataDir + QLatin1String("/pkcs12/leaf.key"));
+ QFile f2(QLatin1String(":/pkcs12/leaf.key"));
ok = f2.open(QIODevice::ReadOnly);
QVERIFY(ok);
@@ -1344,7 +1322,7 @@ void tst_QSslCertificate::pkcs12()
QVERIFY(!leafKey.isNull());
QCOMPARE(key, leafKey);
- QList<QSslCertificate> caCert = QSslCertificate::fromPath(testDataDir + QLatin1String("/pkcs12/inter.crt"));
+ QList<QSslCertificate> caCert = QSslCertificate::fromPath(QLatin1String(":/pkcs12/inter.crt"));
QVERIFY(!caCert.isEmpty());
QVERIFY(!caCerts.isEmpty());
@@ -1352,7 +1330,7 @@ void tst_QSslCertificate::pkcs12()
QCOMPARE(caCerts, caCert);
// QTBUG-62335 - Fail (found no private key) but don't crash:
- QFile nocert(testDataDir + QLatin1String("/pkcs12/leaf-nokey.p12"));
+ QFile nocert(QLatin1String(":/pkcs12/leaf-nokey.p12"));
ok = nocert.open(QIODevice::ReadOnly);
QVERIFY(ok);
QTest::ignoreMessage(QtWarningMsg, "Unable to convert private key");
diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.pro b/tests/auto/network/ssl/qsslkey/qsslkey.pro
index 8c3877631a..760369df39 100644
--- a/tests/auto/network/ssl/qsslkey/qsslkey.pro
+++ b/tests/auto/network/ssl/qsslkey/qsslkey.pro
@@ -9,4 +9,7 @@ qtConfig(private_tests) {
TARGET = tst_qsslkey
+RESOURCES += \
+ qsslkey.qrc
+
TESTDATA += keys/* rsa-without-passphrase.pem rsa-with-passphrase.pem
diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.qrc b/tests/auto/network/ssl/qsslkey/qsslkey.qrc
new file mode 100644
index 0000000000..4b994ac7af
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/qsslkey.qrc
@@ -0,0 +1,65 @@
+<RCC>
+ <qresource prefix="/">
+ <file>rsa-without-passphrase.pem</file>
+ <file>rsa-with-passphrase-3des.pem</file>
+ <file>rsa-with-passphrase-des.pem</file>
+ <file>rsa-with-passphrase-rc2.pem</file>
+ <file>keys/dsa-pri-1024.der</file>
+ <file>keys/dsa-pri-1024.pem</file>
+ <file>keys/dsa-pri-512.der</file>
+ <file>keys/dsa-pri-512.pem</file>
+ <file>keys/dsa-pri-576.der</file>
+ <file>keys/dsa-pri-576.pem</file>
+ <file>keys/dsa-pri-960.der</file>
+ <file>keys/dsa-pri-960.pem</file>
+ <file>keys/dsa-pub-1024.der</file>
+ <file>keys/dsa-pub-1024.pem</file>
+ <file>keys/dsa-pub-512.der</file>
+ <file>keys/dsa-pub-512.pem</file>
+ <file>keys/dsa-pub-576.der</file>
+ <file>keys/dsa-pub-576.pem</file>
+ <file>keys/dsa-pub-960.der</file>
+ <file>keys/dsa-pub-960.pem</file>
+ <file>keys/ec-pri-224-secp224r1.der</file>
+ <file>keys/ec-pri-224-secp224r1.pem</file>
+ <file>keys/ec-pri-256-prime256v1.der</file>
+ <file>keys/ec-pri-256-prime256v1.pem</file>
+ <file>keys/ec-pri-384-secp384r1.der</file>
+ <file>keys/ec-pri-384-secp384r1.pem</file>
+ <file>keys/ec-pub-224-secp224r1.der</file>
+ <file>keys/ec-pub-224-secp224r1.pem</file>
+ <file>keys/ec-pub-256-prime256v1.der</file>
+ <file>keys/ec-pub-256-prime256v1.pem</file>
+ <file>keys/ec-pub-384-secp384r1.der</file>
+ <file>keys/ec-pub-384-secp384r1.pem</file>
+ <file>keys/genkeys.sh</file>
+ <file>keys/rsa-pri-1023.der</file>
+ <file>keys/rsa-pri-1023.pem</file>
+ <file>keys/rsa-pri-1024.der</file>
+ <file>keys/rsa-pri-1024.pem</file>
+ <file>keys/rsa-pri-2048.der</file>
+ <file>keys/rsa-pri-2048.pem</file>
+ <file>keys/rsa-pri-40.der</file>
+ <file>keys/rsa-pri-40.pem</file>
+ <file>keys/rsa-pri-511.der</file>
+ <file>keys/rsa-pri-511.pem</file>
+ <file>keys/rsa-pri-512.der</file>
+ <file>keys/rsa-pri-512.pem</file>
+ <file>keys/rsa-pri-999.der</file>
+ <file>keys/rsa-pri-999.pem</file>
+ <file>keys/rsa-pub-1023.der</file>
+ <file>keys/rsa-pub-1023.pem</file>
+ <file>keys/rsa-pub-1024.der</file>
+ <file>keys/rsa-pub-1024.pem</file>
+ <file>keys/rsa-pub-2048.der</file>
+ <file>keys/rsa-pub-2048.pem</file>
+ <file>keys/rsa-pub-40.der</file>
+ <file>keys/rsa-pub-40.pem</file>
+ <file>keys/rsa-pub-511.der</file>
+ <file>keys/rsa-pub-511.pem</file>
+ <file>keys/rsa-pub-512.der</file>
+ <file>keys/rsa-pub-512.pem</file>
+ <file>keys/rsa-pub-999.der</file>
+ <file>keys/rsa-pub-999.pem</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
index 0112af4ed7..3c88cddf9a 100644
--- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
+++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
@@ -97,17 +97,11 @@ private slots:
#endif
#endif
-private:
- QString testDataDir;
};
void tst_QSslKey::initTestCase()
{
- testDataDir = QFileInfo(QFINDTESTDATA("rsa-without-passphrase.pem")).absolutePath();
- if (testDataDir.isEmpty())
- testDataDir = QCoreApplication::applicationDirPath();
-
- QDir dir(testDataDir + "/keys");
+ QDir dir(":/keys");
QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?\\w*\\.(pem|der)$"));
foreach (QFileInfo fileInfo, fileInfoList) {
@@ -392,9 +386,9 @@ void tst_QSslKey::passphraseChecks_data()
{
QTest::addColumn<QString>("fileName");
- QTest::newRow("DES") << QString(testDataDir + "/rsa-with-passphrase-des.pem");
- QTest::newRow("3DES") << QString(testDataDir + "/rsa-with-passphrase-3des.pem");
- QTest::newRow("RC2") << QString(testDataDir + "/rsa-with-passphrase-rc2.pem");
+ QTest::newRow("DES") << QString(":/rsa-with-passphrase-des.pem");
+ QTest::newRow("3DES") << QString(":/rsa-with-passphrase-3des.pem");
+ QTest::newRow("RC2") << QString(":/rsa-with-passphrase-rc2.pem");
}
void tst_QSslKey::passphraseChecks()
@@ -440,7 +434,7 @@ void tst_QSslKey::passphraseChecks()
void tst_QSslKey::noPassphraseChecks()
{
// be sure and check a key without passphrase too
- QString fileName(testDataDir + "/rsa-without-passphrase.pem");
+ QString fileName(":/rsa-without-passphrase.pem");
QFile keyFile(fileName);
{
if (!keyFile.isOpen())
diff --git a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
index 4ccf0f24b0..5249c1aac5 100644
--- a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
+++ b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
@@ -14,6 +14,9 @@ win32 {
}
}
+RESOURCES += \
+ qsslsocket.qrc
+
DEFINES += SRCDIR=\\\"$$PWD/\\\"
requires(qtConfig(private_tests))
diff --git a/tests/auto/network/ssl/qsslsocket/qsslsocket.qrc b/tests/auto/network/ssl/qsslsocket/qsslsocket.qrc
new file mode 100644
index 0000000000..fb486c8e0b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslsocket/qsslsocket.qrc
@@ -0,0 +1,21 @@
+<RCC>
+ <qresource prefix="/">
+ <file>certs/aspiriniks.ca.crt</file>
+ <file>certs/bogus-ca.crt</file>
+ <file>certs/bogus-ca.key</file>
+ <file>certs/bogus-client.crt</file>
+ <file>certs/bogus-client.key</file>
+ <file>certs/bogus-server.crt</file>
+ <file>certs/bogus-server.key</file>
+ <file>certs/ca.crt</file>
+ <file>certs/fake-login.live.com.key</file>
+ <file>certs/fake-login.live.com.pem</file>
+ <file>certs/fluke.cert</file>
+ <file>certs/fluke.key</file>
+ <file>certs/inter.crt</file>
+ <file>certs/leaf.crt</file>
+ <file>certs/leaf.key</file>
+ <file>certs/qt-test-server-cacert.pem</file>
+ <file>certs/xn--schufele-2za.crt</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 8324a9c8fa..4e12a16696 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -705,7 +705,7 @@ void tst_QSslSocket::connectToHostEncrypted()
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
- QVERIFY(socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")));
+ QVERIFY(socket->addCaCertificates(QLatin1String(":/certs/qt-test-server-cacert.pem")));
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
@@ -739,7 +739,7 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
- socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ socket->addCaCertificates(QLatin1String(":/certs/qt-test-server-cacert.pem"));
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
@@ -803,10 +803,10 @@ void tst_QSslSocket::localCertificate()
// values. This test should just run the codepath inside qsslsocket_openssl.cpp
QSslSocketPtr socket = newSocket();
- QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> localCert = QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem");
socket->setCaCertificates(localCert);
- socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
- socket->setPrivateKey(QLatin1String(SRCDIR "certs/fluke.key"));
+ socket->setLocalCertificate(QLatin1String(":/certs/fluke.cert"));
+ socket->setPrivateKey(QLatin1String(":/certs/fluke.key"));
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
QFETCH_GLOBAL(bool, setProxy);
@@ -832,7 +832,7 @@ void tst_QSslSocket::peerCertificateChain()
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
- QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(":/certs/qt-test-server-cacert.pem"));
QCOMPARE(caCertificates.count(), 1);
socket->addCaCertificates(caCertificates);
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
@@ -895,7 +895,7 @@ void tst_QSslSocket::privateKeyOpaque()
if (!QSslSocket::supportsSsl())
return;
- QFile file(SRCDIR "certs/fluke.key");
+ QFile file(":/certs/fluke.key");
QVERIFY(file.open(QIODevice::ReadOnly));
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!key.isNull());
@@ -908,9 +908,9 @@ void tst_QSslSocket::privateKeyOpaque()
// values. This test should just run the codepath inside qsslsocket_openssl.cpp
QSslSocketPtr socket = newSocket();
- QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> localCert = QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem");
socket->setCaCertificates(localCert);
- socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
+ socket->setLocalCertificate(QLatin1String(":/certs/fluke.cert"));
socket->setPrivateKey(QSslKey(reinterpret_cast<Qt::HANDLE>(pkey)));
socket->setPeerVerifyMode(QSslSocket::QueryPeer);
@@ -928,7 +928,7 @@ void tst_QSslSocket::protocol()
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
- QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem");
socket->setCaCertificates(certs);
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
@@ -1075,8 +1075,8 @@ class SslServer : public QTcpServer
{
Q_OBJECT
public:
- SslServer(const QString &keyFile = SRCDIR "certs/fluke.key",
- const QString &certFile = SRCDIR "certs/fluke.cert",
+ SslServer(const QString &keyFile = ":/certs/fluke.key",
+ const QString &certFile = ":/certs/fluke.cert",
const QString &interFile = QString())
: socket(0),
config(QSslConfiguration::defaultConfiguration()),
@@ -1167,6 +1167,9 @@ protected slots:
void tst_QSslSocket::protocolServerSide_data()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QTest::addColumn<QSsl::SslProtocol>("serverProtocol");
QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
QTest::addColumn<bool>("works");
@@ -1347,6 +1350,9 @@ void tst_QSslSocket::protocolServerSide()
void tst_QSslSocket::serverCipherPreferences()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl()) {
qWarning("SSL not supported, skipping test");
return;
@@ -1422,7 +1428,7 @@ void tst_QSslSocket::setCaCertificates()
QSslSocket socket;
QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
- socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"));
+ socket.setCaCertificates(QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem"));
QCOMPARE(socket.caCertificates().size(), 1);
socket.setCaCertificates(socket.defaultCaCertificates());
QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
@@ -1438,7 +1444,7 @@ void tst_QSslSocket::localCertificateChain()
return;
QSslSocket socket;
- socket.setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
+ socket.setLocalCertificate(QLatin1String(":/certs/fluke.cert"));
QSslConfiguration conf = socket.sslConfiguration();
QList<QSslCertificate> chain = conf.localCertificateChain();
@@ -1449,6 +1455,9 @@ void tst_QSslSocket::localCertificateChain()
void tst_QSslSocket::setLocalCertificateChain()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl())
return;
@@ -1456,9 +1465,9 @@ void tst_QSslSocket::setLocalCertificateChain()
if (setProxy)
return;
- SslServer server(QLatin1String(SRCDIR "certs/leaf.key"),
- QLatin1String(SRCDIR "certs/leaf.crt"),
- QLatin1String(SRCDIR "certs/inter.crt"));
+ SslServer server(QLatin1String(":/certs/leaf.key"),
+ QLatin1String(":/certs/leaf.crt"),
+ QLatin1String(":/certs/inter.crt"));
QVERIFY(server.listen());
@@ -1486,6 +1495,9 @@ void tst_QSslSocket::setPrivateKey()
void tst_QSslSocket::setSocketDescriptor()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl())
return;
@@ -1524,7 +1536,7 @@ void tst_QSslSocket::setSslConfiguration_data()
QTest::newRow("empty") << QSslConfiguration() << false;
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
QTest::newRow("default") << conf << false; // does not contain test server cert
- QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem");
conf.setCaCertificates(testServerCert);
QTest::newRow("set-root-cert") << conf << true;
conf.setProtocol(QSsl::SecureProtocols);
@@ -1627,7 +1639,7 @@ void tst_QSslSocket::addDefaultCaCertificate()
// Reset the global CA chain
QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
- QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(":/certs/qt-test-server-cacert.pem");
QCOMPARE(flukeCerts.size(), 1);
QList<QSslCertificate> globalCerts = QSslSocket::defaultCaCertificates();
QVERIFY(!globalCerts.contains(flukeCerts.first()));
@@ -1739,7 +1751,7 @@ void tst_QSslSocket::isMatchingHostname()
{
// with normalization: (the certificate has *.SCHÄUFELE.DE as a CN)
// openssl req -x509 -nodes -subj "/CN=*.SCHÄUFELE.DE" -newkey rsa:512 -keyout /dev/null -out xn--schufele-2za.crt
- QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/xn--schufele-2za.crt");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(":/certs/xn--schufele-2za.crt");
QVERIFY(!certs.isEmpty());
QSslCertificate cert = certs.first();
@@ -1795,7 +1807,7 @@ protected:
socket->ignoreSslErrors();
// Only set the certificate
- QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
+ QList<QSslCertificate> localCert = QSslCertificate::fromPath(":/certs/fluke.cert");
QVERIFY(!localCert.isEmpty());
QVERIFY(!localCert.first().isNull());
socket->setLocalCertificate(localCert.first());
@@ -1808,6 +1820,9 @@ protected:
void tst_QSslSocket::setEmptyKey()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl())
return;
@@ -1829,6 +1844,9 @@ void tst_QSslSocket::setEmptyKey()
void tst_QSslSocket::spontaneousWrite()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -1874,6 +1892,9 @@ void tst_QSslSocket::spontaneousWrite()
void tst_QSslSocket::setReadBufferSize()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2024,13 +2045,13 @@ protected:
socket = new QSslSocket(this);
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
- QFile file(SRCDIR "certs/fluke.key");
+ QFile file(":/certs/fluke.key");
QVERIFY(file.open(QIODevice::ReadOnly));
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!key.isNull());
socket->setPrivateKey(key);
- QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
+ QList<QSslCertificate> localCert = QSslCertificate::fromPath(":/certs/fluke.cert");
QVERIFY(!localCert.isEmpty());
QVERIFY(!localCert.first().isNull());
socket->setLocalCertificate(localCert.first());
@@ -2134,6 +2155,9 @@ void tst_QSslSocket::waitForMinusOne()
#ifdef Q_OS_WIN
QSKIP("QTBUG-24451 - indefinite wait may hang");
#endif
+#ifdef Q_OS_WINRT // This can stay in case the one above goes away
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2203,8 +2227,8 @@ protected:
{
socket = new QSslSocket(this);
- socket->setPrivateKey(SRCDIR "certs/fluke.key");
- socket->setLocalCertificate(SRCDIR "certs/fluke.cert");
+ socket->setPrivateKey(":/certs/fluke.key");
+ socket->setLocalCertificate(":/certs/fluke.cert");
socket->setSocketDescriptor(socketDescriptor);
socket->startServerEncryption();
}
@@ -2212,6 +2236,9 @@ protected:
void tst_QSslSocket::verifyMode()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2319,7 +2346,7 @@ void tst_QSslSocket::resetProxy()
// make sure the connection works, and then set a nonsense proxy, and then
// make sure it does not work anymore
QSslSocket socket;
- socket.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ socket.addCaCertificates(QLatin1String(":/certs/qt-test-server-cacert.pem"));
socket.setProxy(goodProxy);
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
QVERIFY2(socket.waitForConnected(10000), qPrintable(socket.errorString()));
@@ -2338,7 +2365,7 @@ void tst_QSslSocket::resetProxy()
// set the nonsense proxy and make sure the connection does not work,
// and then set the right proxy and make sure it works
QSslSocket socket2;
- socket2.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ socket2.addCaCertificates(QLatin1String(":/certs/qt-test-server-cacert.pem"));
socket2.setProxy(badProxy);
socket2.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
QVERIFY(! socket2.waitForConnected(10000));
@@ -2357,7 +2384,7 @@ void tst_QSslSocket::ignoreSslErrorsList_data()
// construct the list of errors that we will get with the SSL handshake and that we will ignore
QList<QSslError> expectedSslErrors;
// fromPath gives us a list of certs, but it actually only contains one
- QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(":/certs/qt-test-server-cacert.pem"));
QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0));
QSslError wrongError(FLUKE_CERTIFICATE_ERROR);
@@ -2430,6 +2457,9 @@ void tst_QSslSocket::ignoreSslErrorsListWithSlot()
void tst_QSslSocket::abortOnSslErrors()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2526,11 +2556,14 @@ void tst_QSslSocket::writeBigChunk()
void tst_QSslSocket::blacklistedCertificates()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
- SslServer server(SRCDIR "certs/fake-login.live.com.key", SRCDIR "certs/fake-login.live.com.pem");
+ SslServer server(":/certs/fake-login.live.com.key", ":/certs/fake-login.live.com.pem");
QSslSocket *receiver = new QSslSocket(this);
connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
@@ -2642,7 +2675,7 @@ void tst_QSslSocket::resume_data()
QTest::newRow("DoNotIgnoreErrors") << false << QList<QSslError>() << false;
QTest::newRow("ignoreAllErrors") << true << QList<QSslError>() << true;
- QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(":/certs/qt-test-server-cacert.pem"));
QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0));
QSslError wrongError(FLUKE_CERTIFICATE_ERROR);
errorsList.append(wrongError);
@@ -2712,8 +2745,8 @@ class WebSocket : public QSslSocket
Q_OBJECT
public:
explicit WebSocket(qintptr socketDescriptor,
- const QString &keyFile = SRCDIR "certs/fluke.key",
- const QString &certFile = SRCDIR "certs/fluke.cert");
+ const QString &keyFile = ":/certs/fluke.key",
+ const QString &certFile = ":/certs/fluke.cert");
protected slots:
void onReadyReadFirstBytes(void);
@@ -2783,6 +2816,9 @@ protected:
void tst_QSslSocket::qtbug18498_peek()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2850,6 +2886,9 @@ protected:
void tst_QSslSocket::qtbug18498_peek2()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2918,13 +2957,13 @@ void tst_QSslSocket::qtbug18498_peek2()
QCOMPARE(a[2], 'S');
QCOMPARE(server->readAll(), QByteArray("TLS\r\n"));
- QFile file(SRCDIR "certs/fluke.key");
+ QFile file(":/certs/fluke.key");
QVERIFY(file.open(QIODevice::ReadOnly));
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!key.isNull());
server->setPrivateKey(key);
- QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
+ QList<QSslCertificate> localCert = QSslCertificate::fromPath(":/certs/fluke.cert");
QVERIFY(!localCert.isEmpty());
QVERIFY(!localCert.first().isNull());
server->setLocalCertificate(localCert.first());
@@ -2964,6 +3003,9 @@ void tst_QSslSocket::qtbug18498_peek2()
void tst_QSslSocket::dhServer()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl())
QSKIP("No SSL support");
@@ -3073,6 +3115,9 @@ void tst_QSslSocket::dhServerCustomParams()
void tst_QSslSocket::ecdhServer()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl()) {
qWarning("SSL not supported, skipping test");
return;
@@ -3118,10 +3163,10 @@ void tst_QSslSocket::verifyClientCertificate_data()
QTest::newRow("NoCert:VerifyPeer") << QSslSocket::VerifyPeer << noCerts << noKey << false;
// self-signed certificate
- QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
+ QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(":/certs/fluke.cert");
QCOMPARE(flukeCerts.size(), 1);
- QFile flukeFile(SRCDIR "certs/fluke.key");
+ QFile flukeFile(":/certs/fluke.key");
QVERIFY(flukeFile.open(QIODevice::ReadOnly));
QSslKey flukeKey(flukeFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!flukeKey.isNull());
@@ -3132,10 +3177,10 @@ void tst_QSslSocket::verifyClientCertificate_data()
QTest::newRow("SelfSignedCert:VerifyPeer") << QSslSocket::VerifyPeer << flukeCerts << flukeKey << false;
// valid certificate, but wrong usage (server certificate)
- QList<QSslCertificate> serverCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-server.crt");
+ QList<QSslCertificate> serverCerts = QSslCertificate::fromPath(":/certs/bogus-server.crt");
QCOMPARE(serverCerts.size(), 1);
- QFile serverFile(SRCDIR "certs/bogus-server.key");
+ QFile serverFile(":/certs/bogus-server.key");
QVERIFY(serverFile.open(QIODevice::ReadOnly));
QSslKey serverKey(serverFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!serverKey.isNull());
@@ -3146,10 +3191,10 @@ void tst_QSslSocket::verifyClientCertificate_data()
QTest::newRow("ValidServerCert:VerifyPeer") << QSslSocket::VerifyPeer << serverCerts << serverKey << false;
// valid certificate, correct usage (client certificate)
- QList<QSslCertificate> validCerts = QSslCertificate::fromPath(SRCDIR "certs/bogus-client.crt");
+ QList<QSslCertificate> validCerts = QSslCertificate::fromPath(":/certs/bogus-client.crt");
QCOMPARE(validCerts.size(), 1);
- QFile validFile(SRCDIR "certs/bogus-client.key");
+ QFile validFile(":/certs/bogus-client.key");
QVERIFY(validFile.open(QIODevice::ReadOnly));
QSslKey validKey(validFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
QVERIFY(!validKey.isNull());
@@ -3160,7 +3205,7 @@ void tst_QSslSocket::verifyClientCertificate_data()
QTest::newRow("ValidClientCert:VerifyPeer") << QSslSocket::VerifyPeer << validCerts << validKey << true;
// valid certificate, correct usage (client certificate), with chain
- validCerts += QSslCertificate::fromPath(SRCDIR "certs/bogus-ca.crt");
+ validCerts += QSslCertificate::fromPath(":/certs/bogus-ca.crt");
QCOMPARE(validCerts.size(), 2);
QTest::newRow("ValidClientCert:AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << validCerts << validKey << true;
@@ -3179,6 +3224,9 @@ void tst_QSslSocket::verifyClientCertificate()
// success instead of failure etc.).
QSKIP("This test can not work with Secure Transport");
#endif
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
if (!QSslSocket::supportsSsl()) {
qWarning("SSL not supported, skipping test");
return;
@@ -3190,7 +3238,7 @@ void tst_QSslSocket::verifyClientCertificate()
QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode);
SslServer server;
- server.addCaCertificates = QLatin1String(SRCDIR "certs/bogus-ca.crt");
+ server.addCaCertificates = QLatin1String(":/certs/bogus-ca.crt");
server.ignoreSslErrors = false;
server.peerVerifyMode = peerVerifyMode;
QVERIFY(server.listen());
@@ -3689,6 +3737,9 @@ void tst_QSslSocket::simplePskConnect()
void tst_QSslSocket::ephemeralServerKey_data()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QTest::addColumn<QString>("cipher");
QTest::addColumn<bool>("emptyKey");
@@ -3763,6 +3814,9 @@ void tst_QSslSocket::allowedProtocolNegotiation()
void tst_QSslSocket::pskServer()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Server-side encryption is not implemented on WinRT.");
+#endif
QFETCH_GLOBAL(bool, setProxy);
if (!QSslSocket::supportsSsl() || setProxy)
return;