diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/changelog qtbase-opensource-src-5.2.1+dfsg/debian/changelog --- qtbase-opensource-src-5.2.1+dfsg/debian/changelog 2014-04-09 21:59:41.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/changelog 2015-05-27 17:56:10.000000000 +0000 @@ -1,3 +1,47 @@ +qtbase-opensource-src (5.2.1+dfsg-1ubuntu14.3) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via crafted GIF image + - debian/patches/CVE-2014-0190.patch: check for broken image in + src/gui/image/qgifhandler.cpp. + - CVE-2014-0190 + * SECURITY UPDATE: denial of service via crafted BMP + - debian/patches/CVE-2015-0295.patch: fix division by zero in + src/gui/image/qbmphandler.cpp. + - CVE-2015-0295 + * SECURITY UPDATE: denial of service and possible code execution via + crafted BMP or ICO images + - debian/patches/CVE-2015-1858-1859.patch: move check to better + location in src/gui/image/qbmphandler.cpp, check depth in + src/plugins/imageformats/ico/qicohandler.cpp. + - CVE-2015-1858 + - CVE-2015-1859 + * SECURITY UPDATE: denial of service and possible code exection via + crafted GIF image + - debian/patches/CVE-2015-1860.patch: check bounds in + src/gui/image/qgifhandler.cpp. + - CVE-2015-1860 + + -- Marc Deslauriers Wed, 27 May 2015 13:55:50 -0400 + +qtbase-opensource-src (5.2.1+dfsg-1ubuntu14.2) trusty; urgency=medium + + * debian/patches/xi2-use-master-device.patch: + - Make xi2 select events on master device instead of slaves. + (LP: #1307701) + + -- Maarten Lankhorst Tue, 06 May 2014 13:14:17 +0000 + +qtbase-opensource-src (5.2.1+dfsg-1ubuntu14.1) trusty; urgency=medium + + [ Dmitry Shachnev ] + * Backport upstream patch to fix issues with keymap update handling + (Add_better_support_for_keymap_update_handling.patch, copied from + Debian and rebased). (LP: #1318482) + * Build-depend on libxkbcommon-x11-dev, as the new patch includes + . + + -- Timo Jyrinki Mon, 28 Apr 2014 03:11:01 +0000 + qtbase-opensource-src (5.2.1+dfsg-1ubuntu14) trusty; urgency=medium * libqt5gui5.symbols, libqt5opengl5.symbols: making the gl/gles symbols diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/control qtbase-opensource-src-5.2.1+dfsg/debian/control --- qtbase-opensource-src-5.2.1+dfsg/debian/control 2014-04-01 12:44:51.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/control 2014-05-12 08:40:30.000000000 +0000 @@ -55,6 +55,7 @@ libxcb1-dev, libxi-dev, libxkbcommon-dev, + libxkbcommon-x11-dev, libxrender-dev, pkg-kde-tools (>= 0.14.2), unixodbc-dev, diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/Add_better_support_for_keymap_update_handling.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/Add_better_support_for_keymap_update_handling.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/Add_better_support_for_keymap_update_handling.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/Add_better_support_for_keymap_update_handling.patch 2014-05-12 08:40:30.000000000 +0000 @@ -0,0 +1,665 @@ +From 18e162e8640d96f2d7f2a85ef35d00350360903d Mon Sep 17 00:00:00 2001 +From: Gatis Paeglis +Date: Thu, 27 Feb 2014 18:05:14 +0100 +Subject: [PATCH] Add better support for keymap update handling + +Use the new X11 support API xkb_x11_* released in libxkbcommon version 0.4.0. + +From the commit message where this API was introduced: + +"These are function to create an xkb_keymap directly from XKB requests +to the X server. This opens up the possibility for X clients to use +xcb + xcb-xkb + xkbcommon as a proper replacement for Xlib + xkbfile for +keyboard support. + +Why not just use the RMLVO that the server puts in the _XKB_RULES_NAMES +property? This does not account for custom keymaps, on-the-fly keymap +modifications, remote clients, etc., so is not a proper solution in +practice. Also, some servers don't even set it. Now, the client just +needs to recreate the keymap in response to a change in the server's +keymap (as Xlib clients do with XRefreshKeyboardMapping() and friends)." + +This patch moves XKEYBOARD presence decision from compile time to runtime +for a proper remote X client support. + +Task-number: QTBUG-31527 +Task-number: QTBUG-32760 +Change-Id: I4d402668cda2126ef180b27022154f96b1874b1d +--- + src/plugins/platforms/xcb/qxcbconnection.cpp | 61 ++++---- + src/plugins/platforms/xcb/qxcbconnection.h | 2 +- + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 220 +++++++++++---------------- + src/plugins/platforms/xcb/qxcbkeyboard.h | 35 ++--- + src/plugins/platforms/xcb/xcb-plugin.pro | 8 +- + 5 files changed, 136 insertions(+), 190 deletions(-) + +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -782,6 +782,7 @@ + xcb_timestamp_t time; + uint8_t deviceID; + } any; ++ xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify; + xcb_xkb_map_notify_event_t map_notify; + xcb_xkb_state_notify_event_t state_notify; + } _xkb_event; +@@ -812,15 +813,11 @@ + case XCB_EXPOSE: + HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); + case XCB_BUTTON_PRESS: +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state); +-#endif + handleButtonPress(event); + HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); + case XCB_BUTTON_RELEASE: +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state); +-#endif + handleButtonRelease(event); + HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); + case XCB_MOTION_NOTIFY: +@@ -828,9 +825,7 @@ + xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event; + qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast(m_buttons)); + } +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); +-#endif + HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); + case XCB_CONFIGURE_NOTIFY: + HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); +@@ -846,29 +841,21 @@ + case XCB_ENTER_NOTIFY: + HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); + case XCB_LEAVE_NOTIFY: +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); +-#endif + HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); + case XCB_FOCUS_IN: + HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent); + case XCB_FOCUS_OUT: + HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent); + case XCB_KEY_PRESS: +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state); +-#endif + HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent); + case XCB_KEY_RELEASE: +-#ifdef QT_NO_XKB + m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state); +-#endif + HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent); +-#ifdef QT_NO_XKB + case XCB_MAPPING_NOTIFY: + m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event); + break; +-#endif + case XCB_SELECTION_REQUEST: + { + xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event; +@@ -936,6 +923,8 @@ + _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event); + if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) { + switch (xkb_event->any.xkbType) { ++ // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap ++ // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations. + case XCB_XKB_STATE_NOTIFY: + m_keyboard->updateXKBState(&xkb_event->state_notify); + handled = true; +@@ -944,6 +933,12 @@ + m_keyboard->handleMappingNotifyEvent(&xkb_event->map_notify); + handled = true; + break; ++ case XCB_XKB_NEW_KEYBOARD_NOTIFY: { ++ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify; ++ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES) ++ m_keyboard->updateKeymap(); ++ break; ++ } + default: + break; + } +@@ -1667,6 +1662,7 @@ + #ifndef QT_NO_XKB + const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id); + if (!reply || !reply->present) { ++ qWarning() << "Qt: XKEYBOARD extension not present on the X server."; + xkb_first_event = 0; + return; + } +@@ -1676,14 +1672,14 @@ + xcb_xkb_use_extension_cookie_t xkb_query_cookie; + xcb_xkb_use_extension_reply_t *xkb_query; + +- xkb_query_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); ++ xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); + xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); + + if (!xkb_query) { + qWarning("Qt: Failed to initialize XKB extension"); + return; + } else if (!xkb_query->supported) { +- qWarning("Qt: Unsupported XKB version (want %d %d, has %d %d)", ++ qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)", + XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION, + xkb_query->serverMajor, xkb_query->serverMinor); + free(xkb_query); +@@ -1693,25 +1689,28 @@ + has_xkb = true; + free(xkb_query); + +- uint affectMap, map; +- affectMap = map = XCB_XKB_MAP_PART_KEY_TYPES | +- XCB_XKB_MAP_PART_KEY_SYMS | +- XCB_XKB_MAP_PART_MODIFIER_MAP | +- XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | +- XCB_XKB_MAP_PART_KEY_ACTIONS | +- XCB_XKB_MAP_PART_KEY_BEHAVIORS | +- XCB_XKB_MAP_PART_VIRTUAL_MODS | +- XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP; ++ const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | ++ XCB_XKB_MAP_PART_KEY_SYMS | ++ XCB_XKB_MAP_PART_MODIFIER_MAP | ++ XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | ++ XCB_XKB_MAP_PART_KEY_ACTIONS | ++ XCB_XKB_MAP_PART_KEY_BEHAVIORS | ++ XCB_XKB_MAP_PART_VIRTUAL_MODS | ++ XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP); ++ ++ const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | ++ XCB_XKB_EVENT_TYPE_MAP_NOTIFY | ++ XCB_XKB_EVENT_TYPE_STATE_NOTIFY); + +- // Xkb events are reported to all interested clients without regard ++ // XKB events are reported to all interested clients without regard + // to the current keyboard input focus or grab state + xcb_void_cookie_t select = xcb_xkb_select_events_checked(c, + XCB_XKB_ID_USE_CORE_KBD, +- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY, ++ required_events, + 0, +- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY, +- affectMap, +- map, ++ required_events, ++ required_map_parts, ++ required_map_parts, + 0); + + xcb_generic_error_t *error = xcb_request_check(c, select); +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -54,7 +54,7 @@ + #include + + // This is needed to make Qt compile together with XKB. xkb.h is using a variable +-// which is called 'explicit', this is a reserved keyword in c++ */ ++// which is called 'explicit', this is a reserved keyword in c++ + #ifndef QT_NO_XKB + #define explicit dont_use_cxx_explicit + #include +--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp +@@ -662,6 +662,7 @@ + void QXcbKeyboard::updateKeymap() + { + m_config = true; ++ // set xkb context object + if (!xkb_context) { + xkb_context = xkb_context_new((xkb_context_flags)0); + if (!xkb_context) { +@@ -670,67 +671,50 @@ + return; + } + } +- readXKBConfig(); +- // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names +- if (xkb_keymap) +- xkb_keymap_unref(xkb_keymap); ++ // update xkb keymap object ++ xkb_keymap_unref(xkb_keymap); ++ xkb_keymap = 0; + +- xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); ++ struct xkb_state *new_state = 0; ++#ifndef QT_NO_XKB ++ if (connection()->hasXKB()) { ++ xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0); ++ if (xkb_keymap) { ++ // Create a new keyboard state object for a keymap ++ new_state = xkb_x11_state_new_from_device(xkb_keymap, xcb_connection(), core_device_id); ++ } ++ } ++#endif ++ if (!xkb_keymap) { ++ // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names ++ readXKBConfig(); ++ xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); ++ if (xkb_keymap) ++ new_state = xkb_state_new(xkb_keymap); ++ } + + if (!xkb_keymap) { + qWarning("Qt: Failed to compile a keymap"); + m_config = false; +- return; + } +- // Create a new keyboard state object for a keymap +- struct xkb_state *new_state = xkb_state_new(xkb_keymap); + if (!new_state) { +- qWarning("Qt: Failed to create a new keyboard state"); ++ qWarning("Qt: Failed to create xkb state"); + m_config = false; +- return; + } ++ if (!m_config) ++ return; + +- if (xkb_state) { +- xkb_state_unref(xkb_state); +- xkb_state = new_state; +- } else { +- xkb_state = new_state; +-#ifndef QT_NO_XKB +- // get initial state from the X server (and keep it up-to-date at all times) +- xcb_xkb_get_state_cookie_t state; +- xcb_xkb_get_state_reply_t *init_state; +- +- xcb_connection_t *c = xcb_connection(); +- state = xcb_xkb_get_state(c, XCB_XKB_ID_USE_CORE_KBD); +- init_state = xcb_xkb_get_state_reply(c, state, 0); +- if (!init_state) { +- qWarning("Qt: couldn't retrieve an initial keyboard state"); +- return; +- } +- /* The xkb keyboard state is comprised of the state of all keyboard modifiers, +- the keyboard group, and the state of the pointer buttons */ +- xkb_state_update_mask(xkb_state, +- init_state->baseMods, +- init_state->latchedMods, +- init_state->lockedMods, +- init_state->baseGroup, +- init_state->latchedGroup, +- init_state->lockedGroup); +- free(init_state); +-#else ++ // update xkb state object ++ xkb_state_unref(xkb_state); ++ xkb_state = new_state; ++ if (!connection()->hasXKB()) + updateXKBMods(); +-#endif +- } + } + + #ifndef QT_NO_XKB + void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) + { +- if (!m_config) +- return; +- +- if (connection()->hasXKB()) { +- ++ if (m_config && connection()->hasXKB()) { + const xkb_state_component newState + = xkb_state_update_mask(xkb_state, + state->baseMods, +@@ -745,35 +729,34 @@ + } + } + } ++#endif + +-#else + void QXcbKeyboard::updateXKBStateFromCore(quint16 state) + { +- if (!m_config) +- return; ++ if (m_config && !connection()->hasXKB()) { ++ const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); ++ const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); ++ const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); ++ const quint32 xkbMask = xkbModMask(state); ++ ++ const quint32 latched = modsLatched & xkbMask; ++ const quint32 locked = modsLocked & xkbMask; ++ quint32 depressed = modsDepressed & xkbMask; ++ // set modifiers in depressed if they don't appear in any of the final masks ++ depressed |= ~(depressed | latched | locked) & xkbMask; + +- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); +- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); +- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); +- const quint32 xkbMask = xkbModMask(state); +- +- const quint32 latched = modsLatched & xkbMask; +- const quint32 locked = modsLocked & xkbMask; +- quint32 depressed = modsDepressed & xkbMask; +- // set modifiers in depressed if they don't appear in any of the final masks +- depressed |= ~(depressed | latched | locked) & xkbMask; +- +- const xkb_state_component newState +- = xkb_state_update_mask(xkb_state, +- depressed, +- latched, +- locked, +- 0, +- 0, +- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group ++ const xkb_state_component newState ++ = xkb_state_update_mask(xkb_state, ++ depressed, ++ latched, ++ locked, ++ 0, ++ 0, ++ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group + +- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { +- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); ++ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { ++ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); ++ } + } + } + +@@ -803,16 +786,15 @@ + + void QXcbKeyboard::updateXKBMods() + { +- xkb_mods.shift = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT); +- xkb_mods.lock = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS); +- xkb_mods.control = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL); +- xkb_mods.mod1 = xkb_map_mod_get_index(xkb_keymap, "Mod1"); +- xkb_mods.mod2 = xkb_map_mod_get_index(xkb_keymap, "Mod2"); +- xkb_mods.mod3 = xkb_map_mod_get_index(xkb_keymap, "Mod3"); +- xkb_mods.mod4 = xkb_map_mod_get_index(xkb_keymap, "Mod4"); +- xkb_mods.mod5 = xkb_map_mod_get_index(xkb_keymap, "Mod5"); ++ xkb_mods.shift = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT); ++ xkb_mods.lock = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS); ++ xkb_mods.control = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL); ++ xkb_mods.mod1 = xkb_keymap_mod_get_index(xkb_keymap, "Mod1"); ++ xkb_mods.mod2 = xkb_keymap_mod_get_index(xkb_keymap, "Mod2"); ++ xkb_mods.mod3 = xkb_keymap_mod_get_index(xkb_keymap, "Mod3"); ++ xkb_mods.mod4 = xkb_keymap_mod_get_index(xkb_keymap, "Mod4"); ++ xkb_mods.mod5 = xkb_keymap_mod_get_index(xkb_keymap, "Mod5"); + } +-#endif + + QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const + { +@@ -897,10 +879,8 @@ + result += (qtKey + mods); + } + } +- if (kb_state) +- xkb_state_unref(kb_state); +- if (fallback_keymap) +- xkb_keymap_unref(fallback_keymap); ++ xkb_state_unref(kb_state); ++ xkb_keymap_unref(fallback_keymap); + + return result; + } +@@ -967,58 +947,41 @@ + , xkb_context(0) + , xkb_keymap(0) + , xkb_state(0) +-#ifndef QT_NO_XKB + , core_device_id(0) +-#endif + { + memset(&xkb_names, 0, sizeof(xkb_names)); +- updateKeymap(); + #ifndef QT_NO_XKB + if (connection->hasXKB()) { +- + updateVModMapping(); + updateVModToRModMapping(); +- +- // get the core keyboard id +- xcb_xkb_get_device_info_cookie_t device_id_cookie; +- xcb_xkb_get_device_info_reply_t *device_id; +- +- device_id_cookie = xcb_xkb_get_device_info(xcb_connection(), +- XCB_XKB_ID_USE_CORE_KBD, +- 0, 0, 0, 0, 0, 0); +- +- device_id = xcb_xkb_get_device_info_reply(xcb_connection(), device_id_cookie, 0); +- if (!device_id) { ++ core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection()); ++ if (core_device_id == -1) { + qWarning("Qt: couldn't get core keyboard device info"); + return; + } +- +- core_device_id = device_id->deviceID; +- free(device_id); ++ } else { ++#endif ++ m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); ++ updateModifiers(); ++#ifndef QT_NO_XKB + } +-#else +- m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); +- updateModifiers(); + #endif ++ updateKeymap(); + } + + QXcbKeyboard::~QXcbKeyboard() + { +- if (xkb_state) +- xkb_state_unref(xkb_state); +- if (xkb_keymap) +- xkb_keymap_unref(xkb_keymap); +- if (xkb_context) +- xkb_context_unref(xkb_context); +-#ifdef QT_NO_XKB +- xcb_key_symbols_free(m_key_symbols); +-#endif ++ xkb_state_unref(xkb_state); ++ xkb_keymap_unref(xkb_keymap); ++ xkb_context_unref(xkb_context); ++ if (!connection()->hasXKB()) ++ xcb_key_symbols_free(m_key_symbols); + clearXKBConfig(); + } + +-#ifndef QT_NO_XKB + void QXcbKeyboard::updateVModMapping() + { ++#ifndef QT_NO_XKB + xcb_xkb_get_names_cookie_t names_cookie; + xcb_xkb_get_names_reply_t *name_reply; + xcb_xkb_get_names_value_list_t names_list; +@@ -1082,10 +1045,12 @@ + } + + free(name_reply); ++#endif + } + + void QXcbKeyboard::updateVModToRModMapping() + { ++#ifndef QT_NO_XKB + xcb_xkb_get_map_cookie_t map_cookie; + xcb_xkb_get_map_reply_t *map_reply; + xcb_xkb_get_map_map_t map; +@@ -1148,8 +1113,9 @@ + + free(map_reply); + resolveMaskConflicts(); ++#endif + } +-#else ++ + void QXcbKeyboard::updateModifiers() + { + // The core protocol does not provide a convenient way to determine the mapping +@@ -1213,7 +1179,6 @@ + free(modMapReply); + resolveMaskConflicts(); + } +-#endif + + void QXcbKeyboard::resolveMaskConflicts() + { +@@ -1296,17 +1261,9 @@ + + if (!m_config) + return; +- // It is crucial the order of xkb_state_key_get_one_sym & +- // xkb_state_update_key operations is not reversed! ++ ++ // It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed! + xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); +-#ifdef QT_NO_XKB +- enum xkb_key_direction direction; +- if (type == QEvent::KeyPress) +- direction = XKB_KEY_DOWN; +- else +- direction = XKB_KEY_UP; +- xkb_state_update_key(xkb_state, code, direction); +-#endif + + QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); + QMetaMethod method; +@@ -1442,17 +1399,14 @@ + void QXcbKeyboard::handleMappingNotifyEvent(const void *event) + { + updateKeymap(); +-#ifdef QT_NO_XKB +- void *ev = const_cast(event); +- xcb_refresh_keyboard_mapping(m_key_symbols, static_cast(ev)); +- updateModifiers(); +-#else +- Q_UNUSED(event) + if (connection()->hasXKB()) { + updateVModMapping(); + updateVModToRModMapping(); ++ } else { ++ void *ev = const_cast(event); ++ xcb_refresh_keyboard_mapping(m_key_symbols, static_cast(ev)); ++ updateModifiers(); + } +-#endif + } + + QT_END_NAMESPACE +--- a/src/plugins/platforms/xcb/qxcbkeyboard.h ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.h +@@ -44,11 +44,15 @@ + + #include "qxcbobject.h" + +-#ifdef QT_NO_XKB + #include +-#endif + + #include ++#ifndef QT_NO_XKB ++// note: extern won't be needed from libxkbcommon 0.4.1 and above ++extern "C" { ++#include ++} ++#endif + + #include + +@@ -65,41 +69,37 @@ + + void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event); + void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event); +- + void handleMappingNotifyEvent(const void *event); + + Qt::KeyboardModifiers translateModifiers(int s) const; +- + void updateKeymap(); + QList possibleKeys(const QKeyEvent *e) const; + +-#ifdef QT_NO_XKB +- void updateXKBStateFromCore(quint16 state); ++ // when XKEYBOARD not present on the X server + void updateXKBMods(); + quint32 xkbModMask(quint16 state); +-#else +- int coreDeviceId() { return core_device_id; } ++ void updateXKBStateFromCore(quint16 state); ++ // when XKEYBOARD is present on the X server ++ int coreDeviceId() const { return core_device_id; } ++#ifndef QT_NO_XKB + void updateXKBState(xcb_xkb_state_notify_event_t *state); + #endif + + protected: + void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); +- void resolveMaskConflicts(); + ++ void resolveMaskConflicts(); + QString keysymToUnicode(xcb_keysym_t sym) const; +- + int keysymToQtKey(xcb_keysym_t keysym) const; + int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; + + void readXKBConfig(); + void clearXKBConfig(); +- +-#ifdef QT_NO_XKB ++ // when XKEYBOARD not present on the X server + void updateModifiers(); +-#else ++ // when XKEYBOARD is present on the X server + void updateVModMapping(); + void updateVModToRModMapping(); +-#endif + + private: + bool m_config; +@@ -120,9 +120,8 @@ + + _mod_masks rmod_masks; + +-#ifdef QT_NO_XKB ++ // when XKEYBOARD not present on the X server + xcb_key_symbols_t *m_key_symbols; +- + struct _xkb_mods { + xkb_mod_index_t shift; + xkb_mod_index_t lock; +@@ -133,12 +132,10 @@ + xkb_mod_index_t mod4; + xkb_mod_index_t mod5; + }; +- + _xkb_mods xkb_mods; +-#else ++ // when XKEYBOARD is present on the X server + _mod_masks vmod_masks; + int core_device_id; +-#endif + }; + + QT_END_NAMESPACE +--- a/src/plugins/platforms/xcb/xcb-plugin.pro ++++ b/src/plugins/platforms/xcb/xcb-plugin.pro +@@ -121,13 +121,9 @@ + INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude + LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static + } else { +- LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr ++ LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-keysyms + !contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape +- contains(DEFINES, QT_NO_XKB) { +- LIBS += -lxcb-keysyms +- } else { +- LIBS += -lxcb-xkb +- } ++ !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb -lxkbcommon-x11 + } + + # libxkbcommon diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2014-0190.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2014-0190.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2014-0190.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2014-0190.patch 2015-05-27 17:53:35.000000000 +0000 @@ -0,0 +1,41 @@ +From eb1325047f2697d24e93ebaf924900affc876bc1 Mon Sep 17 00:00:00 2001 +From: Lars Knoll +Date: Thu, 24 Apr 2014 15:33:27 +0200 +Subject: [PATCH] Don't crash on broken GIF images + +Broken GIF images could set invalid width and height +values inside the image, leading to Qt creating a null +QImage for it. In that case we need to abort decoding +the image and return an error. + +Initial patch by Rich Moore. + +Task-number: QTBUG-38367 +Change-Id: Id82a4036f478bd6e49c402d6598f57e7e5bb5e1e +Security-advisory: CVE-2014-0190 +Reviewed-by: Richard J. Moore +--- + src/gui/image/qgifhandler.cpp | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp +index eeb62af..19b8382 100644 +--- a/src/gui/image/qgifhandler.cpp ++++ b/src/gui/image/qgifhandler.cpp +@@ -359,6 +359,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, + memset(bits, 0, image->byteCount()); + } + ++ // Check if the previous attempt to create the image failed. If it ++ // did then the image is broken and we should give up. ++ if (image->isNull()) { ++ state = Error; ++ return -1; ++ } ++ + disposePrevious(image); + disposed = false; + +-- +1.7.1 + diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-0295.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-0295.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-0295.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-0295.patch 2015-05-27 17:55:17.000000000 +0000 @@ -0,0 +1,39 @@ +Backport of: + +From 661f6bfd032dacc62841037732816a583640e187 Mon Sep 17 00:00:00 2001 +From: Richard J. Moore +Date: Sat, 21 Feb 2015 17:43:21 +0000 +Subject: [PATCH] Fix a division by zero when processing malformed BMP files. + +This fixes a division by 0 when processing a maliciously crafted BMP +file. No impact beyond DoS. + +Task-number: QTBUG-44547 +Change-Id: Ifcded2c0aa712e90d23e6b3969af0ec3add53973 +Reviewed-by: Thiago Macieira +Reviewed-by: Oswald Buddenhagen +--- + src/gui/image/qbmphandler.cpp | 8 ++++++++ + 1 files changed, 8 insertions(+), 0 deletions(-) + +Index: qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qbmphandler.cpp +=================================================================== +--- qtbase-opensource-src-5.2.1+dfsg.orig/src/gui/image/qbmphandler.cpp 2015-05-27 13:53:47.752594135 -0400 ++++ qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qbmphandler.cpp 2015-05-27 13:54:44.441291055 -0400 +@@ -319,10 +319,16 @@ + } + } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) { + red_shift = calc_shift(red_mask); ++ if (((red_mask >> red_shift) + 1) == 0) ++ return false; + red_scale = 256 / ((red_mask >> red_shift) + 1); + green_shift = calc_shift(green_mask); ++ if (((green_mask >> green_shift) + 1) == 0) ++ return false; + green_scale = 256 / ((green_mask >> green_shift) + 1); + blue_shift = calc_shift(blue_mask); ++ if (((blue_mask >> blue_shift) + 1) == 0) ++ return false; + blue_scale = 256 / ((blue_mask >> blue_shift) + 1); + } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) { + blue_mask = 0x000000ff; diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1858-1859.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1858-1859.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1858-1859.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1858-1859.patch 2015-05-27 17:55:36.000000000 +0000 @@ -0,0 +1,59 @@ +From 51ec7ebfe5f45d1c0a03d992e97053cac66e25fe Mon Sep 17 00:00:00 2001 +From: Eirik Aavitsland +Date: Wed, 11 Mar 2015 13:34:01 +0100 +Subject: [PATCH] Fixes crash in bmp and ico image decoding + +Fuzzing test revealed that for certain malformed bmp and ico files, +the handler would segfault. + +Change-Id: I19d45145f31e7f808f7f6a1a1610270ea4159cbe +Reviewed-by: Lars Knoll +--- + src/gui/image/qbmphandler.cpp | 13 +++++++------ + src/plugins/imageformats/ico/qicohandler.cpp | 2 +- + 2 files changed, 8 insertions(+), 7 deletions(-) + +Index: qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qbmphandler.cpp +=================================================================== +--- qtbase-opensource-src-5.2.1+dfsg.orig/src/gui/image/qbmphandler.cpp 2015-05-27 13:55:33.345892038 -0400 ++++ qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qbmphandler.cpp 2015-05-27 13:55:33.341891989 -0400 +@@ -478,12 +478,6 @@ + p = data + (h-y-1)*bpl; + break; + case 2: // delta (jump) +- // Protection +- if ((uint)x >= (uint)w) +- x = w-1; +- if ((uint)y >= (uint)h) +- y = h-1; +- + { + quint8 tmp; + d->getChar((char *)&tmp); +@@ -491,6 +485,13 @@ + d->getChar((char *)&tmp); + y += tmp; + } ++ ++ // Protection ++ if ((uint)x >= (uint)w) ++ x = w-1; ++ if ((uint)y >= (uint)h) ++ y = h-1; ++ + p = data + (h-y-1)*bpl + x; + break; + default: // absolute mode +Index: qtbase-opensource-src-5.2.1+dfsg/src/plugins/imageformats/ico/qicohandler.cpp +=================================================================== +--- qtbase-opensource-src-5.2.1+dfsg.orig/src/plugins/imageformats/ico/qicohandler.cpp 2015-05-27 13:55:33.345892038 -0400 ++++ qtbase-opensource-src-5.2.1+dfsg/src/plugins/imageformats/ico/qicohandler.cpp 2015-05-27 13:55:33.341891989 -0400 +@@ -571,7 +571,7 @@ + QImage::Format format = QImage::Format_ARGB32; + if (icoAttrib.nbits == 24) + format = QImage::Format_RGB32; +- else if (icoAttrib.ncolors == 2) ++ else if (icoAttrib.ncolors == 2 && icoAttrib.depth == 1) + format = QImage::Format_Mono; + else if (icoAttrib.ncolors > 0) + format = QImage::Format_Indexed8; diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1860.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1860.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1860.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/CVE-2015-1860.patch 2015-05-27 17:55:45.000000000 +0000 @@ -0,0 +1,27 @@ +From d3048a29797ee2d80d84bbda26bb3c954584f332 Mon Sep 17 00:00:00 2001 +From: Eirik Aavitsland +Date: Wed, 11 Mar 2015 09:00:41 +0100 +Subject: [PATCH] Fixes crash in gif image decoder + +Fuzzing test revealed that for certain malformed gif files, +qgifhandler would segfault. + +Change-Id: I5bb6f60e1c61849e0d8c735edc3869945e5331c1 +Reviewed-by: Richard J. Moore +--- + src/gui/image/qgifhandler.cpp | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +Index: qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qgifhandler.cpp +=================================================================== +--- qtbase-opensource-src-5.2.1+dfsg.orig/src/gui/image/qgifhandler.cpp 2015-05-27 13:55:42.318002271 -0400 ++++ qtbase-opensource-src-5.2.1+dfsg/src/gui/image/qgifhandler.cpp 2015-05-27 13:55:42.314002222 -0400 +@@ -944,6 +944,8 @@ + + void QGIFFormat::nextY(unsigned char *bits, int bpl) + { ++ if (out_of_bounds) ++ return; + int my; + switch (interlace) { + case 0: // Non-interlaced diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/series qtbase-opensource-src-5.2.1+dfsg/debian/patches/series --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/series 2014-04-01 12:44:51.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/series 2015-05-27 17:55:41.000000000 +0000 @@ -29,3 +29,9 @@ Minor-optimization-for-QTextEngine-shapeText.patch HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch When-looking-up-the-window-hierarchy-stop-at-foreign.patch +Add_better_support_for_keymap_update_handling.patch +xi2-use-master-device.patch +CVE-2014-0190.patch +CVE-2015-0295.patch +CVE-2015-1858-1859.patch +CVE-2015-1860.patch diff -Nru qtbase-opensource-src-5.2.1+dfsg/debian/patches/xi2-use-master-device.patch qtbase-opensource-src-5.2.1+dfsg/debian/patches/xi2-use-master-device.patch --- qtbase-opensource-src-5.2.1+dfsg/debian/patches/xi2-use-master-device.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtbase-opensource-src-5.2.1+dfsg/debian/patches/xi2-use-master-device.patch 2014-05-12 08:40:30.000000000 +0000 @@ -0,0 +1,81 @@ +Description: qt5 use xi2 master device instead of selecting events on all slave devices separately. +Author: Maarten Lankhorst + +For LP: #1307701 + +Selecting events from the master device has the advantage that we don't need to +grab the touch event to prevent mouse emulation to our window. + +--- +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -84,6 +84,7 @@ + m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest; + } else { + m_xi2Enabled = true; ++ has_touch_without_mouse_emulation = true; + } + if (m_xi2Enabled) { + if (Q_UNLIKELY(debug_xinput_devices)) +@@ -180,17 +181,9 @@ + XIEventMask mask; + mask.mask_len = sizeof(bitMask); + mask.mask = xiBitMask; +- // Enable each touchscreen +- foreach (XInput2DeviceData *dev, m_touchDevices.values()) { +- mask.deviceid = dev->xiDeviceInfo->deviceid; +- Status result = XISelectEvents(xDisplay, window, &mask, 1); +- // If we have XInput >= 2.2 and successfully enable a touchscreen, then +- // it will provide touch only. In most other cases, there will be +- // emulated mouse events from the driver. If not, then Qt must do its +- // own mouse emulation to enable interaction with mouse-oriented QWidgets. +- if (m_xi2Minor >= 2 && result == Success) +- has_touch_without_mouse_emulation = true; +- } ++ mask.deviceid = XIAllMasterDevices; ++ ++ Status result = XISelectEvents(xDisplay, window, &mask, 1); + #endif // XCB_USE_XINPUT22 + + #ifndef QT_NO_TABLETEVENT +@@ -201,7 +194,7 @@ + // all the pure xcb code with Xlib-based XI2. + if (!m_tabletData.isEmpty()) { + QVector xiEventMask(m_tabletData.count()); +- bitMask |= XI_ButtonPressMask; ++ bitMask = XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; + bitMask |= XI_PropertyEventMask; +@@ -329,7 +322,7 @@ + fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) ); + + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { +- XInput2DeviceData *dev = deviceForId(xiEvent->deviceid); ++ XInput2DeviceData *dev = deviceForId(xiDeviceEvent->sourceid); + Q_ASSERT(dev); + const bool firstTouch = m_touchPoints.isEmpty(); + if (xiEvent->evtype == XI_TouchBegin) { +@@ -434,22 +427,6 @@ + qDebug() << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << + " area " << touchPoint.area << " pressure " << touchPoint.pressure; + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values()); +- if (has_touch_without_mouse_emulation) { +- // We need to grab the touch event to prevent mouse emulation. +- if (xiEvent->evtype == XI_TouchBegin) { +- XIEventMask xieventmask; +- unsigned int bitMask = 0; +- unsigned char *xiBitMask = reinterpret_cast(&bitMask); +- xieventmask.deviceid = xiEvent->deviceid; +- xieventmask.mask = xiBitMask; +- xieventmask.mask_len = sizeof(bitMask); +- bitMask |= XI_TouchBeginMask; +- bitMask |= XI_TouchUpdateMask; +- bitMask |= XI_TouchEndMask; +- XIGrabDevice(static_cast(m_xlib_display), xiEvent->deviceid, platformWindow->winId(), xiEvent->time, None, GrabModeAsync, GrabModeAsync, true, &xieventmask); +- } else if (xiEvent->evtype == XI_TouchEnd) +- XIUngrabDevice(static_cast(m_xlib_display), xiEvent->deviceid, xiEvent->time); +- } + if (touchPoint.state == Qt::TouchPointReleased) + // If a touchpoint was released, we can forget it, because the ID won't be reused. + m_touchPoints.remove(touchPoint.id);