Backed out changeset bb2acd046eae (bug 1497580) for clipboard failures on test_clipboard_events.html. CLOSED TREE

This commit is contained in:
Narcis Beleuzu 2018-10-17 02:02:33 +03:00
Родитель 517c9916eb
Коммит 0b8074bdd7
1 изменённых файлов: 30 добавлений и 45 удалений

Просмотреть файл

@ -34,16 +34,12 @@
#include "mozilla/Encoding.h" #include "mozilla/Encoding.h"
using namespace mozilla; using namespace mozilla;
// Idle timeout for receiving selection and property notify events (microsec) // Idle timeout for receiving selection and property notify events (microsec)
const int kClipboardTimeout = 500000; const int kClipboardTimeout = 500000;
// We add this prefix to HTML markup, so that GetHTMLCharset can correctly
// detect the HTML as UTF-8 encoded.
static const char kHTMLMarkupPrefix[] =
R"(<meta http-equiv="content-type" content="text/html; charset=utf-8">)";
// Callback when someone asks us for the data // Callback when someone asks us for the data
void void
clipboard_get_cb(GtkClipboard *aGtkClipboard, clipboard_get_cb(GtkClipboard *aGtkClipboard,
@ -531,31 +527,6 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard,
return; return;
} }
if (selectionTarget == gdk_atom_intern(kHTMLMime, FALSE)) {
rv = trans->GetTransferData(kHTMLMime, getter_AddRefs(item), &len);
if (!item || NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsISupportsString> wideString;
wideString = do_QueryInterface(item);
if (!wideString) {
return;
}
nsAutoString ucs2string;
wideString->GetData(ucs2string);
nsAutoCString html;
// Add the prefix so the encoding is correctly detected.
html.AppendLiteral(kHTMLMarkupPrefix);
AppendUTF16toUTF8(ucs2string, html);
gtk_selection_data_set(aSelectionData, selectionTarget, 8,
(const guchar*)html.get(), html.Length());
return;
}
// Try to match up the selection data target to something our // Try to match up the selection data target to something our
// transferable provides. // transferable provides.
gchar *target_name = gdk_atom_name(selectionTarget); gchar *target_name = gdk_atom_name(selectionTarget);
@ -574,10 +545,31 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard,
item, &primitive_data, len); item, &primitive_data, len);
if (primitive_data) { if (primitive_data) {
// Check to see if the selection data is text/html
if (selectionTarget == gdk_atom_intern (kHTMLMime, FALSE)) {
/*
* "text/html" can be encoded UCS2. It is recommended that
* documents transmitted as UCS2 always begin with a ZERO-WIDTH
* NON-BREAKING SPACE character (hexadecimal FEFF, also called
* Byte Order Mark (BOM)). Adding BOM can help other app to
* detect mozilla use UCS2 encoding when copy-paste.
*/
guchar *buffer = (guchar *)
g_malloc((len * sizeof(guchar)) + sizeof(char16_t));
if (!buffer)
return;
char16_t prefix = 0xFEFF;
memcpy(buffer, &prefix, sizeof(prefix));
memcpy(buffer + sizeof(prefix), primitive_data, len);
g_free((guchar *)primitive_data);
primitive_data = (guchar *)buffer;
len += sizeof(prefix);
}
gtk_selection_data_set(aSelectionData, selectionTarget, gtk_selection_data_set(aSelectionData, selectionTarget,
8, /* 8 bits in a unit */ 8, /* 8 bits in a unit */
(const guchar *)primitive_data, len); (const guchar *)primitive_data, len);
free(primitive_data); g_free(primitive_data);
} }
g_free(target_name); g_free(target_name);
@ -664,19 +656,8 @@ void ConvertHTMLtoUCS2(const char* data, int32_t dataLength,
outUnicodeLen = 0; outUnicodeLen = 0;
return; return;
} }
auto dataSpan = MakeSpan(data, dataLength);
// Remove kHTMLMarkupPrefix again, it won't necessarily cause any
// issues, but might confuse other users.
const size_t prefixLen = ArrayLength(kHTMLMarkupPrefix) - 1;
if (dataSpan.Length() >= prefixLen &&
!strncmp(data, kHTMLMarkupPrefix, prefixLen)) {
dataSpan = dataSpan.From(prefixLen);
}
auto decoder = encoding->NewDecoder(); auto decoder = encoding->NewDecoder();
CheckedInt<size_t> needed = CheckedInt<size_t> needed = decoder->MaxUTF16BufferLength(dataLength);
decoder->MaxUTF16BufferLength(dataSpan.Length());
if (!needed.isValid() || needed.value() > INT32_MAX) { if (!needed.isValid() || needed.value() > INT32_MAX) {
outUnicodeLen = 0; outUnicodeLen = 0;
return; return;
@ -691,13 +672,17 @@ void ConvertHTMLtoUCS2(const char* data, int32_t dataLength,
size_t written; size_t written;
bool hadErrors; bool hadErrors;
Tie(result, read, written, hadErrors) = Tie(result, read, written, hadErrors) =
decoder->DecodeToUTF16(AsBytes(dataSpan), decoder->DecodeToUTF16(AsBytes(MakeSpan(data, dataLength)),
MakeSpan(*unicodeData, needed.value()), MakeSpan(*unicodeData, needed.value()),
true); true);
MOZ_ASSERT(result == kInputEmpty); MOZ_ASSERT(result == kInputEmpty);
MOZ_ASSERT(read == size_t(dataSpan.Length())); MOZ_ASSERT(read == size_t(dataLength));
MOZ_ASSERT(written <= needed.value()); MOZ_ASSERT(written <= needed.value());
Unused << hadErrors; Unused << hadErrors;
#ifdef DEBUG_CLIPBOARD
if (read != dataLength)
printf("didn't consume all the bytes\n");
#endif
outUnicodeLen = written; outUnicodeLen = written;
// null terminate. // null terminate.
(*unicodeData)[outUnicodeLen] = '\0'; (*unicodeData)[outUnicodeLen] = '\0';