summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-04-20 12:25:51 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-04-20 12:25:51 +0200
commit4171a98ca5e69683615ffc1b743a0407e4bc7c51 (patch)
tree762d5b9ba30bf1db60274a5230b6d77e40097f87
parentcff39fba10ffc10ee4dcfdc66ff6528eb26462d3 (diff)
parent50ce5a68301dee2fd00b7c6ccc615257a2353098 (diff)
Merge 5.4 into 5.4.2
-rw-r--r--config.tests/unix/floatmath/floatmath.cpp2
-rw-r--r--doc/global/html-footer-online.qdocconf17
-rw-r--r--doc/global/html-header-online.qdocconf15
-rw-r--r--doc/global/template/scripts/extras.js6
-rw-r--r--doc/global/template/scripts/main.js6
-rw-r--r--doc/global/template/style/online.css8
-rw-r--r--src/3rdparty/pcre/pcre_compile.c142
-rw-r--r--src/3rdparty/pcre/pcre_dfa_exec.c5
-rw-r--r--src/3rdparty/pcre/pcre_exec.c20
-rw-r--r--src/3rdparty/pcre/pcre_jit_compile.c8
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.c6
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.h12
-rw-r--r--src/corelib/io/qlockfile_unix.cpp10
-rw-r--r--src/corelib/io/qlockfile_win.cpp22
-rw-r--r--src/corelib/io/qwindowspipereader.cpp102
-rw-r--r--src/corelib/io/qwindowspipereader_p.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm6
-rw-r--r--src/widgets/kernel/qapplication.cpp7
-rw-r--r--src/widgets/kernel/qapplication_p.h2
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp17
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp53
21 files changed, 300 insertions, 170 deletions
diff --git a/config.tests/unix/floatmath/floatmath.cpp b/config.tests/unix/floatmath/floatmath.cpp
index c8540c6d1d..9ac7884377 100644
--- a/config.tests/unix/floatmath/floatmath.cpp
+++ b/config.tests/unix/floatmath/floatmath.cpp
@@ -33,7 +33,7 @@
#include <math.h>
-int main(int argc, char **argv)
+int main(int, char **)
{
float c = ceilf(1.3f);
float f = floorf(1.7f);
diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf
index 5c72819341..1937d97cbb 100644
--- a/doc/global/html-footer-online.qdocconf
+++ b/doc/global/html-footer-online.qdocconf
@@ -13,12 +13,12 @@ HTML.footer += \
" <nav class=\"footer-nav clearfix\">\n" \
" <div class=\"menu-footer-menu-container\"><ul id=\"menu-footer-menu\" class=\"menu\"><li id=\"menu-item-1350\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1350\"><a href=\"http://qt.io/about-us/\">About us</a>\n" \
"<ul class=\"sub-menu\">\n" \
- " <li id=\"menu-item-1353\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1353\"><a href=\"http://qt.io/events/\">Events</a></li>\n" \
+ " <li id=\"menu-item-1353\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1353\"><a href=\"http://qt.io/events/\">Training &amp; Events</a></li>\n" \
" <li id=\"menu-item-1596\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1596\"><a href=\"http://qt.io/news/\">News</a></li>\n" \
" <li id=\"menu-item-1354\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1354\"><a href=\"http://qt.io/resource-center/\">Resource Center</a></li>\n" \
" <li id=\"menu-item-1352\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1352\"><a href=\"http://qt.io/partners/\">Partners</a></li>\n" \
" <li id=\"menu-item-1349\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1349\"><a href=\"http://qt.io/careers/\">Careers</a></li>\n" \
- " <li id=\"menu-item-1415\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1415\"><a href=\"http://qt.io/terms-conditions/\">Terms &amp; Conditions</a></li>\n" \
+ " <li id=\"menu-item-11676\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-11676\"><a href=\"http://qt.io/locations/\">Locations</a></li>\n" \
"</ul>\n" \
"</li>\n" \
"<li id=\"menu-item-1355\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1355\"><a href=\"http://qt.io/product/\">Product</a>\n" \
@@ -28,7 +28,7 @@ HTML.footer += \
" <li id=\"menu-item-1359\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1359\"><a href=\"http://qt.io/qt-quick/\">Qt Quick</a></li>\n" \
" <li id=\"menu-item-1357\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1357\"><a href=\"http://qt.io/qt-for-device-creation/\">Qt for Device Creation</a></li>\n" \
" <li id=\"menu-item-10159\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-10159\"><a href=\"http://qt.io/mobile-app-development/\">Qt for Mobile Apps</a></li>\n" \
- " <li id=\"menu-item-1366\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1366\"><a href=\"http://showroom.qt-project.org/\">Showroom</a></li>\n" \
+ " <li id=\"menu-item-12576\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12576\"><a href=\"http://qt.io/qt-in-use/\">Qt in Use</a></li>\n" \
"</ul>\n" \
"</li>\n" \
"<li id=\"menu-item-33\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-33\"><a href=\"http://qt.io/developers/\">Developers</a>\n" \
@@ -53,18 +53,19 @@ HTML.footer += \
"</li>\n" \
"<li id=\"menu-item-1403\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1403\"><a href=\"http://qt.io/download/\">Download</a>\n" \
"<ul class=\"sub-menu\">\n" \
- " <li id=\"menu-item-1985\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1985\"><a title=\"Professional\" href=\"http://qt.io/buy/\">Professional</a></li>\n" \
- " <li id=\"menu-item-3346\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3346\"><a title=\"Indie Mobile\" href=\"http://qt.io/download-mobile/\">Indie Mobile</a></li>\n" \
- " <li id=\"menu-item-1982\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1982\"><a title=\"Enterprise\" href=\"http://qt.io/download-enterprise-step-2/\">Enterprise</a></li>\n" \
- " <li id=\"menu-item-3013\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3013\"><a title=\"Evaluation\" href=\"http://qt.io/download-eval-step-2/\">Evaluation</a></li>\n" \
+ " <li id=\"menu-item-11677\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-11677\"><a href=\"http://qt.io/download/\">Free 30-Day Trial</a></li>\n" \
+ " <li id=\"menu-item-1982\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1982\"><a href=\"http://qt.io/buy-enterprise-step-2/\">Enterprise</a></li>\n" \
+ " <li id=\"menu-item-1985\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1985\"><a href=\"http://qt.io/buy-professional-step-2/\">Professional</a></li>\n" \
+ " <li id=\"menu-item-3346\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3346\"><a href=\"http://qt.io/buy-indiemobile-step-2/\">Indie Mobile</a></li>\n" \
" <li id=\"menu-item-3343\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-3343\"><a href=\"http://qt.io/download-open-source/\">Community</a></li>\n" \
+ " <li id=\"menu-item-1415\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1415\"><a href=\"http://qt.io/terms-conditions/\">Legal | Terms &amp; Conditions</a></li>\n" \
"</ul>\n" \
"</li>\n" \
"</ul></div></nav>\n" \
"<a href=\"http://qt.io/about-us/\" target=\"_blank\" class=\"theqtcompany\"></a>\n" \
" <div class=\"footer-social clearfix\">\n" \
" <div class=\"facebook\">\n" \
- " <iframe scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" src=\"//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fqtbydigia&amp;width&amp;layout=button_count&amp;action=like&amp;show_faces=true&amp;share=false&amp;height=21\" style=\"border:none;overflow:hidden;height:21px;\"></iframe>\n" \
+ " <iframe scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" src=\"//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fqt&amp;width&amp;layout=button_count&amp;action=like&amp;show_faces=true&amp;share=false&amp;height=21\" style=\"border:none;overflow:hidden;height:21px;\"></iframe>\n" \
" </div>\n" \
" <div class=\"twitter\">\n" \
" <iframe id=\"twitter-widget-0\" scrolling=\"no\" frameborder=\"0\" allowtransparency=\"true\" src=\"http://platform.twitter.com/widgets/follow_button.33b190ea0cba008796487b65df7f6d8e.en.html#_=1414403615717&amp;id=twitter-widget-0&amp;lang=en&amp;screen_name=qtproject&amp;show_count=true&amp;show_screen_name=false&amp;size=m\" class=\"twitter-follow-button twitter-follow-button\" title=\"Twitter Follow Button\" data-twttr-rendered=\"true\" style=\"width: 160px; height: 20px;\"></iframe>\n" \
diff --git a/doc/global/html-header-online.qdocconf b/doc/global/html-header-online.qdocconf
index e6dcbe19fa..aa67c43947 100644
--- a/doc/global/html-header-online.qdocconf
+++ b/doc/global/html-header-online.qdocconf
@@ -29,7 +29,7 @@ HTML.headerstyles = \
HTML.headerscripts = \
" <script type=\"text/javascript\"> wpThemeFolder = \'http://qt.io/wp-content/themes/oneqt\'; </script>\n" \
- " <script type=\"text/javascript\" src=\"http://d3hp9ud7yvwzy0.cloudfront.net/wp-content/themes/oneqt/js/combo.js.gzip\"></script>\n" \
+ " <script type=\"text/javascript\" src=\"//d3hp9ud7yvwzy0.cloudfront.net/wp-content/themes/oneqt/js/combo.js.gzip\"></script>\n" \
" <script type=\"text/javascript\" src=\"scripts/main.js\"></script>\n" \
" <script type=\"text/javascript\" src=\"scripts/extras.js\"></script>\n" \
" <script type=\"text/javascript\">\n" \
@@ -62,7 +62,7 @@ HTML.postheader = \
"<header id=\"navbar\" class=\"\">\n" \
" <div class=\"cookies_yum\">\n" \
" <div>\n" \
- " <img src=\"http://qt.io/wp-content/themes/oneqt/assets/images/cookie_small.png\" align=\"left\">\n" \
+ " <img src=\"//d3hp9ud7yvwzy0.cloudfront.net/wp-content/themes/oneqt/assets/images/cookie_small.png\" align=\"left\">\n" \
" <p class=\"close_button\">\n" \
" We bake cookies in your browser for a better experience. Using this site means that you consent. <a href=\"//qt.io/terms-conditions/\">Read More</a>\n" \
" </p>\n" \
@@ -95,12 +95,11 @@ HTML.postheader = \
" <a href=\"http://qt.io/\" class=\"navbar-oneQt retina\" data-icon=\"\">\n" \
" </a>\n" \
" <nav class=\"navbar-menu clearfix\" role=\"navigation\">\n" \
- " <ul id=\"mainmenu\" class=\"menu\"><li id=\"menu-item-21\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-21\"><a href=\"http://qt.io/product/\">Product</a></li>\n" \
- "<li id=\"menu-item-1381\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1381\"><a href=\"http://qt.io/services/\">Services</a></li>\n" \
- "<li id=\"menu-item-22\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-22\"><a href=\"http://qt.io/qt-in-use/\">Qt in Use</a></li>\n" \
- "<li id=\"menu-item-20\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-20\"><a href=\"http://qt.io/developers/\">Developers</a></li>\n" \
- "<li id=\"menu-item-4466\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4466\"><a href=\"http://qt.io/licensing/\">Licensing</a></li>\n" \
- "<li id=\"menu-item-18\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-18\"><a href=\"http://qt.io/download/\">Download</a></li>\n" \
+ " <ul id=\"mainmenu\" class=\"menu\"><li id=\"menu-item-18\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-18\"><a href=\"http://qt.io/download/\">Download</a></li>\n" \
+ "<li id=\"menu-item-12207\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12207\"><a href=\"http://www.qt.io/qt-for-device-creation/\">Device Creation</a></li>\n" \
+ "<li id=\"menu-item-12208\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-12208\"><a href=\"http://www.qt.io/application-development/\">Application Development</a></li>\n" \
+ "<li id=\"menu-item-1381\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1381\"><a href=\"http://www.qt.io/services/\">Services</a></li>\n" \
+ "<li id=\"menu-item-20\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-20\"><a href=\"http://www.qt.io/developers/\">Developers</a></li>\n" \
"</ul> <ul class=\"menuextraslanguages\">\n" \
" <li class=\"active dark\"><a class=\"dark\" href=\"http://qt.io/support/\">EN</a></li><li class=\"dark\"><a class=\"dark\" href=\"http://qt.io/ru/\">RU</a></li><li class=\"dark\"><a class=\"dark\" href=\"http://qt.io/zh-hans/\">ZH</a></li></ul>\n" \
" </nav>\n" \
diff --git a/doc/global/template/scripts/extras.js b/doc/global/template/scripts/extras.js
index 409215f2d8..8a623a037e 100644
--- a/doc/global/template/scripts/extras.js
+++ b/doc/global/template/scripts/extras.js
@@ -4,7 +4,7 @@ $(function () {
$('a[href*=#]:not([href=#])').on('click', function (e) {
if (e.which == 2)
return true;
- var target = $(this.hash);
+ var target = $(this.hash.replace(/(\.)/g, "\\$1"));
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
setTimeout(function () {
@@ -15,10 +15,10 @@ $(function () {
$(window).load(function () {
var h = window.location.hash;
- var re = /[^a-z0-9_\#\-]/i
+ var re = /[^a-z0-9_\.\#\-]/i
if (h.length > 1 && !re.test(h)) {
setTimeout(function () {
- $(window).scrollTop($(h).offset().top - vOffset);
+ $(window).scrollTop($(h.replace(/(\.)/g, "\\$1")).offset().top - vOffset);
}, 0);
}
});
diff --git a/doc/global/template/scripts/main.js b/doc/global/template/scripts/main.js
index 79de4ea5b2..823cebecf8 100644
--- a/doc/global/template/scripts/main.js
+++ b/doc/global/template/scripts/main.js
@@ -36,7 +36,7 @@ function load_sdk(s, id, src) {
fjs.parentNode.insertBefore(js, fjs);
}
$(document).ready(function($) {
- if (document.documentElement.clientWidth < 1220) {
+ if (document.documentElement.clientWidth < 1280) {
oneQt.extraLinksToMain();
}
@@ -76,7 +76,7 @@ $(document).ready(function($) {
$(window).resize(function() {
oneQt.stickySidebar();
oneQt.footerPosition();
- if (document.documentElement.clientWidth < 1220) {
+ if (document.documentElement.clientWidth < 1280) {
oneQt.extraLinksToMain();
} else {
oneQt.mainLinkstoExtra();
@@ -216,7 +216,7 @@ var oneQt = {
var extramenuLinks = $('#menuextras').find('li');
var mainmenu = $('#mainmenu');
var count = 0;
- if ($(extramenuLinks).length > 3) {
+ if ($(extramenuLinks).length > 2) {
$(extramenuLinks).each(function() {
if (count < 3) {
var newLink = $(this);
diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css
index b4f5be18b6..aa2633f26a 100644
--- a/doc/global/template/style/online.css
+++ b/doc/global/template/style/online.css
@@ -25,7 +25,9 @@
min-width:95px;
position:relative;
text-align:center;
- margin:10px 0 0 0
+ border-left:1px solid #eee;
+ border-right:1px solid #eee;
+ padding:10px 0 10px 0
}
#navbar .navbar-toggle:hover figure {
background:#5caa15
@@ -873,13 +875,13 @@ body.qt-account #navbar .navbar-oneQt h2 {
.clearfix .right {
float:right
}
-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
margin:0;
padding:0;
border:0;
font-size:100%
}
-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
vertical-align:baseline
}
body {
diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c
index 7df7fef4bd..3f8174fbd4 100644
--- a/src/3rdparty/pcre/pcre_compile.c
+++ b/src/3rdparty/pcre/pcre_compile.c
@@ -866,6 +866,14 @@ static const pcre_uint8 opcode_possessify[] = {
};
+/* Structure for mutual recursion detection. */
+
+typedef struct recurse_check {
+ struct recurse_check *prev;
+ const pcre_uchar *group;
+} recurse_check;
+
+
/*************************************************
* Find an error text *
@@ -1704,6 +1712,7 @@ Arguments:
utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
atend TRUE if called when the pattern is complete
cd the "compile data" structure
+ recurses chain of recurse_check to catch mutual recursion
Returns: the fixed length,
or -1 if there is no fixed length,
@@ -1713,10 +1722,11 @@ Returns: the fixed length,
*/
static int
-find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
+find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd,
+ recurse_check *recurses)
{
int length = -1;
-
+recurse_check this_recurse;
register int branchlength = 0;
register pcre_uchar *cc = code + 1 + LINK_SIZE;
@@ -1741,7 +1751,8 @@ for (;;)
case OP_ONCE:
case OP_ONCE_NC:
case OP_COND:
- d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
+ d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd,
+ recurses);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
@@ -1775,7 +1786,15 @@ for (;;)
cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
if (cc > cs && cc < ce) return -1; /* Recursion */
- d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
+ else /* Check for mutual recursion */
+ {
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
+ if (r != NULL) return -1; /* Mutual recursion */
+ }
+ this_recurse.prev = recurses;
+ this_recurse.group = cs;
+ d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd, &this_recurse);
if (d < 0) return d;
branchlength += d;
cc += 1 + LINK_SIZE;
@@ -2362,11 +2381,6 @@ Arguments:
Returns: TRUE if what is matched could be empty
*/
-typedef struct recurse_check {
- struct recurse_check *prev;
- const pcre_uchar *group;
-} recurse_check;
-
static BOOL
could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
BOOL utf, compile_data *cd, recurse_check *recurses)
@@ -2497,8 +2511,8 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
empty_branch = FALSE;
do
{
- if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd, NULL))
- empty_branch = TRUE;
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd,
+ recurses)) empty_branch = TRUE;
code += GET(code, 1);
}
while (*code == OP_ALT);
@@ -3093,7 +3107,7 @@ Returns: TRUE if the auto-possessification is possible
static BOOL
compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
- const pcre_uint32 *base_list, const pcre_uchar *base_end)
+ const pcre_uint32 *base_list, const pcre_uchar *base_end, int *rec_limit)
{
pcre_uchar c;
pcre_uint32 list[8];
@@ -3110,6 +3124,9 @@ pcre_uint32 chr;
BOOL accepted, invert_bits;
BOOL entered_a_group = FALSE;
+if (*rec_limit == 0) return FALSE;
+--(*rec_limit);
+
/* Note: the base_list[1] contains whether the current opcode has greedy
(represented by a non-zero value) quantifier. This is a different from
other character type lists, which stores here that the character iterator
@@ -3180,7 +3197,8 @@ for(;;)
while (*next_code == OP_ALT)
{
- if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE;
+ if (!compare_opcodes(code, utf, cd, base_list, base_end, rec_limit))
+ return FALSE;
code = next_code + 1 + LINK_SIZE;
next_code += GET(next_code, 1);
}
@@ -3200,7 +3218,7 @@ for(;;)
/* The bracket content will be checked by the
OP_BRA/OP_CBRA case above. */
next_code += 1 + LINK_SIZE;
- if (!compare_opcodes(next_code, utf, cd, base_list, base_end))
+ if (!compare_opcodes(next_code, utf, cd, base_list, base_end, rec_limit))
return FALSE;
code += PRIV(OP_lengths)[c];
@@ -3633,6 +3651,7 @@ register pcre_uchar c;
const pcre_uchar *end;
pcre_uchar *repeat_opcode;
pcre_uint32 list[8];
+int rec_limit;
for (;;)
{
@@ -3653,7 +3672,8 @@ for (;;)
get_chr_property_list(code, utf, cd->fcc, list) : NULL;
list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
- if (end != NULL && compare_opcodes(end, utf, cd, list, end))
+ rec_limit = 1000;
+ if (end != NULL && compare_opcodes(end, utf, cd, list, end, &rec_limit))
{
switch(c)
{
@@ -3709,7 +3729,8 @@ for (;;)
list[1] = (c & 1) == 0;
- if (compare_opcodes(end, utf, cd, list, end))
+ rec_limit = 1000;
+ if (compare_opcodes(end, utf, cd, list, end, &rec_limit))
{
switch (c)
{
@@ -4002,7 +4023,7 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
/* See if this recursion is on the forward reference list. If so, adjust the
reference. */
- for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
+ for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
hc += LINK_SIZE)
{
offset = (int)GET(hc, 0);
@@ -4208,7 +4229,11 @@ if ((options & PCRE_CASELESS) != 0)
range. Otherwise, use a recursive call to add the additional range. */
else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */
- else if (od > end && oc <= end + 1) end = od; /* Extend upwards */
+ else if (od > end && oc <= end + 1)
+ {
+ end = od; /* Extend upwards */
+ if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff);
+ }
else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od);
}
}
@@ -5509,6 +5534,12 @@ for (;; ptr++)
}
#endif
+ /* Even though any XCLASS list is now discarded, we must allow for
+ its memory. */
+
+ if (lengthptr != NULL)
+ *lengthptr += (int)(class_uchardata - class_uchardata_base);
+
/* If there are no characters > 255, or they are all to be included or
excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
whole class was negated and whether there were negative specials such as \S
@@ -5907,6 +5938,7 @@ for (;; ptr++)
{
register int i;
int len = (int)(code - previous);
+ size_t base_hwm_offset = save_hwm_offset;
pcre_uchar *bralink = NULL;
pcre_uchar *brazeroptr = NULL;
@@ -6052,21 +6084,21 @@ for (;; ptr++)
memcpy(code, previous, IN_UCHARS(len));
while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN -
- (this_hwm_offset - save_hwm_offset))
+ WORK_SIZE_SAFETY_MARGIN -
+ (this_hwm_offset - base_hwm_offset))
{
*errorcodeptr = expand_workspace(cd);
if (*errorcodeptr != 0) goto FAILED;
}
- for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
- hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
+ for (hc = (pcre_uchar *)cd->start_workspace + base_hwm_offset;
+ hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
hc += LINK_SIZE)
{
PUT(cd->hwm, 0, GET(hc, 0) + len);
cd->hwm += LINK_SIZE;
}
- save_hwm_offset = this_hwm_offset;
+ base_hwm_offset = this_hwm_offset;
code += len;
}
}
@@ -6133,21 +6165,21 @@ for (;; ptr++)
copying them. */
while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN -
- (this_hwm_offset - save_hwm_offset))
+ WORK_SIZE_SAFETY_MARGIN -
+ (this_hwm_offset - base_hwm_offset))
{
*errorcodeptr = expand_workspace(cd);
if (*errorcodeptr != 0) goto FAILED;
}
- for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
- hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
+ for (hc = (pcre_uchar *)cd->start_workspace + base_hwm_offset;
+ hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
hc += LINK_SIZE)
{
PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
cd->hwm += LINK_SIZE;
}
- save_hwm_offset = this_hwm_offset;
+ base_hwm_offset = this_hwm_offset;
code += len;
}
@@ -6455,15 +6487,25 @@ for (;; ptr++)
parenthesis forms. */
case CHAR_LEFT_PARENTHESIS:
- newoptions = options;
- skipbytes = 0;
- bravalue = OP_CBRA;
- save_hwm_offset = cd->hwm - cd->start_workspace;
- reset_bracount = FALSE;
+ ptr++;
- /* First deal with various "verbs" that can be introduced by '*'. */
+ /* First deal with comments. Putting this code right at the start ensures
+ that comments have no bad side effects. */
+
+ if (ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
+ {
+ ptr += 2;
+ while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ if (*ptr == CHAR_NULL)
+ {
+ *errorcodeptr = ERR18;
+ goto FAILED;
+ }
+ continue;
+ }
+
+ /* Now deal with various "verbs" that can be introduced by '*'. */
- ptr++;
if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
|| (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
{
@@ -6584,10 +6626,18 @@ for (;; ptr++)
goto FAILED;
}
+ /* Initialize for "real" parentheses */
+
+ newoptions = options;
+ skipbytes = 0;
+ bravalue = OP_CBRA;
+ save_hwm_offset = cd->hwm - cd->start_workspace;
+ reset_bracount = FALSE;
+
/* Deal with the extended parentheses; all are introduced by '?', and the
appearance of any of them means that this is not a capturing group. */
- else if (*ptr == CHAR_QUESTION_MARK)
+ if (*ptr == CHAR_QUESTION_MARK)
{
int i, set, unset, namelen;
int *optset;
@@ -6596,17 +6646,6 @@ for (;; ptr++)
switch (*(++ptr))
{
- case CHAR_NUMBER_SIGN: /* Comment; skip to ket */
- ptr++;
- while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr == CHAR_NULL)
- {
- *errorcodeptr = ERR18;
- goto FAILED;
- }
- continue;
-
-
/* ------------------------------------------------------------ */
case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
reset_bracount = TRUE;
@@ -6655,7 +6694,9 @@ for (;; ptr++)
if (tempptr[1] == CHAR_QUESTION_MARK &&
(tempptr[2] == CHAR_EQUALS_SIGN ||
tempptr[2] == CHAR_EXCLAMATION_MARK ||
- tempptr[2] == CHAR_LESS_THAN_SIGN))
+ (tempptr[2] == CHAR_LESS_THAN_SIGN &&
+ (tempptr[3] == CHAR_EQUALS_SIGN ||
+ tempptr[3] == CHAR_EXCLAMATION_MARK))))
{
cd->iscondassert = TRUE;
break;
@@ -8264,7 +8305,7 @@ for (;;)
int fixed_length;
*code = OP_END;
fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
- FALSE, cd);
+ FALSE, cd, NULL);
DPRINTF(("fixed length = %d\n", fixed_length));
if (fixed_length == -3)
{
@@ -8549,6 +8590,7 @@ do {
case OP_RREF:
case OP_DNRREF:
case OP_DEF:
+ case OP_FAIL:
return FALSE;
default: /* Assertion */
@@ -9366,7 +9408,7 @@ if (cd->check_lookbehind)
int end_op = *be;
*be = OP_END;
fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
- cd);
+ cd, NULL);
*be = end_op;
DPRINTF(("fixed length = %d\n", fixed_length));
if (fixed_length < 0)
diff --git a/src/3rdparty/pcre/pcre_dfa_exec.c b/src/3rdparty/pcre/pcre_dfa_exec.c
index 64a495cc04..2d99787631 100644
--- a/src/3rdparty/pcre/pcre_dfa_exec.c
+++ b/src/3rdparty/pcre/pcre_dfa_exec.c
@@ -2736,9 +2736,10 @@ for (;;)
condcode == OP_DNRREF)
return PCRE_ERROR_DFA_UCOND;
- /* The DEFINE condition is always false */
+ /* The DEFINE condition is always false, and the assertion (?!) is
+ converted to OP_FAIL. */
- if (condcode == OP_DEF)
+ if (condcode == OP_DEF || condcode == OP_FAIL)
{ ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
/* The only supported version of OP_RREF is for the value RREF_ANY,
diff --git a/src/3rdparty/pcre/pcre_exec.c b/src/3rdparty/pcre/pcre_exec.c
index 75fa2a7329..b639a28b69 100644
--- a/src/3rdparty/pcre/pcre_exec.c
+++ b/src/3rdparty/pcre/pcre_exec.c
@@ -1376,6 +1376,7 @@ for (;;)
break;
case OP_DEF: /* DEFINE - always false */
+ case OP_FAIL: /* From optimized (?!) condition */
break;
/* The condition is an assertion. Call match() to evaluate it - setting
@@ -3482,7 +3483,7 @@ for (;;)
if (possessive) continue; /* No backtracking */
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ if (eptr <= pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
#ifdef SUPPORT_UCP
@@ -3903,7 +3904,7 @@ for (;;)
if (possessive) continue; /* No backtracking */
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ if (eptr <= pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
@@ -4038,7 +4039,7 @@ for (;;)
if (possessive) continue; /* No backtracking */
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ if (eptr <= pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
@@ -5609,7 +5610,7 @@ for (;;)
if (possessive) continue; /* No backtracking */
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ if (eptr <= pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
@@ -5651,12 +5652,17 @@ for (;;)
if (possessive) continue; /* No backtracking */
+ /* We use <= pp rather than == pp to detect the start of the run while
+ backtracking because the use of \C in UTF mode can cause BACKCHAR to
+ move back past pp. This is just palliative; the use of \C in UTF mode
+ is fraught with danger. */
+
for(;;)
{
int lgb, rgb;
PCRE_PUCHAR fptr;
- if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
+ if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */
RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
@@ -5674,7 +5680,7 @@ for (;;)
for (;;)
{
- if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
+ if (eptr <= pp) goto TAIL_RECURSE; /* At start of char run */
fptr = eptr - 1;
if (!utf) c = *fptr; else
{
@@ -5924,7 +5930,7 @@ for (;;)
if (possessive) continue; /* No backtracking */
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ if (eptr <= pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c
index 795a5d2b47..0901c1bd53 100644
--- a/src/3rdparty/pcre/pcre_jit_compile.c
+++ b/src/3rdparty/pcre/pcre_jit_compile.c
@@ -2108,7 +2108,7 @@ sljit_uw *result;
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
return NULL;
-result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), common->allocator_data);
+result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
if (SLJIT_UNLIKELY(result == NULL))
{
sljit_set_compiler_memory_error(compiler);
@@ -6997,7 +6997,7 @@ cc += GET(cc, 1);
has_alternatives = *cc == OP_ALT;
if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
- has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE;
+ has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) ? FALSE : TRUE;
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
opcode = OP_SCOND;
@@ -7255,12 +7255,14 @@ if (opcode == OP_COND || opcode == OP_SCOND)
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
matchingpath += 1 + 2 * IMM2_SIZE;
}
- else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
+ else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL)
{
/* Never has other case. */
BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
SLJIT_ASSERT(!has_alternatives);
+ if (*matchingpath == OP_FAIL)
+ stacksize = 0;
if (*matchingpath == OP_RREF)
{
stacksize = GET2(matchingpath, 1);
diff --git a/src/3rdparty/pcre/sljit/sljitLir.c b/src/3rdparty/pcre/sljit/sljitLir.c
index 8112e8da6e..5039a7e04e 100644
--- a/src/3rdparty/pcre/sljit/sljitLir.c
+++ b/src/3rdparty/pcre/sljit/sljitLir.c
@@ -435,6 +435,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile
SLJIT_FREE(compiler, allocator_data);
}
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
+{
+ if (compiler->error == SLJIT_SUCCESS)
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+}
+
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
{
diff --git a/src/3rdparty/pcre/sljit/sljitLir.h b/src/3rdparty/pcre/sljit/sljitLir.h
index 79f1d102c1..24c0f60399 100644
--- a/src/3rdparty/pcre/sljit/sljitLir.h
+++ b/src/3rdparty/pcre/sljit/sljitLir.h
@@ -429,11 +429,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile
these checks increases the performance of the compiling process. */
static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
-/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED. After
- the error code is set, the compiler behaves as if itself detected
- an allocation failure. This can greatly simplify error management,
- since only the compiler needs to be checked after compilation. */
-static SLJIT_INLINE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) { compiler->error = SLJIT_ERR_ALLOC_FAILED; }
+/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except
+ if an error was detected before. After the error code is set
+ the compiler behaves as if the allocation failure happened
+ during an sljit function call. This can greatly simplify error
+ checking, since only the compiler status needs to be checked
+ after the compilation. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);
/*
Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index bf1015a7be..dc9f8f73c4 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -181,11 +181,11 @@ bool QLockFilePrivate::isApparentlyStale() const
{
qint64 pid;
QString hostname, appname;
- if (!getLockInfo(&pid, &hostname, &appname))
- return false;
- if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
- if (::kill(pid, 0) == -1 && errno == ESRCH)
- return true; // PID doesn't exist anymore
+ if (getLockInfo(&pid, &hostname, &appname)) {
+ if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
+ if (::kill(pid, 0) == -1 && errno == ESRCH)
+ return true; // PID doesn't exist anymore
+ }
}
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index f9f29090d7..3587c7bffe 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -115,21 +115,21 @@ bool QLockFilePrivate::isApparentlyStale() const
{
qint64 pid;
QString hostname, appname;
- if (!getLockInfo(&pid, &hostname, &appname))
- return false;
// On WinRT there seems to be no way of obtaining information about other
// processes due to sandboxing
#ifndef Q_OS_WINRT
- if (hostname == QString::fromLocal8Bit(localHostName())) {
- HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (!procHandle)
- return true;
- // We got a handle but check if process is still alive
- DWORD dwR = ::WaitForSingleObject(procHandle, 0);
- ::CloseHandle(procHandle);
- if (dwR == WAIT_TIMEOUT)
- return true;
+ if (getLockInfo(&pid, &hostname, &appname)) {
+ if (hostname == QString::fromLocal8Bit(localHostName())) {
+ HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (!procHandle)
+ return true;
+ // We got a handle but check if process is still alive
+ DWORD dwR = ::WaitForSingleObject(procHandle, 0);
+ ::CloseHandle(procHandle);
+ if (dwR == WAIT_TIMEOUT)
+ return true;
+ }
}
#endif // !Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index e932fc0c02..4ed9674f36 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -36,7 +36,6 @@
#include <qdebug.h>
#include <qelapsedtimer.h>
#include <qeventloop.h>
-#include <qtimer.h>
QT_BEGIN_NAMESPACE
@@ -45,13 +44,11 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent)
handle(INVALID_HANDLE_VALUE),
readBufferMaxSize(0),
actualReadBufferSize(0),
+ stopped(true),
readSequenceStarted(false),
- emitReadyReadTimer(new QTimer(this)),
pipeBroken(false),
readyReadEmitted(false)
{
- emitReadyReadTimer->setSingleShot(true);
- connect(emitReadyReadTimer, SIGNAL(timeout()), SIGNAL(readyRead()));
dataReadNotifier = new QWinOverlappedIoNotifier(this);
connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified);
}
@@ -73,12 +70,7 @@ static bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
QWindowsPipeReader::~QWindowsPipeReader()
{
- if (readSequenceStarted) {
- if (qt_cancelIo(handle, &overlapped))
- dataReadNotifier->waitForNotified(-1, &overlapped);
- else
- qErrnoWarning("QWindowsPipeReader: qt_cancelIo on handle %x failed.", handle);
- }
+ stop();
}
/*!
@@ -89,9 +81,9 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
readBuffer.clear();
actualReadBufferSize = 0;
handle = hPipeReadEnd;
- ZeroMemory(&overlapped, sizeof(overlapped));
pipeBroken = false;
readyReadEmitted = false;
+ stopped = false;
if (hPipeReadEnd != INVALID_HANDLE_VALUE) {
dataReadNotifier->setHandle(hPipeReadEnd);
dataReadNotifier->setEnabled(true);
@@ -100,13 +92,24 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
/*!
Stops the asynchronous read sequence.
- This function assumes that the file already has been closed.
- It does not cancel any I/O operation.
+ If the read sequence is running then the I/O operation is canceled.
*/
void QWindowsPipeReader::stop()
{
- dataReadNotifier->setEnabled(false);
+ stopped = true;
+ if (readSequenceStarted) {
+ if (qt_cancelIo(handle, &overlapped)) {
+ dataReadNotifier->waitForNotified(-1, &overlapped);
+ } else {
+ const DWORD dwError = GetLastError();
+ if (dwError != ERROR_NOT_FOUND) {
+ qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.",
+ handle);
+ }
+ }
+ }
readSequenceStarted = false;
+ dataReadNotifier->setEnabled(false);
handle = INVALID_HANDLE_VALUE;
}
@@ -119,7 +122,7 @@ qint64 QWindowsPipeReader::bytesAvailable() const
}
/*!
- Stops the asynchronous read sequence.
+ Copies at most \c{maxlen} bytes from the internal read buffer to \c{data}.
*/
qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
{
@@ -147,9 +150,7 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
}
if (!pipeBroken) {
- if (!actualReadBufferSize)
- emitReadyReadTimer->stop();
- if (!readSequenceStarted)
+ if (!readSequenceStarted && !stopped)
startAsyncRead();
if (readSoFar == 0)
return -2; // signal EWOULDBLOCK
@@ -172,13 +173,41 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
{
if (&overlapped != notifiedOverlapped)
return;
- if (!completeAsyncRead(numberOfBytesRead, errorCode)) {
+
+ switch (errorCode) {
+ case ERROR_SUCCESS:
+ break;
+ case ERROR_MORE_DATA:
+ // This is not an error. We're connected to a message mode
+ // pipe and the message didn't fit into the pipe's system
+ // buffer. We will read the remaining data in the next call.
+ break;
+ case ERROR_BROKEN_PIPE:
+ case ERROR_PIPE_NOT_CONNECTED:
pipeBroken = true;
+ break;
+ default:
+ emit winError(errorCode, QLatin1String("QWindowsPipeReader::completeAsyncRead"));
+ pipeBroken = true;
+ break;
+ }
+
+ readSequenceStarted = false;
+
+ // After the reader was stopped, the only reason why this function can be called is the
+ // completion of a cancellation. No signals should be emitted, and no new read sequence should
+ // be started in this case.
+ if (stopped)
+ return;
+
+ if (pipeBroken) {
emit pipeClosed();
return;
}
+
+ actualReadBufferSize += numberOfBytesRead;
+ readBuffer.truncate(actualReadBufferSize);
startAsyncRead();
- emitReadyReadTimer->stop();
readyReadEmitted = true;
emit readyRead();
}
@@ -206,6 +235,7 @@ void QWindowsPipeReader::startAsyncRead()
char *ptr = readBuffer.reserve(bytesToRead);
readSequenceStarted = true;
+ ZeroMemory(&overlapped, sizeof(overlapped));
if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) {
// We get notified by the QWinOverlappedIoNotifier - even in the synchronous case.
return;
@@ -241,38 +271,6 @@ void QWindowsPipeReader::startAsyncRead()
/*!
\internal
- Sets the correct size of the read buffer after a read operation.
- Returns \c false, if an error occurred or the connection dropped.
- */
-bool QWindowsPipeReader::completeAsyncRead(DWORD bytesRead, DWORD errorCode)
-{
- readSequenceStarted = false;
-
- switch (errorCode) {
- case ERROR_SUCCESS:
- break;
- case ERROR_MORE_DATA:
- // This is not an error. We're connected to a message mode
- // pipe and the message didn't fit into the pipe's system
- // buffer. We will read the remaining data in the next call.
- break;
- case ERROR_BROKEN_PIPE:
- case ERROR_PIPE_NOT_CONNECTED:
- return false;
- default:
- emit winError(errorCode, QLatin1String("QWindowsPipeReader::completeAsyncRead"));
- return false;
- }
-
- actualReadBufferSize += bytesRead;
- readBuffer.truncate(actualReadBufferSize);
- if (!emitReadyReadTimer->isActive())
- emitReadyReadTimer->start();
- return true;
-}
-
-/*!
- \internal
Returns the number of available bytes in the pipe.
Sets QWindowsPipeReader::pipeBroken to true if the connection is broken.
*/
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index ecc6974efa..b0a23e1a51 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -47,7 +47,6 @@
#include <qbytearray.h>
#include <qobject.h>
-#include <qtimer.h>
#include <private/qringbuffer_p.h>
#include <qt_windows.h>
@@ -89,7 +88,6 @@ private Q_SLOTS:
void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
private:
- bool completeAsyncRead(DWORD bytesRead, DWORD errorCode);
DWORD checkPipeState();
private:
@@ -99,8 +97,8 @@ private:
qint64 readBufferMaxSize;
QRingBuffer readBuffer;
int actualReadBufferSize;
+ bool stopped;
bool readSequenceStarted;
- QTimer *emitReadyReadTimer;
bool pipeBroken;
bool readyReadEmitted;
};
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 2adea0f493..0f9c2c1c86 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -680,8 +680,10 @@ void QCocoaWindow::setVisible(bool visible)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
- monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) {
- QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton);
+ monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
+ QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]);
+ QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
+ cocoaButton2QtButton([e buttonNumber]));
}];
}
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index abd0231b00..ba14a06af4 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -4275,15 +4275,16 @@ void QApplicationPrivate::cleanupMultitouch_sys()
{
}
-QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos)
+QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint)
{
+ const QPointF screenPos = touchPoint.screenPos();
int closestTouchPointId = -1;
QObject *closestTarget = 0;
qreal closestDistance = qreal(0.);
QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it = activeTouchPoints.constBegin(),
ite = activeTouchPoints.constEnd();
while (it != ite) {
- if (it.key().device == device) {
+ if (it.key().device == device && it.key().touchPointId != touchPoint.id()) {
const QTouchEvent::TouchPoint &touchPoint = it->touchPoint;
qreal dx = screenPos.x() - touchPoint.screenPos().x();
qreal dy = screenPos.y() - touchPoint.screenPos().y();
@@ -4339,7 +4340,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
}
if (device->type() == QTouchDevice::TouchScreen) {
- QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint.screenPos());
+ QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint);
QWidget *widget = static_cast<QWidget *>(target.data());
if (closestWidget
&& (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 7d97235c66..7f76d1ba97 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -280,7 +280,7 @@ public:
void initializeMultitouch_sys();
void cleanupMultitouch();
void cleanupMultitouch_sys();
- QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos);
+ QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint);
void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
void removeTouchPoint(int touchPointId);
static bool translateRawTouchEvent(QWidget *widget,
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
index 77bef94550..12bea6769c 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
@@ -58,6 +58,7 @@ private slots:
void staleLongLockFromBusyProcess();
void staleLockRace();
void noPermissions();
+ void corruptedLockFile();
public:
QString m_helperApp;
@@ -415,5 +416,21 @@ void tst_QLockFile::noPermissions()
QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError));
}
+void tst_QLockFile::corruptedLockFile()
+{
+ const QString fileName = dir.path() + "/corruptedLockFile";
+
+ {
+ // Create a empty file. Typically the result of a computer crash or hard disk full.
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::WriteOnly));
+ }
+
+ QLockFile secondLock(fileName);
+ secondLock.setStaleLockTime(100);
+ QVERIFY(secondLock.tryLock(10000));
+ QCOMPARE(int(secondLock.error()), int(QLockFile::NoError));
+}
+
QTEST_MAIN(tst_QLockFile)
#include "tst_qlockfile.moc"
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index ae6d62c332..717039d64e 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -435,6 +435,7 @@ private slots:
void grabKeyboard();
void touchEventSynthesizedMouseEvent();
+ void touchUpdateOnNewTouch();
void styleSheetPropagation();
@@ -9763,6 +9764,9 @@ class TouchMouseWidget : public QWidget {
public:
explicit TouchMouseWidget(QWidget *parent = 0)
: QWidget(parent),
+ m_touchBeginCount(0),
+ m_touchUpdateCount(0),
+ m_touchEndCount(0),
m_touchEventCount(0),
m_acceptTouch(false),
m_mouseEventCount(0),
@@ -9789,6 +9793,12 @@ protected:
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
+ if (e->type() == QEvent::TouchBegin)
+ ++m_touchBeginCount;
+ else if (e->type() == QEvent::TouchUpdate)
+ ++m_touchUpdateCount;
+ else if (e->type() == QEvent::TouchEnd)
+ ++m_touchEndCount;
++m_touchEventCount;
if (m_acceptTouch)
e->accept();
@@ -9813,6 +9823,9 @@ protected:
}
public:
+ int m_touchBeginCount;
+ int m_touchUpdateCount;
+ int m_touchEndCount;
int m_touchEventCount;
bool m_acceptTouch;
int m_mouseEventCount;
@@ -9933,6 +9946,46 @@ void tst_QWidget::touchEventSynthesizedMouseEvent()
}
}
+void tst_QWidget::touchUpdateOnNewTouch()
+{
+ QTouchDevice *device = new QTouchDevice;
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device);
+
+ TouchMouseWidget widget;
+ widget.setAcceptTouch(true);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QWidget);
+ widget.setLayout(layout);
+ widget.show();
+
+ QWindow* window = widget.windowHandle();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ QCOMPARE(widget.m_touchBeginCount, 0);
+ QCOMPARE(widget.m_touchUpdateCount, 0);
+ QCOMPARE(widget.m_touchEndCount, 0);
+ QTest::touchEvent(window, device).press(0, QPoint(20, 20), window);
+ QCOMPARE(widget.m_touchBeginCount, 1);
+ QCOMPARE(widget.m_touchUpdateCount, 0);
+ QCOMPARE(widget.m_touchEndCount, 0);
+ QTest::touchEvent(window, device).move(0, QPoint(25, 25), window);
+ QCOMPARE(widget.m_touchBeginCount, 1);
+ QCOMPARE(widget.m_touchUpdateCount, 1);
+ QCOMPARE(widget.m_touchEndCount, 0);
+ QTest::touchEvent(window, device).stationary(0).press(1, QPoint(40, 40), window);
+ QCOMPARE(widget.m_touchBeginCount, 1);
+ QCOMPARE(widget.m_touchUpdateCount, 2);
+ QCOMPARE(widget.m_touchEndCount, 0);
+ QTest::touchEvent(window, device).stationary(1).release(0, QPoint(25, 25), window);
+ QCOMPARE(widget.m_touchBeginCount, 1);
+ QCOMPARE(widget.m_touchUpdateCount, 3);
+ QCOMPARE(widget.m_touchEndCount, 0);
+ QTest::touchEvent(window, device).release(1, QPoint(40, 40), window);
+ QCOMPARE(widget.m_touchBeginCount, 1);
+ QCOMPARE(widget.m_touchUpdateCount, 3);
+ QCOMPARE(widget.m_touchEndCount, 1);
+}
+
void tst_QWidget::styleSheetPropagation()
{
QTableView tw;