зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1611407 [Linux/X11] Don't try to get text clipboard data of binary MIME types, r=jhorak
X11 tries to convert any binary clipboard data to text if text MIME type is missing in clipboard. This leads to various errors, wrong conversions and timeouts. So get clipboard content first and if there are only binary MIME types in clipboard advertise only these types. Differential Revision: https://phabricator.services.mozilla.com/D123687
This commit is contained in:
Родитель
8197b9611b
Коммит
646adf404e
|
@ -253,6 +253,76 @@ void nsClipboard::SetTransferableData(nsITransferable* aTransferable,
|
|||
aTransferable->SetTransferData(aFlavor.get(), wrapper);
|
||||
}
|
||||
|
||||
static bool IsMIMEAtFlavourList(const nsTArray<nsCString>& aFlavourList,
|
||||
const char* aMime) {
|
||||
for (const auto& flavorStr : aFlavourList) {
|
||||
if (flavorStr.Equals(aMime)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// When clipboard contains only images, X11/Gtk tries to convert them
|
||||
// to text when we request text instead of just fail to provide the data.
|
||||
// So if clipboard contains images only remove text MIME offer.
|
||||
bool nsClipboard::FilterImportedFlavors(int32_t aWhichClipboard,
|
||||
nsTArray<nsCString>& aFlavors) {
|
||||
LOGCLIP(("nsClipboard::FilterImportedFlavors"));
|
||||
|
||||
int targetNums;
|
||||
GdkAtom* targets = mContext->GetTargets(aWhichClipboard, &targetNums);
|
||||
if (!targets) {
|
||||
LOGCLIP((" X11: no targes at clipboard (null), quit.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < targetNums; i++) {
|
||||
gchar* atom_name = gdk_atom_name(targets[i]);
|
||||
if (!atom_name) {
|
||||
continue;
|
||||
}
|
||||
// Filter out system MIME types.
|
||||
if (strcmp(atom_name, "TARGETS") == 0 ||
|
||||
strcmp(atom_name, "TIMESTAMP") == 0 ||
|
||||
strcmp(atom_name, "SAVE_TARGETS") == 0 ||
|
||||
strcmp(atom_name, "MULTIPLE") == 0) {
|
||||
continue;
|
||||
}
|
||||
// Filter out types which can't be converted to text.
|
||||
if (strncmp(atom_name, "image/", 6) == 0 ||
|
||||
strncmp(atom_name, "application/", 12) == 0 ||
|
||||
strncmp(atom_name, "audio/", 6) == 0 ||
|
||||
strncmp(atom_name, "video/", 6) == 0) {
|
||||
continue;
|
||||
}
|
||||
// We have some other MIME type on clipboard which can be hopefully
|
||||
// converted to text without any problem.
|
||||
LOGCLIP((" X11: text types in clipboard, no need to filter them.\n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// So make sure we offer only types we have at clipboard.
|
||||
nsTArray<nsCString> clipboardFlavors;
|
||||
for (int i = 0; i < targetNums; i++) {
|
||||
gchar* atom_name = gdk_atom_name(targets[i]);
|
||||
if (!atom_name) {
|
||||
continue;
|
||||
}
|
||||
if (IsMIMEAtFlavourList(aFlavors, atom_name)) {
|
||||
clipboardFlavors.AppendElement(nsCString(atom_name));
|
||||
}
|
||||
}
|
||||
aFlavors.SwapElements(clipboardFlavors);
|
||||
#ifdef MOZ_LOGGING
|
||||
LOGCLIP((" X11: Flavors which match clipboard content:\n"));
|
||||
for (uint32_t i = 0; i < aFlavors.Length(); i++) {
|
||||
LOGCLIP((" %s\n", aFlavors[i].get()));
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
|
||||
LOGCLIP(("nsClipboard::GetData (%s)\n",
|
||||
|
@ -270,7 +340,6 @@ nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
|
|||
LOGCLIP((" FlavorsTransferableCanImport falied!\n"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
LOGCLIP(("Flavors which can be imported:\n"));
|
||||
for (uint32_t i = 0; i < flavors.Length(); i++) {
|
||||
|
@ -278,6 +347,14 @@ nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Filter out MIME types on X11 to prevent unwanted conversions,
|
||||
// see Bug 1611407
|
||||
if (widget::GdkIsX11Display()) {
|
||||
if (!FilterImportedFlavors(aWhichClipboard, flavors)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < flavors.Length(); i++) {
|
||||
nsCString& flavorStr = flavors[i];
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ class nsClipboard : public nsIClipboard, public nsIObserver {
|
|||
|
||||
void ClearTransferable(int32_t aWhichClipboard);
|
||||
|
||||
bool FilterImportedFlavors(int32_t aWhichClipboard,
|
||||
nsTArray<nsCString>& aFlavors);
|
||||
|
||||
// Hang on to our owners and transferables so we can transfer data
|
||||
// when asked.
|
||||
nsCOMPtr<nsIClipboardOwner> mSelectionOwner;
|
||||
|
|
|
@ -204,9 +204,11 @@ void nsRetrievalContextX11::Complete(ClipboardDataType aDataType,
|
|||
|
||||
gint dataLength = gtk_selection_data_get_length(selection);
|
||||
const guchar* data = gtk_selection_data_get_data(selection);
|
||||
|
||||
LOGCLIP((" got data %p len %d\n", data, dataLength));
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
GdkAtom target = gtk_selection_data_get_target(selection);
|
||||
LOGCLIP((" got data %p len %d MIME %s\n", data, dataLength,
|
||||
gdk_atom_name(target)));
|
||||
#endif
|
||||
if (dataLength > 0) {
|
||||
mClipboardDataLength = dataLength;
|
||||
mClipboardData = moz_xmalloc(dataLength);
|
||||
|
@ -266,14 +268,17 @@ bool nsRetrievalContextX11::WaitForClipboardData(ClipboardDataType aDataType,
|
|||
|
||||
switch (aDataType) {
|
||||
case CLIPBOARD_DATA:
|
||||
LOGCLIP((" getting DATA MIME %s\n", aMimeType));
|
||||
gtk_clipboard_request_contents(clipboard,
|
||||
gdk_atom_intern(aMimeType, FALSE),
|
||||
clipboard_contents_received, handler);
|
||||
break;
|
||||
case CLIPBOARD_TEXT:
|
||||
LOGCLIP((" getting TEXT\n"));
|
||||
gtk_clipboard_request_text(clipboard, clipboard_text_received, handler);
|
||||
break;
|
||||
case CLIPBOARD_TARGETS:
|
||||
LOGCLIP((" getting TARGETS\n"));
|
||||
gtk_clipboard_request_contents(clipboard, mTargetMIMEType,
|
||||
clipboard_contents_received, handler);
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче