From 65b510fbc3ad822ab8c75e6d94eaee5b6ceb07a4 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Thu, 23 Jul 2015 00:05:22 +0100 Subject: Rework IDN URL retrieval to return an nserror --- amiga/gui.c | 32 +++++++++++++++------------- render/html_interaction.c | 17 +++++++++------ utils/nsurl.c | 53 ++++++++++++++++++++++++----------------------- utils/nsurl.h | 16 ++++++++------ 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/amiga/gui.c b/amiga/gui.c index 8c2fde542..afc05bf67 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -4892,23 +4892,27 @@ static void gui_window_set_status(struct gui_window *g, const char *text) static nserror gui_window_set_url(struct gui_window *g, nsurl *url) { + size_t idn_url_l; + char *idn_url_s = NULL; + char *url_lc = NULL; + if(!g) return NSERROR_OK; if (g == g->shared->gw) { - if(nsoption_bool(display_decoded_idn) == false) { - RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL], - g->shared->win, NULL, - STRINGA_TextVal, nsurl_access(url), - TAG_DONE); - } else { - char *idn_url = nsurl_access_utf8(url); - char *idn_url_lc = ami_utf8_easy(idn_url); - RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL], - g->shared->win, NULL, - STRINGA_TextVal, idn_url_lc, - TAG_DONE); - free(idn_url); - ami_utf8_free(idn_url_lc); + if(nsoption_bool(display_decoded_idn) == true) { + if (nsurl_access_utf8(url, &idn_url_s, &idn_url_l) == NSERROR_OK) { + url_lc = ami_utf8_easy(idn_url_s); + } + } + + RefreshSetGadgetAttrs((struct Gadget *)g->shared->objects[GID_URL], + g->shared->win, NULL, + STRINGA_TextVal, url_lc ? url_lc : nsurl_access(url), + TAG_DONE); + + if(url_lc) { + ami_utf8_free(url_lc); + if(idn_url_s) free(idn_url_s); } } diff --git a/render/html_interaction.c b/render/html_interaction.c index af8417448..1b2e5b9c9 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -300,7 +300,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw, enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE; const char *title = 0; nsurl *url = 0; - char *idn_url = NULL; + char *url_s = NULL; + size_t url_l = 0; const char *target = 0; char status_buffer[200]; const char *status = 0; @@ -816,21 +817,25 @@ void html_mouse_action(struct content *c, struct browser_window *bw, } } else if (url) { if (nsoption_bool(display_decoded_idn) == true) { - idn_url = nsurl_access_utf8(url); + if (nsurl_access_utf8(url, &url_s, &url_l) != NSERROR_OK) { + /* Unable to obtain a decoded IDN. This is not a fatal error. + * Ensure the string pointer is NULL so we use the encoded version. */ + url_s = NULL; + } } if (title) { snprintf(status_buffer, sizeof status_buffer, "%s: %s", - idn_url ? idn_url : nsurl_access(url), title); + url_s ? url_s : nsurl_access(url), title); } else { snprintf(status_buffer, sizeof status_buffer, "%s", - idn_url ? idn_url : nsurl_access(url)); + url_s ? url_s : nsurl_access(url)); } status = status_buffer; - if (idn_url != NULL) - free(idn_url); + if (url_s != NULL) + free(url_s); pointer = get_pointer_shape(url_box, imagemap); diff --git a/utils/nsurl.c b/utils/nsurl.c index 78647b4ae..ed6d896b6 100644 --- a/utils/nsurl.c +++ b/utils/nsurl.c @@ -1698,8 +1698,11 @@ const char *nsurl_access(const nsurl *url) return url->string; } -char *nsurl_access_utf8(const nsurl *url) + +/* exported interface, documented in nsurl.h */ +nserror nsurl_access_utf8(const nsurl *url, char **url_s, size_t *url_l) { + nserror err; lwc_string *host; char *idna_host; size_t idna_host_len; @@ -1707,45 +1710,43 @@ char *nsurl_access_utf8(const nsurl *url) size_t scheme_len; char *path; size_t path_len; - char *idna_url; - size_t idna_url_len; assert(url != NULL); host = nsurl_get_component(url, NSURL_HOST); - if(host == NULL) { - return strdup(url->string); - } + if(host == NULL) + return NSERROR_BAD_URL; - if (idna_decode(lwc_string_data(host), lwc_string_length(host), - &idna_host, &idna_host_len) != NSERROR_OK) { - lwc_string_unref(host); - return strdup(url->string); - } + err = idna_decode(lwc_string_data(host), lwc_string_length(host), + &idna_host, &idna_host_len); lwc_string_unref(host); - if (nsurl_get(url, NSURL_SCHEME | NSURL_CREDENTIALS, - &scheme, &scheme_len) != NSERROR_OK) { - return strdup(url->string); - } + if (err != NSERROR_OK) + return err; - if (nsurl_get(url, NSURL_PORT | NSURL_PATH | NSURL_QUERY | NSURL_FRAGMENT, - &path, &path_len) != NSERROR_OK) { - return strdup(url->string); - } + err = nsurl_get(url, NSURL_SCHEME | NSURL_CREDENTIALS, + &scheme, &scheme_len); - idna_url_len = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */ - idna_url = malloc(idna_url_len); + if (err != NSERROR_OK) + return err; - if (idna_url == NULL) { - return strdup(url->string); - } + err = nsurl_get(url, NSURL_PORT | NSURL_PATH | NSURL_QUERY | NSURL_FRAGMENT, + &path, &path_len); + + if (err != NSERROR_OK) + return err; + + *url_l = scheme_len + idna_host_len + path_len + 1; /* +1 for \0 */ + *url_s = malloc(*url_l); - snprintf(idna_url, idna_url_len, "%s%s%s", scheme, idna_host, path); + if (*url_s == NULL) + return NSERROR_NOMEM; + + snprintf(*url_s, *url_l, "%s%s%s", scheme, idna_host, path); - return(idna_url); + return NSERROR_OK; } diff --git a/utils/nsurl.h b/utils/nsurl.h index 07d73f17f..383b35711 100644 --- a/utils/nsurl.h +++ b/utils/nsurl.h @@ -181,17 +181,21 @@ const char *nsurl_access(const nsurl *url); /** - * Access a NetSurf URL object as a UTF-8 string (for human readable IDNA) + * Access a NetSurf URL object as a UTF-8 string (for human readable IDNs) * * \param url NetSurf URL to retrieve a string pointer for. - * \return the required string + * \param url_s Returns a url string + * \param url_l Returns length of url_s + * \return NSERROR_OK on success, appropriate error otherwise + * + * If return value != NSERROR_OK, nothing will be returned in url_s or url_l. * - * It is up to the client to free the returned string when they have - * finished with it. + * The string returned in url_s is owned by the client and it is up to them + * to free it. It includes a trailing '\0'. * - * The returned string has a trailing '\0'. + * The length returned in url_l excludes the trailing '\0'. */ -char *nsurl_access_utf8(const nsurl *url); +nserror nsurl_access_utf8(const nsurl *url, char **url_s, size_t *url_l); /** -- cgit v1.2.3