summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-10-06 10:31:37 +0200
committerSamuli Piippo <samuli.piippo@digia.com>2011-06-09 13:07:03 +0300
commit3650691c505607d5af7b2c7e7e2ab9db1739c836 (patch)
tree6c6d23b3ddd69e900e269c58a57f02ee6cea755b
parentb8113220499fa8384bc2fbcc17aba59b636f2d48 (diff)
downloadqt4-tools-3650691c505607d5af7b2c7e7e2ab9db1739c836.tar.gz
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.cpp22
-rw-r--r--src/gui/kernel/qdnd_x11.cpp2
-rw-r--r--src/gui/kernel/qmotifdnd_x11.cpp2
-rw-r--r--src/gui/kernel/qt_x11_p.h2
4 files changed, 12 insertions, 16 deletions
diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp
index 682b249f00..e3753175f8 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 e6818180f4..330fb3e93e 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 ea8a8bc49a..b995f3bc60 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 e752e3c4cf..8e484d6fd0 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