[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
This commit is contained in:
John Mark Bell 2006-01-22 17:25:30 +00:00
parent 0a3489c9c2
commit 15a14599db
2 changed files with 57 additions and 14 deletions

View File

@ -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;
}

View File

@ -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;
}