diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2010-10-06 08:31:37 (GMT) |
---|---|---|
committer | Samuli Piippo <samuli.piippo@digia.com> | 2011-06-09 10:07:03 (GMT) |
commit | 3650691c505607d5af7b2c7e7e2ab9db1739c836 (patch) | |
tree | 6c6d23b3ddd69e900e269c58a57f02ee6cea755b | |
parent | b8113220499fa8384bc2fbcc17aba59b636f2d48 (diff) | |
download | Qt-3650691c505607d5af7b2c7e7e2ab9db1739c836.zip Qt-3650691c505607d5af7b2c7e7e2ab9db1739c836.tar.gz Qt-3650691c505607d5af7b2c7e7e2ab9db1739c836.tar.bz2 |
Fixed a buffer overrun when pasting large data from non-Qt apps
When we receive a COMPOUND_TEXT data and convert it to multi-byte, if
the new length is less than the original buffer, we resize the buffer,
but then we need to make sure we reset the buffer_offset variable,
which is returned as a "size" of the buffer to a caller.
The conversion to COMPOUND_TEXT format was totally wrong, we were using
the wrong length of the input text, so the converted string was
truncated.
Task-number: QTBUG-8644
Reviewed-by: Bradley T. Hughes
(cherry picked from commit 4b81cb847647450f4bad8a0d9a278d43ebdfecc6)
-rw-r--r-- | src/gui/kernel/qclipboard_x11.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qdnd_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qmotifdnd_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qt_x11_p.h | 2 |
4 files changed, 12 insertions, 16 deletions
diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index 682b249..e375317 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -597,7 +597,7 @@ static inline int maxSelectionIncr(Display *dpy) { return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; } bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deleteProperty, - QByteArray *buffer, int *size, Atom *type, int *format, bool nullterm) + QByteArray *buffer, int *size, Atom *type, int *format) { int maxsize = maxSelectionIncr(display); ulong bytes_left; // bytes_after @@ -643,13 +643,13 @@ bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deletePrope break; } - int newSize = proplen + (nullterm ? 1 : 0); + int newSize = proplen; buffer->resize(newSize); bool ok = (buffer->size() == newSize); VDEBUG("QClipboard: read_property(): buffer resized to %d", buffer->size()); - if (ok) { + if (ok && newSize) { // could allocate buffer while (bytes_left) { @@ -685,23 +685,19 @@ bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deletePrope XTextProperty textprop; textprop.encoding = *type; textprop.format = *format; - textprop.nitems = length; + textprop.nitems = buffer_offset; textprop.value = (unsigned char *) buffer->data(); char **list_ret = 0; int count; if (XmbTextPropertyToTextList(display, &textprop, &list_ret, &count) == Success && count && list_ret) { - offset = strlen(list_ret[0]); - buffer->resize(offset + (nullterm ? 1 : 0)); + offset = buffer_offset = strlen(list_ret[0]); + buffer->resize(offset); memcpy(buffer->data(), list_ret[0], offset); } if (list_ret) XFreeStringList(list_ret); } - - // zero-terminate (for text) - if (nullterm) - buffer->data()[buffer_offset] = '\0'; } // correct size, not 0-term. @@ -744,7 +740,7 @@ QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property, if (event.xproperty.atom != property || event.xproperty.state != PropertyNewValue) continue; - if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0, false)) { + if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) { if (length == 0) { // no more data, we're done if (nullterm) { buf.resize(offset+1); @@ -1072,7 +1068,7 @@ bool QClipboard::event(QEvent *e) QByteArray multi_data; if (req->property == XNone || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data, - 0, &multi_type, &multi_format, 0) + 0, &multi_type, &multi_format) || multi_format != 32) { // MULTIPLE property not formatted correctly XSendEvent(dpy, req->requestor, False, NoEventMask, &event); @@ -1294,7 +1290,7 @@ QByteArray QClipboardWatcher::getDataInFormat(Atom fmtatom) const Atom type; XSelectInput(dpy, win, PropertyChangeMask); - if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0)) { if (type == ATOM(INCR)) { int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0; buf = X11->clipboardReadIncrementalProperty(win, ATOM(_QT_SELECTION), nbytes, false); diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index e681818..330fb3e 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -1862,7 +1862,7 @@ static QVariant xdndObtainData(const char *format, QVariant::Type requestedType) if (got) { Atom type; - if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0)) { if (type == ATOM(INCR)) { int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0; result = X11->clipboardReadIncrementalProperty(tw->effectiveWinId(), ATOM(XdndSelection), nbytes, false); diff --git a/src/gui/kernel/qmotifdnd_x11.cpp b/src/gui/kernel/qmotifdnd_x11.cpp index ea8a8bc..b995f3b 100644 --- a/src/gui/kernel/qmotifdnd_x11.cpp +++ b/src/gui/kernel/qmotifdnd_x11.cpp @@ -766,7 +766,7 @@ QVariant QX11Data::motifdndObtainData(const char *mimeType) if (got) { Atom type; - if (X11->clipboardReadProperty(tw->internalWinId(), Dnd_selection, true, &result, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(tw->internalWinId(), Dnd_selection, true, &result, 0, &type, 0)) { } } diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index e752e3c..8e484d6 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -350,7 +350,7 @@ struct QX11Data // from qclipboard_x11.cpp bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout); bool clipboardReadProperty(Window win, Atom property, bool deleteProperty, - QByteArray *buffer, int *size, Atom *type, int *format, bool nullterm); + QByteArray *buffer, int *size, Atom *type, int *format); QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm); // from qdnd_x11.cpp |