Changeset 61881 in webkit


Ignore:
Timestamp:
Jun 25, 2010 12:50:04 PM (14 years ago)
Author:
Martin Robinson
Message:

2010-06-25 Martin Robinson <mrobinson@igalia.com>

Reviewed by Xan Lopez.

[GTK] Pasteboard code does not take into account the nil character when getting and setting markup/netscape-url data
https://bugs.webkit.org/show_bug.cgi?id=41221

Take into account null-terminator when getting and setting markup and
Netscape URL pasteboard types. This means that if the selection data
contains the null terminator, it won't be included in the final String.
When setting the pasteboard data the null terminator is now included to
match the behavior of other applications.

  • platform/gtk/PasteboardHelper.cpp: (WebCore::PasteboardHelper::getClipboardContents): Create the markup string after using g_strndup to protect against non-null-terminated strings. Use String::fromUTF8 here to ensure that the string is not longer than the first null-terminator. Also fix a small indentation issue. (WebCore::PasteboardHelper::fillSelectionData): Always include the null-terminator when setting pasteboard data manually. This matches the behavior of other browser applications.

2010-06-25 Martin Robinson <mrobinson@igalia.com>

Reviewed by Xan Lopez.

[GTK] Pasteboard code does not take into account the nil character when getting and setting markup/netscape-url data
https://bugs.webkit.org/show_bug.cgi?id=41221

Add a test for this issue which simulates a paste keyboard event into an editable
body. The pasteboard should contain a markup portion containing a null terminator.

  • tests/testcopyandpaste.c: (test_info_new): (test_info_destroy): (load_status_cb): (runPasteTestCallback): (window_object_cleared_callback): (pasting_test_get_data_callback): (pasting_test_clear_data_callback): (test_pasting_markup): (main):
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r61880 r61881  
     12010-06-25  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Xan Lopez.
     4
     5        [GTK] Pasteboard code does not take into account the nil character when getting and setting markup/netscape-url data
     6        https://bugs.webkit.org/show_bug.cgi?id=41221
     7
     8        Take into account null-terminator when getting and setting markup and
     9        Netscape URL pasteboard types. This means that if the selection data
     10        contains the null terminator, it won't be included in the final String.
     11        When setting the pasteboard data the null terminator is now included to
     12        match the behavior of other applications.
     13
     14        * platform/gtk/PasteboardHelper.cpp:
     15        (WebCore::PasteboardHelper::getClipboardContents):
     16        Create the markup string after using g_strndup to protect against non-null-terminated
     17        strings. Use String::fromUTF8 here to ensure that the string is not longer than the
     18        first null-terminator. Also fix a small indentation issue.
     19        (WebCore::PasteboardHelper::fillSelectionData):
     20        Always include the null-terminator when setting pasteboard data manually. This matches
     21        the behavior of other browser applications.
     22
    1232010-06-25  Sam Magnuson  <smagnuson@netflix.com>
    224
  • trunk/WebCore/platform/gtk/PasteboardHelper.cpp

    r61802 r61881  
    115115
    116116    if (gtk_clipboard_wait_is_target_available(clipboard, gdkMarkupAtom)) {
    117        if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, gdkMarkupAtom)) {
    118           RefPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("text/plain", "UTF-8", true));
    119           String markup(decoder->decode(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data)));
    120           markup += decoder->flush();
    121           dataObject->setMarkup(markup);
    122           gtk_selection_data_free(data);
    123        }
     117        if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, gdkMarkupAtom)) {
     118            // g_strndup guards against selection data that is not null-terminated.
     119            GOwnPtr<gchar> markupString(g_strndup(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data)));
     120            dataObject->setMarkup(String::fromUTF8(markupString.get()));
     121            gtk_selection_data_free(data);
     122        }
    124123    }
    125124
     
    144143        GOwnPtr<gchar> markup(g_strdup(dataObject->markup().utf8().data()));
    145144        gtk_selection_data_set(selectionData, gdkMarkupAtom, 8,
    146             reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()));
     145            reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()) + 1);
    147146
    148147    } else if (info == getIdForTargetType(TargetTypeURIList)) {
     
    167166        GOwnPtr<gchar> resultData(g_strdup(result.utf8().data()));
    168167        gtk_selection_data_set(selectionData, netscapeURLAtom, 8,
    169             reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()));
     168            reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()) + 1);
    170169
    171170    } else if (info == getIdForTargetType(TargetTypeImage))
  • trunk/WebKit/gtk/ChangeLog

    r61808 r61881  
     12010-06-25  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Xan Lopez.
     4
     5        [GTK] Pasteboard code does not take into account the nil character when getting and setting markup/netscape-url data
     6        https://bugs.webkit.org/show_bug.cgi?id=41221
     7
     8        Add a test for this issue which simulates a paste keyboard event into an editable
     9        body. The pasteboard should contain a markup portion containing a null terminator.
     10
     11        * tests/testcopyandpaste.c:
     12        (test_info_new):
     13        (test_info_destroy):
     14        (load_status_cb):
     15        (runPasteTestCallback):
     16        (window_object_cleared_callback):
     17        (pasting_test_get_data_callback):
     18        (pasting_test_clear_data_callback):
     19        (test_pasting_markup):
     20        (main):
     21
    1222010-06-24  Martin Robinson  <mrobinson@igalia.com>
    223
  • trunk/WebKit/gtk/tests/testcopyandpaste.c

    r60447 r61881  
    3131typedef struct {
    3232    char* page;
    33     char* expectedPlainText;
     33    char* expectedContent;
    3434} TestInfo;
    3535
     
    4242
    4343TestInfo*
    44 test_info_new(const char* page, const char* expectedPlainText)
     44test_info_new(const char* page, const char* expectedContent)
    4545{
    4646    TestInfo* info;
    4747    info = g_slice_new0(TestInfo);
    4848    info->page = g_strdup(page);
    49     if (expectedPlainText)
    50         info->expectedPlainText = g_strdup(expectedPlainText);
     49    if (expectedContent)
     50        info->expectedContent = g_strdup(expectedContent);
    5151    return info;
    5252}
     
    5656{
    5757    g_free(info->page);
    58     g_free(info->expectedPlainText);
     58    g_free(info->expectedContent);
    5959    g_slice_free(TestInfo, info);
    6060}
     
    9090
    9191    gchar* text = gtk_clipboard_wait_for_text(clipboard);
    92     g_assert(text || !fixture->info->expectedPlainText);
    93     g_assert(!text || !strcmp(text, fixture->info->expectedPlainText));
     92    g_assert(text || !fixture->info->expectedContent);
     93    g_assert(!text || !strcmp(text, fixture->info->expectedContent));
    9494    g_free(text);
    9595
     
    124124    g_main_loop_run(fixture->loop);
    125125}
     126
     127static CopyAndPasteFixture* currentFixture;
     128static JSValueRef runPasteTestCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     129{
     130    // Simulate a paste keyboard sequence.
     131    GdkEvent event;
     132    memset(&event, 0, sizeof(event));
     133    event.key.keyval = gdk_unicode_to_keyval('v');
     134    event.key.state = GDK_CONTROL_MASK;
     135    event.key.window = GTK_WIDGET(currentFixture->webView)->window;
     136    GdkKeymapKey* keys;
     137    gint n_keys;
     138    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), event.key.keyval, &keys, &n_keys)) {
     139        event.key.hardware_keycode = keys[0].keycode;
     140        g_free(keys);
     141    }
     142    event.key.type = GDK_KEY_PRESS;
     143    gtk_main_do_event(&event);
     144    event.key.type = GDK_KEY_RELEASE;
     145    gtk_main_do_event(&event);
     146
     147    JSStringRef scriptString = JSStringCreateWithUTF8CString("document.body.innerHTML;");
     148    JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0);
     149    JSStringRelease(scriptString);
     150
     151    g_assert(JSValueIsString(context, value));
     152    JSStringRef actual = JSValueToStringCopy(context, value, exception);
     153    g_assert(!exception || !*exception);
     154    g_assert(currentFixture->info->expectedContent);
     155    JSStringRef expected = JSStringCreateWithUTF8CString(currentFixture->info->expectedContent);
     156    g_assert(JSStringIsEqual(expected, actual));
     157
     158    JSStringRelease(expected);
     159    JSStringRelease(actual);
     160    g_main_loop_quit(currentFixture->loop);
     161    return JSValueMakeUndefined(context);
     162}
     163
     164static void window_object_cleared_callback(WebKitWebView* web_view, WebKitWebFrame* web_frame, JSGlobalContextRef context, JSObjectRef window_object, gpointer data)
     165{
     166    JSStringRef name = JSStringCreateWithUTF8CString("runTest");
     167    JSObjectRef testComplete = JSObjectMakeFunctionWithCallback(context, name, runPasteTestCallback);
     168    JSObjectSetProperty(context, window_object, name, testComplete, kJSPropertyAttributeNone, 0);
     169    JSStringRelease(name);
     170}
     171
     172static void pasting_test_get_data_callback(GtkClipboard* clipboard, GtkSelectionData* selection_data, guint info, gpointer data)
     173{
     174    gtk_selection_data_set(selection_data, gdk_atom_intern("text/html", FALSE), 8, (const guchar*) data, strlen((char*)data) + 1);
     175}
     176
     177static void pasting_test_clear_data_callback(GtkClipboard* clipboard, gpointer data)
     178{
     179    g_free(data);
     180}
     181
     182static void test_pasting_markup(CopyAndPasteFixture* fixture, gconstpointer data)
     183{
     184    fixture->info = (TestInfo*)data;
     185    currentFixture = fixture;
     186
     187    GtkTargetList* targetList = gtk_target_list_new(0, 0);
     188    gtk_target_list_add(targetList, gdk_atom_intern("text/html", FALSE), 0, 0);
     189
     190    int numberOfTargets = 1;
     191    GtkTargetEntry* targetTable = gtk_target_table_new_from_list(targetList, &numberOfTargets);
     192    gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
     193                                targetTable, numberOfTargets,
     194                                pasting_test_get_data_callback,
     195                                pasting_test_clear_data_callback,
     196                                g_strdup(fixture->info->expectedContent));
     197    gtk_target_list_unref(targetList);
     198    gtk_target_table_free(targetTable, numberOfTargets);
     199
     200    g_signal_connect(fixture->window, "map-event",
     201                     G_CALLBACK(map_event_cb), fixture);
     202    g_signal_connect(fixture->webView, "window-object-cleared",
     203                     G_CALLBACK(window_object_cleared_callback), fixture);
     204
     205    gtk_widget_show(fixture->window);
     206    gtk_widget_show(GTK_WIDGET(fixture->webView));
     207    gtk_window_present(GTK_WINDOW(fixture->window));
     208
     209    g_main_loop_run(fixture->loop);
     210}
     211
    126212
    127213int main(int argc, char** argv)
     
    152238               copy_and_paste_fixture_teardown);
    153239
     240    const char* paste_test_html = "<html>"
     241        "<body onLoad=\"document.body.focus(); runTest();\" contentEditable=\"true\">"
     242        "</body></html>";
     243    g_test_add("/webkit/copyandpaste/paste-markup", CopyAndPasteFixture,
     244               test_info_new(paste_test_html, "bobby"),
     245               copy_and_paste_fixture_setup,
     246               test_pasting_markup,
     247               copy_and_paste_fixture_teardown);
     248
    154249    return g_test_run();
    155250}
Note: See TracChangeset for help on using the changeset viewer.