[gnumeric] clipboard: handle ms html even better.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] clipboard: handle ms html even better.
- Date: Fri, 25 Jun 2010 17:32:01 +0000 (UTC)
commit bf04bee24c21af134e50c4c6ddb026ac1fec1f1b
Author: Morten Welinder <terra gnome org>
Date: Fri Jun 25 13:31:19 2010 -0400
clipboard: handle ms html even better.
ChangeLog | 1 +
src/gui-clipboard.c | 102 +++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 83 insertions(+), 20 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 097caf3..50eca4b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
* src/gui-clipboard.c (table_content_received): Skip headers for
MS HTML Format.
+ (parse_ms_headers): New function.
2010-06-25 Andreas J. Guelzow <aguelzow pyrshep ca>
diff --git a/src/gui-clipboard.c b/src/gui-clipboard.c
index 8ca93d3..a79c98c 100644
--- a/src/gui-clipboard.c
+++ b/src/gui-clipboard.c
@@ -371,6 +371,83 @@ image_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
}
static void
+parse_ms_headers (const char *data, size_t length, size_t *start, size_t *end)
+{
+ GHashTable *headers = g_hash_table_new_full
+ (g_str_hash, g_str_equal, g_free, g_free);
+ size_t limit = length;
+ size_t i = 0;
+ char *key = NULL;
+ char *value = NULL;
+ long sf, ef;
+ const char *v;
+
+ while (i < limit && data[i] != '<') {
+ size_t j, k;
+
+ for (j = i; j < limit; j++) {
+ if (data[j] == ':') {
+ key = g_strndup (data + i, j - i);
+ break;
+ }
+ if (g_ascii_isspace (data[j]))
+ goto bad;
+ }
+ if (j >= limit)
+ goto bad;
+ j++;
+
+ for (k = j; k < limit; k++) {
+ if (data[k] == '\n' || data[k] == '\r') {
+ value = g_strndup (data + j, k - j);
+ break;
+ }
+ }
+ if (k >= limit)
+ goto bad;
+ while (g_ascii_isspace (data[k]))
+ k++;
+
+ i = k;
+
+ if (debug_clipboard ())
+ g_printerr ("MS HTML Header [%s] => [%s]\n", key, value);
+
+ if (strcmp (key, "StartHTML") == 0) {
+ long l = strtol (value, NULL, 10);
+ limit = MIN (limit, MAX (0, l));
+ }
+
+ g_hash_table_replace (headers, key, value);
+ key = value = NULL;
+ }
+
+ v = g_hash_table_lookup (headers, "StartFragment");
+ sf = v ? strtol (v, NULL, 10) : -1;
+ if (sf < (long)limit)
+ goto bad;
+
+ v = g_hash_table_lookup (headers, "EndFragment");
+ ef = v ? strtol (v, NULL, 10) : -1;
+ if (ef < sf || ef > (long)length)
+ goto bad;
+
+ *start = sf;
+ *end = ef;
+ goto out;
+
+ bad:
+ g_free (key);
+ g_free (value);
+ *start = 0;
+ *end = length;
+
+ out:
+ g_hash_table_destroy (headers);
+}
+
+
+static void
table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
gpointer closure)
{
@@ -415,33 +492,18 @@ table_content_received (GtkClipboard *clipboard, GtkSelectionData *sel,
sel->length);
} else if (sel->target == gdk_atom_intern (HTML_ATOM_NAME_UNIX, FALSE) ||
sel->target == gdk_atom_intern (HTML_ATOM_NAME_WINDOWS, FALSE)) {
- char *data = sel->data;
size_t length = sel->length;
+ size_t start = 0, end = length;
if (sel->target == gdk_atom_intern (HTML_ATOM_NAME_WINDOWS, FALSE)) {
/* See bug 143084 */
- size_t i = 0;
- while (i + 9 < length) {
- if (memcmp (data + i, "<!DOCTYPE", 9) == 0) {
- if (debug_clipboard ())
- g_printerr ("Skipping %d bytes of headers.\n", (int)i);
- data += i;
- length -= i;
- break;
- }
- while (i < length) {
- if (data[i] == '\n' || data[i] == '\r') {
- while (i < length && g_ascii_isspace (data[i]))
- i++;
- break;
- }
- i++;
- }
- }
+ parse_ms_headers (sel->data, length, &start, &end);
}
content = table_cellregion_read (wbc, "Gnumeric_html:html",
- pt, data, length);
+ pt,
+ sel->data + start,
+ end - start);
} else if ((sel->target == gdk_atom_intern ( BIFF8_ATOM_NAME, FALSE)) ||
(sel->target == gdk_atom_intern ( BIFF8_ATOM_NAME_CITRIX, FALSE)) ||
(sel->target == gdk_atom_intern ( BIFF5_ATOM_NAME, FALSE)) ||
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]