From 15a14599dbc321fbcdd4c865e22c27280676427d Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sun, 22 Jan 2006 17:25:30 +0000 Subject: [project @ 2006-01-22 17:25:30 by jmb] Convert local files to UTF-8 when dragged in (assumes they're encoded in the system local encoding). Fix potential buffer overflow in utf8_from_local_encoding svn path=/import/netsurf/; revision=2025 --- riscos/ucstables.c | 32 +++++++++++++++++++++++++------- riscos/window.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 14 deletions(-) (limited to 'riscos') diff --git a/riscos/ucstables.c b/riscos/ucstables.c index a431f4609..f14fdb395 100644 --- a/riscos/ucstables.c +++ b/riscos/ucstables.c @@ -18,6 +18,7 @@ #include "oslib/territory.h" #include "netsurf/riscos/ucstables.h" +#include "netsurf/utils/log.h" #include "netsurf/utils/utf8.h" #include "netsurf/utils/utils.h" @@ -582,7 +583,11 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { - *result = strndup(string, len); + temp = strndup(string, len); + if (!temp) + return UTF8_CONVERT_NOMEM; + + *result = temp; return UTF8_CONVERT_OK; } @@ -616,8 +621,8 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, return utf8_from_enc(string, enc, len, result); } - /* create output buffer (oversized, but not by much) */ - *(result) = malloc(len + (3 * offset_count) + 1); + /* create output buffer (oversized) */ + *(result) = malloc((len * 4) + (3 * offset_count) + 1); if (!(*result)) return UTF8_CONVERT_NOMEM; *(*result) = '\0'; @@ -625,13 +630,13 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, /* convert the chunks between offsets, then copy stripped * UTF-8 character into output string */ for (i = 0; i != offset_count; i++) { - off = (i > 0 ? offsets[i-1].offset + offsets[i-1].local->len - : 0); + off = (i > 0 ? offsets[i-1].offset + 1 : 0); err = utf8_from_enc(string + off, enc, offsets[i].offset - off, &temp); if (err != UTF8_CONVERT_OK) { assert(err != UTF8_CONVERT_BADENC); + LOG(("utf8_from_enc failed")); free(*result); return UTF8_CONVERT_NOMEM; } @@ -644,12 +649,12 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, /* handle last chunk */ if (offsets[offset_count - 1].offset < len) { - off = offsets[offset_count - 1].offset + - offsets[offset_count - 1].local->len; + off = offsets[offset_count - 1].offset + 1; err = utf8_from_enc(string + off, enc, len - off, &temp); if (err != UTF8_CONVERT_OK) { assert(err != UTF8_CONVERT_BADENC); + LOG(("utf8_from_enc failed")); free(*result); return UTF8_CONVERT_NOMEM; } @@ -659,5 +664,18 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len, free(temp); } + /* and copy into more reasonably-sized buffer */ + temp = malloc(strlen((*result)) + 1); + if (!temp) { + LOG(("malloc failed")); + free(*result); + return UTF8_CONVERT_NOMEM; + } + *temp = '\0'; + + strcpy(temp, (*result)); + free(*result); + *result = temp; + return UTF8_CONVERT_OK; } diff --git a/riscos/window.c b/riscos/window.c index c25b6c909..b8ca42456 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -1437,9 +1437,9 @@ bool ro_gui_status_click(wimp_pointer *pointer) struct gui_window *g = ro_gui_status_lookup(pointer->w); wimp_drag drag; os_error *error; - + assert(g); - + switch (pointer->i) { case ICON_STATUS_RESIZE: gui_current_drag_type = GUI_DRAG_STATUS_RESIZE; @@ -2209,11 +2209,23 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) return false; if (file_box) { + utf8_convert_ret ret; + char *utf8_fn; + + ret = utf8_from_local_encoding( + message->data.data_xfer.file_name, 0, + &utf8_fn); + if (ret != UTF8_CONVERT_OK) { + /* A bad encoding should never happen */ + assert(ret != UTF8_CONVERT_BADENC); + LOG(("utf8_from_local_encoding failed")); + /* Load was for us - just no memory */ + return true; + } /* Found: update form input. */ free(file_box->gadget->value); - file_box->gadget->value = - strdup(message->data.data_xfer.file_name); + file_box->gadget->value = utf8_fn; /* Redraw box. */ box_coords(file_box, &x, &y); @@ -2754,8 +2766,9 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename, { fileswitch_object_type obj_type; os_error *error; - char *buf; + char *buf, *utf8_buf; int size; + utf8_convert_ret ret; error = xosfile_read_stamped(filename, &obj_type, NULL, NULL, &size, NULL, NULL); @@ -2782,10 +2795,20 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename, return true; } + ret = utf8_from_local_encoding(buf, size + 1, &utf8_buf); + if (ret != UTF8_CONVERT_OK) { + /* bad encoding shouldn't happen */ + assert(ret != UTF8_CONVERT_BADENC); + LOG(("utf8_from_local_encoding failed")); + free(buf); + warn_user("NoMemory", NULL); + return true; + } + if (toolbar) { const char *ep = buf + size; const char *sp; - char *p = buf; + char *p = utf8_buf; /* skip leading whitespace */ while (p < ep && isspace(*p)) p++; @@ -2801,8 +2824,10 @@ bool ro_gui_window_import_text(struct gui_window *g, const char *filename, ro_gui_window_launch_url(g, sp); } else - browser_window_paste_text(g->bw, buf, size, true); + browser_window_paste_text(g->bw, utf8_buf, + strlen(utf8_buf), true); free(buf); + free(utf8_buf); return true; } -- cgit v1.2.3