summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2004-08-09 16:11:58 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2004-08-09 16:11:58 +0000
commitc9bd6fa9fce386526ea1327adea56128648f3355 (patch)
tree419a7d4fcfd1a7ae7229763f0b9ed2125be0a02c
parent91e6c7c65bb496f88f6af622f558b35c436f9cd2 (diff)
downloadnetsurf-c9bd6fa9fce386526ea1327adea56128648f3355.tar.gz
netsurf-c9bd6fa9fce386526ea1327adea56128648f3355.tar.bz2
[project @ 2004-08-09 16:11:58 by jmb]
Rework the interface of the URL handing module to allow for multiple error types. Modify save_complete URL rewriting appropriately. svn path=/import/netsurf/; revision=1206
-rw-r--r--content/fetch.c6
-rw-r--r--content/fetchcache.c5
-rw-r--r--css/css.c5
-rw-r--r--css/ruleset.c13
-rw-r--r--desktop/browser.c27
-rw-r--r--desktop/loginlist.c16
-rw-r--r--render/box.c67
-rw-r--r--render/html.c11
-rw-r--r--riscos/401login.c5
-rw-r--r--riscos/download.c3
-rw-r--r--riscos/hotlist.c10
-rw-r--r--riscos/save.c3
-rw-r--r--riscos/save_complete.c66
-rw-r--r--riscos/window.c5
-rw-r--r--utils/url.c214
-rw-r--r--utils/url.h14
16 files changed, 273 insertions, 197 deletions
diff --git a/content/fetch.c b/content/fetch.c
index 81f5e3a26..cb1353f98 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -227,12 +227,16 @@ struct fetch * fetch_start(char *url, char *referer,
CURLcode code;
CURLMcode codem;
struct curl_slist *slist;
+ url_func_result res;
fetch = malloc(sizeof (*fetch));
if (!fetch)
return 0;
- host = url_host(url);
+ res = url_host(url, &host);
+ /* we only fail memory exhaustion */
+ if (res == URL_FUNC_NOMEM)
+ goto failed;
LOG(("fetch %p, url '%s'", fetch, url));
diff --git a/content/fetchcache.c b/content/fetchcache.c
index e22a8ae5b..02ce109b1 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -206,6 +206,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const char *data,
char **params;
unsigned int i;
union content_msg_data msg_data;
+ url_func_result result;
switch (msg) {
case FETCH_TYPE:
@@ -283,8 +284,8 @@ void fetchcache_callback(fetch_msg msg, void *p, const char *data,
c->fetch = 0;
/* redirect URLs must be absolute by HTTP/1.1, but many sites send
* relative ones: treat them as relative to requested URL */
- url = url_join(data, c->url);
- if (url) {
+ result = url_join(data, c->url, &url);
+ if (result == URL_FUNC_OK) {
msg_data.redirect = url;
content_broadcast(c, CONTENT_MSG_REDIRECT, msg_data);
free(url);
diff --git a/css/css.c b/css/css.c
index c4bbb8025..fa3f6f3bb 100644
--- a/css/css.c
+++ b/css/css.c
@@ -579,6 +579,7 @@ void css_atimport(struct content *c, struct css_node *node)
unsigned int i;
char **import_url;
struct content **import_content;
+ url_func_result res;
LOG(("@import rule"));
@@ -666,8 +667,8 @@ void css_atimport(struct content *c, struct css_node *node)
return;
}
- url1 = url_join(url, c->url);
- if (!url1) {
+ res = url_join(url, c->url, &url1);
+ if (res != URL_FUNC_OK) {
free(url);
return;
}
diff --git a/css/ruleset.c b/css/ruleset.c
index f0ab22d1c..90ca00226 100644
--- a/css/ruleset.c
+++ b/css/ruleset.c
@@ -621,6 +621,7 @@ bool parse_uri(const struct css_node *v, char **uri)
bool string = false;
const char *u;
char *t, *url;
+ url_func_result res;
switch (v->type) {
case CSS_NODE_URI:
@@ -650,11 +651,11 @@ bool parse_uri(const struct css_node *v, char **uri)
* content is the parent HTML content
*/
if (v->stylesheet->type == CONTENT_HTML)
- *uri = url_join(url, v->stylesheet->data.html.base_url);
+ res = url_join(url, v->stylesheet->data.html.base_url, uri);
else
- *uri = url_join(url, v->stylesheet->url);
+ res = url_join(url, v->stylesheet->url, uri);
free(url);
- if (!*uri)
+ if (res != URL_FUNC_OK)
return false;
break;
case CSS_NODE_STRING:
@@ -663,11 +664,11 @@ bool parse_uri(const struct css_node *v, char **uri)
return false;
if (v->stylesheet->type == CONTENT_HTML)
- *uri = url_join(url, v->stylesheet->data.html.base_url);
+ res = url_join(url, v->stylesheet->data.html.base_url, uri);
else
- *uri = url_join(url, v->stylesheet->url);
+ res = url_join(url, v->stylesheet->url, uri);
free(url);
- if (!*uri)
+ if (res != URL_FUNC_OK)
return false;
break;
default:
diff --git a/desktop/browser.c b/desktop/browser.c
index 6e797a97e..36b6a9245 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -149,11 +149,12 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
struct content *c;
char *url2;
char *hash;
+ url_func_result res;
LOG(("bw %p, url %s", bw, url));
- url2 = url_normalize(url);
- if (!url2) {
+ res = url_normalize(url, &url2);
+ if (res != URL_FUNC_OK) {
LOG(("failed to normalize url %s", url));
return;
}
@@ -602,6 +603,7 @@ void browser_window_mouse_click_html(struct browser_window *bw,
struct content *content = c;
struct content *gadget_content = c;
struct form_control *gadget = 0;
+ url_func_result res;
/* search the box tree for a link, imagemap, or form control */
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
@@ -664,10 +666,10 @@ void browser_window_mouse_click_html(struct browser_window *bw,
/* drop through */
case GADGET_SUBMIT:
if (gadget->form) {
- url = url_join(gadget->form->action, base_url);
+ res = url_join(gadget->form->action, base_url, &url);
snprintf(status_buffer, sizeof status_buffer,
messages_get("FormSubmit"),
- url ? url :
+ (res == URL_FUNC_OK) ? url :
gadget->form->action);
status = status_buffer;
pointer = GUI_POINTER_POINT;
@@ -713,8 +715,8 @@ void browser_window_mouse_click_html(struct browser_window *bw,
}
} else if (href) {
- url = url_join(href, base_url);
- if (!url)
+ res = url_join(href, base_url, &url);
+ if (res != URL_FUNC_OK)
return;
if (title) {
@@ -1634,6 +1636,7 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
{
char *data = 0, *url = 0, *url1 = 0, *base;
struct form_successful_control *success;
+ url_func_result res;
assert(form);
assert(bw->current_content->type == CONTENT_HTML);
@@ -1659,8 +1662,8 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
else {
sprintf(url, "%s?%s", form->action, data);
}
- url1 = url_join(url, base);
- if (!url1)
+ res = url_join(url, base, &url1);
+ if (res != URL_FUNC_OK)
break;
browser_window_go(bw, url1);
break;
@@ -1672,15 +1675,15 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
warn_user("NoMemory", 0);
return;
}
- url = url_join(form->action, base);
- if (!url)
+ res = url_join(form->action, base, &url);
+ if (res != URL_FUNC_OK)
break;
browser_window_go_post(bw, url, data, 0, true);
break;
case method_POST_MULTIPART:
- url = url_join(form->action, base);
- if (!url)
+ res = url_join(form->action, base, &url);
+ if (res != URL_FUNC_OK)
break;
browser_window_go_post(bw, url, 0, success, true);
break;
diff --git a/desktop/loginlist.c b/desktop/loginlist.c
index 1baab81ac..3161bbd11 100644
--- a/desktop/loginlist.c
+++ b/desktop/loginlist.c
@@ -31,10 +31,13 @@ static struct login *loginlist = &login;
void login_list_add(char *host, char* logindets) {
struct login *nli = xcalloc(1, sizeof(*nli));
- char *temp = url_host(host);
+ char *temp;
char *i;
+ url_func_result res;
- assert(temp);
+ res = url_host(host, &temp);
+
+ assert(res == URL_FUNC_OK);
/* Go back to the path base ie strip the document name
* eg. http://www.blah.com/blah/test.htm becomes
@@ -75,6 +78,7 @@ struct login *login_list_get(char *url) {
char *temp, *host;
char *i;
int reached_scheme = 0;
+ url_func_result res;
if (url == NULL)
return NULL;
@@ -83,8 +87,8 @@ struct login *login_list_get(char *url) {
(strncasecmp(url, "https://", 8) != 0))
return NULL;
- host = url_host(url);
- if (host == 0 || strlen(host) == 0) return NULL;
+ res = url_host(url, &host);
+ if (res != URL_FUNC_OK || strlen(host) == 0) return NULL;
temp = xstrdup(url);
@@ -93,8 +97,8 @@ struct login *login_list_get(char *url) {
*/
if (strlen(host) > strlen(temp)) {
xfree(temp);
- temp = url_host(url);
- if (temp == 0 || strlen(temp) == 0) {
+ res = url_host(url, &temp);
+ if (res != URL_FUNC_OK || strlen(temp) == 0) {
xfree(host);
return NULL;
}
diff --git a/render/box.c b/render/box.c
index 32d643fb5..5776501b0 100644
--- a/render/box.c
+++ b/render/box.c
@@ -640,6 +640,7 @@ struct css_style * box_get_style(struct content *c,
struct css_style style_new;
char * s;
unsigned int i;
+ url_func_result res;
memcpy(style, parent_style, sizeof(struct css_style));
memcpy(&style_new, &css_blank_style, sizeof(struct css_style));
@@ -658,12 +659,12 @@ struct css_style * box_get_style(struct content *c,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "background"))) {
style->background_image.type = CSS_BACKGROUND_IMAGE_URI;
/**\todo This will leak memory. */
- style->background_image.uri = url_join(s, c->data.html.base_url);
+ res = url_join(s, c->data.html.base_url, &style->background_image.uri);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!style->background_image.uri ||
+ if (res != URL_FUNC_OK ||
strcasecmp(style->background_image.uri, c->data.html.base_url) == 0)
style->background_image.type = CSS_BACKGROUND_IMAGE_NONE;
xmlFree(s);
@@ -897,6 +898,7 @@ struct box_result box_image(xmlNode *n, struct box_status *status,
struct box *box;
char *s, *url, *s1, *map;
xmlChar *s2;
+ url_func_result res;
box = box_create(style, status->href, status->title, status->id,
status->content->data.html.box_pool);
@@ -926,12 +928,12 @@ struct box_result box_image(xmlNode *n, struct box_status *status,
/* remove leading and trailing whitespace */
s1 = strip(s);
- url = url_join(s1, status->content->data.html.base_url);
+ res = url_join(s1, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url ||
+ if (res != URL_FUNC_OK ||
strcasecmp(url, status->content->data.html.base_url) == 0) {
xmlFree(s);
return (struct box_result) {box, false, false};
@@ -1224,6 +1226,7 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
struct box* box = NULL;
struct form_control *gadget = NULL;
char *s, *type, *url;
+ url_func_result res;
type = (char *) xmlGetProp(n, (const xmlChar *) "type");
@@ -1356,12 +1359,13 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
gadget->box = box;
gadget->type = GADGET_IMAGE;
if ((s = (char *) xmlGetProp(n, (const xmlChar*) "src"))) {
- url = url_join(s, status->content->data.html.base_url);
+ res = url_join(s, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (url && strcasecmp(url, status->content->data.html.base_url) != 0)
+ if (res == URL_FUNC_OK &&
+ strcasecmp(url, status->content->data.html.base_url) != 0)
html_fetch_object(status->content, url, box,
image_types,
status->content->available_width,
@@ -2049,6 +2053,7 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
struct plugin_params* pp;
char *s, *url = NULL, *map;
xmlNode *c;
+ url_func_result res;
box = box_create(style, status->href, 0, status->id,
status->content->data.html.box_pool);
@@ -2065,12 +2070,12 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
/* object data */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) {
- url = url_join(s, status->content->data.html.base_url);
+ res = url_join(s, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url || strcasecmp(url, status->content->data.html.base_url) == 0) {
+ if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
return (struct box_result) {box, true, true};
@@ -2193,6 +2198,7 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
struct plugin_params *pp;
char *s, *url = NULL;
xmlAttr *a;
+ url_func_result res;
box = box_create(style, status->href, 0, status->id,
status->content->data.html.box_pool);
@@ -2209,12 +2215,12 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
/* embed src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
- url = url_join(s, status->content->data.html.base_url);
+ res = url_join(s, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url || strcasecmp(url, status->content->data.html.base_url) == 0) {
+ if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
return (struct box_result) {box, false, true};
@@ -2268,6 +2274,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
struct plugin_params *pp;
char *s, *url = NULL;
xmlNode *c;
+ url_func_result res;
box = box_create(style, status->href, 0, status->id,
status->content->data.html.box_pool);
@@ -2284,12 +2291,12 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
/* code */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) {
- url = url_join(s, status->content->data.html.base_url);
+ res = url_join(s, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url || strcasecmp(url, status->content->data.html.base_url) == 0) {
+ if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
return (struct box_result) {box, true, false};
@@ -2376,6 +2383,7 @@ struct box_result box_iframe(xmlNode *n, struct box_status *status,
struct box *box;
struct object_params *po;
char *s, *url = NULL;
+ url_func_result res;
box = box_create(style, status->href, 0, status->id,
status->content->data.html.box_pool);
@@ -2392,12 +2400,12 @@ struct box_result box_iframe(xmlNode *n, struct box_status *status,
/* iframe src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
- url = url_join(s, status->content->data.html.base_url);
+ res = url_join(s, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url || strcasecmp(url, status->content->data.html.base_url) == 0) {
+ if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
return (struct box_result) {box, false, true};
@@ -2430,16 +2438,17 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
struct object_params* po)
{
struct plugin_params * pp;
+ url_func_result res;
/* Check if the codebase attribute is defined.
* If it is not, set it to the codebase of the current document.
*/
if(po->codebase == 0)
- po->codebase = url_join("./", content->data.html.base_url);
+ res = url_join("./", content->data.html.base_url, &po->codebase);
else
- po->codebase = url_join(po->codebase, content->data.html.base_url);
+ res = url_join(po->codebase, content->data.html.base_url, &po->codebase);
- if (!po->codebase)
+ if (res != URL_FUNC_OK)
return false;
/* Set basehref */
@@ -2464,13 +2473,14 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
pp = pp->next);
if(pp == 0)
return false;
- url = url_join(pp->value, po->basehref);
- if (!url)
+ res = url_join(pp->value, po->basehref, &url);
+ if (res != URL_FUNC_OK)
return false;
/* munge the codebase */
- po->codebase = url_join("./",
- content->data.html.base_url);
- if (!po->codebase)
+ res = url_join("./",
+ content->data.html.base_url,
+ &po->codebase);
+ if (res != URL_FUNC_OK)
return false;
}
else {
@@ -2479,8 +2489,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
}
}
else {
- url = url_join(po->classid, po->codebase);
- if (!url)
+ res = url_join(po->classid, po->codebase, &url);
+ if (res != URL_FUNC_OK)
return false;
/* The java plugin doesn't need the .class extension
@@ -2492,8 +2502,8 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
}
}
else {
- url = url_join(po->data, po->codebase);
- if (!url)
+ res = url_join(po->data, po->codebase, &url);
+ if (res != URL_FUNC_OK)
return false;
}
@@ -2537,6 +2547,7 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
struct box_result r;
struct box_multi_length *row_height = 0, *col_width = 0;
xmlNode *c;
+ url_func_result res;
box = box_create(style, 0, status->title, status->id,
status->content->data.html.box_pool);
@@ -2676,12 +2687,12 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
}
s1 = strip(s);
- url = url_join(s1, status->content->data.html.base_url);
+ res = url_join(s1, status->content->data.html.base_url, &url);
/* if url is equivalent to the parent's url,
* we've got infinite inclusion. stop it here.
* also bail if url_join failed.
*/
- if (!url || strcasecmp(url, status->content->data.html.base_url) == 0) {
+ if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
xmlFree(s);
c = c->next;
continue;
diff --git a/render/html.c b/render/html.c
index 7bda3b02a..b19e99c30 100644
--- a/render/html.c
+++ b/render/html.c
@@ -304,8 +304,10 @@ void html_head(struct content *c, xmlNode *head)
} else if (strcmp(node->name, "base") == 0) {
char *href = (char *) xmlGetProp(node, (const xmlChar *) "href");
if (href) {
- char *url = url_normalize(href);
- if (url) {
+ char *url;
+ url_func_result res;
+ res = url_normalize(href, &url);
+ if (res == URL_FUNC_OK) {
free(c->data.html.base_url);
c->data.html.base_url = url;
}
@@ -330,6 +332,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
unsigned int i = STYLESHEET_START;
unsigned int last_active = 0;
union content_msg_data msg_data;
+ url_func_result res;
/* stylesheet 0 is the base style sheet,
* stylesheet 1 is the adblocking stylesheet,
@@ -414,9 +417,9 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
/* TODO: only the first preferred stylesheets (ie. those with a
* title attribute) should be loaded (see HTML4 14.3) */
- url = url_join(href, c->data.html.base_url);
+ res = url_join(href, c->data.html.base_url, &url);
xmlFree(href);
- if (!url)
+ if (res != URL_FUNC_OK)
continue;
LOG(("linked stylesheet %i '%s'", i, url));
diff --git a/riscos/401login.c b/riscos/401login.c
index 8beaac9be..9edef15a8 100644
--- a/riscos/401login.c
+++ b/riscos/401login.c
@@ -46,10 +46,11 @@ void ro_gui_401login_init(void)
void gui_401login_open(struct browser_window *bw, struct content *c, char *realm)
{
char *murl, *host;
+ url_func_result res;
murl = c->url;
- host = url_host(murl);
- assert(host);
+ res = url_host(murl, &host);
+ assert(res == URL_FUNC_OK);
bwin = bw;
ro_gui_401login_open(bw->window->window, host, realm, murl);
diff --git a/riscos/download.c b/riscos/download.c
index 2a6d8d583..77aa9a217 100644
--- a/riscos/download.c
+++ b/riscos/download.c
@@ -128,6 +128,7 @@ struct gui_download_window *gui_download_window_create(const char *url,
char temp_name[40];
struct gui_download_window *dw;
os_error *error;
+ url_func_result res;
dw = malloc(sizeof *dw);
if (!dw) {
@@ -188,7 +189,7 @@ struct gui_download_window *gui_download_window_create(const char *url,
(osspriteop_id) dw->sprite_name;
strcpy(dw->path, messages_get("SaveObject"));
- if ((nice = url_nice(url))) {
+ if ((res = url_nice(url, &nice)) == URL_FUNC_OK) {
strcpy(dw->path, nice);
free(nice);
}
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index 8a2a57100..de91fbad7 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -906,6 +906,7 @@ struct hotlist_entry *ro_gui_hotlist_create_entry(const char *title,
const char *url, int filetype,
struct hotlist_entry *folder) {
struct hotlist_entry *entry;
+ url_func_result res;
/* Check we have a title or a URL
*/
@@ -923,7 +924,8 @@ struct hotlist_entry *ro_gui_hotlist_create_entry(const char *title,
use the URL instead
*/
entry->url = 0;
- if ((url) && ((entry->url = url_normalize(url)) == 0)) {
+ if ((url) && ((res = url_normalize(url, &entry->url)) != URL_FUNC_OK)) {
+ /** \todo use correct error message */
warn_user("NoMemory", 0);
free(entry->url);
free(entry);
@@ -2443,6 +2445,7 @@ void ro_gui_hotlist_dialog_click(wimp_pointer *pointer) {
int close_icon, ok_icon;
bool folder;
bool add;
+ url_func_result res;
/* Get our data
*/
@@ -2502,8 +2505,9 @@ void ro_gui_hotlist_dialog_click(wimp_pointer *pointer) {
if (entry == NULL) return;
if (url) {
old_value = entry->url;
- entry->url = url_normalize(url);
- if (!entry->url) {
+ res = url_normalize(url, &entry->url);
+ if (res != URL_FUNC_OK) {
+ /** \todo use correct error message */
warn_user("NoMemory", 0);
entry->url = old_value;
return;
diff --git a/riscos/save.c b/riscos/save.c
index 14564f727..b73f57a8d 100644
--- a/riscos/save.c
+++ b/riscos/save.c
@@ -84,6 +84,7 @@ void ro_gui_save_open(gui_save_type save_type, struct content *c,
const char *name = "";
const char *nice;
os_error *error;
+ url_func_result res;
assert(save_type == GUI_SAVE_HOTLIST_EXPORT_HTML || c);
@@ -102,7 +103,7 @@ void ro_gui_save_open(gui_save_type save_type, struct content *c,
/* filename */
name = gui_save_table[save_type].name;
if (c) {
- if ((nice = url_nice(c->url)))
+ if ((res = url_nice(c->url, &nice)) == URL_FUNC_OK)
name = nice;
}
ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name);
diff --git a/riscos/save_complete.c b/riscos/save_complete.c
index fad990c20..519181188 100644
--- a/riscos/save_complete.c
+++ b/riscos/save_complete.c
@@ -342,6 +342,7 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
unsigned int i;
unsigned int imports = 0;
regmatch_t match[11];
+ url_func_result result;
/* count number occurences of @import to (over)estimate result size */
/* can't use strstr because source is not 0-terminated string */
@@ -399,9 +400,9 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
free(res);
return 0;
}
- url = url_join(url2, base);
+ result = url_join(url2, base, (char**)&url);
free(url2);
- if (!url) {
+ if (result == URL_FUNC_NOMEM) {
free(res);
return 0;
}
@@ -410,17 +411,25 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
memcpy(res + *osize, source + offset, match[0].rm_so);
*osize += match[0].rm_so;
- content = save_complete_list_find(url);
- if (content) {
- /* replace import */
- snprintf(buf, sizeof buf, "@import '%x'",
- (unsigned int) content);
- memcpy(res + *osize, buf, strlen(buf));
- *osize += strlen(buf);
- } else {
+ if (result == URL_FUNC_OK) {
+ content = save_complete_list_find(url);
+ if (content) {
+ /* replace import */
+ snprintf(buf, sizeof buf, "@import '%x'",
+ (unsigned int) content);
+ memcpy(res + *osize, buf, strlen(buf));
+ *osize += strlen(buf);
+ } else {
+ /* copy import */
+ memcpy(res + *osize, source + offset + match[0].rm_so,
+ match[0].rm_eo - match[0].rm_so);
+ *osize += match[0].rm_eo - match[0].rm_so;
+ }
+ }
+ else {
/* copy import */
memcpy(res + *osize, source + offset + match[0].rm_so,
- match[0].rm_eo - match[0].rm_so);
+ match[0].rm_eo - match[0].rm_so);
*osize += match[0].rm_eo - match[0].rm_so;
}
@@ -570,6 +579,7 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base)
char *url, *data;
char rel[20];
struct content *content;
+ url_func_result res;
if (!xmlHasProp(n, (const xmlChar *) attr))
return true;
@@ -578,25 +588,29 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base)
if (!data)
return false;
- url = url_join(data, base);
+ res = url_join(data, base, &url);
xmlFree(data);
- if (!url)
+ if (res == URL_FUNC_NOMEM)
return false;
-
- content = save_complete_list_find(url);
- if (content) {
- /* found a match */
- free(url);
- snprintf(rel, sizeof rel, "%x", (unsigned int) content);
- if (!xmlSetProp(n, (const xmlChar *) attr, (xmlChar *) rel))
- return false;
- } else {
- /* no match found */
- if (!xmlSetProp(n, (const xmlChar *) attr, (xmlChar *) url)) {
+ else if (res == URL_FUNC_OK) {
+ content = save_complete_list_find(url);
+ if (content) {
+ /* found a match */
+ free(url);
+ snprintf(rel, sizeof rel, "%x",
+ (unsigned int) content);
+ if (!xmlSetProp(n, (const xmlChar *) attr,
+ (xmlChar *) rel))
+ return false;
+ } else {
+ /* no match found */
+ if (!xmlSetProp(n, (const xmlChar *) attr,
+ (xmlChar *) url)) {
+ free(url);
+ return false;
+ }
free(url);
- return false;
}
- free(url);
}
return true;
diff --git a/riscos/window.c b/riscos/window.c
index ab945cb0d..a0715738d 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -1235,6 +1235,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
char *url;
os_error *error;
wimp_pointer pointer;
+ url_func_result res;
error = xwimp_get_pointer_info(&pointer);
if (error) {
@@ -1361,8 +1362,8 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
case wimp_KEY_RETURN:
if (!toolbar)
break;
- url = url_normalize(g->url);
- if (url) {
+ res = url_normalize(g->url, &url);
+ if (res == URL_FUNC_OK) {
gui_window_set_url(g, url);
browser_window_go(g->bw, url);
free(url);
diff --git a/utils/url.c b/utils/url.c
index 09c2816bf..b1da7ce28 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -57,20 +57,21 @@ void url_init(void)
* replaced with "/". Characters are unescaped if safe.
*/
-char *url_normalize(const char *url)
+url_func_result url_normalize(const char *url, char **result)
{
char c;
- char *res = 0;
int m;
int i;
int len;
bool http = false;
regmatch_t match[10];
+ (*result) = 0;
+
m = regexec(&url_re, url, 10, match, 0);
if (m) {
LOG(("url '%s' failed to match regex", url));
- return 0;
+ return URL_FUNC_FAILED;
}
len = strlen(url);
@@ -78,27 +79,27 @@ char *url_normalize(const char *url)
if (match[1].rm_so == -1) {
/* scheme missing: add http:// and reparse */
LOG(("scheme missing: using http"));
- res = malloc(strlen(url) + 13);
- if (!res) {
+ (*result) = malloc(strlen(url) + 13);
+ if (!(*result)) {
LOG(("malloc failed"));
- return 0;
+ return URL_FUNC_NOMEM;
}
- strcpy(res, "http://");
- strcpy(res + 7, url);
- m = regexec(&url_re, res, 10, match, 0);
+ strcpy((*result), "http://");
+ strcpy((*result) + 7, url);
+ m = regexec(&url_re, (*result), 10, match, 0);
if (m) {
- LOG(("url '%s' failed to match regex", res));
- free(res);
- return 0;
+ LOG(("url '%s' failed to match regex", (*result)));
+ free((*result));
+ return URL_FUNC_FAILED;
}
len += 7;
} else {
- res = malloc(len + 6);
- if (!res) {
+ (*result) = malloc(len + 6);
+ if (!(*result)) {
LOG(("strdup failed"));
- return 0;
+ return URL_FUNC_FAILED;
}
- strcpy(res, url);
+ strcpy((*result), url);
}
/*for (unsigned int i = 0; i != 10; i++) {
@@ -113,55 +114,59 @@ char *url_normalize(const char *url)
/* make scheme lower-case */
if (match[2].rm_so != -1) {
for (i = match[2].rm_so; i != match[2].rm_eo; i++)
- res[i] = tolower(res[i]);
- if (match[2].rm_eo == 4 && res[0] == 'h' && res[1] == 't' &&
- res[2] == 't' && res[3] == 'p')
+ (*result)[i] = tolower((*result)[i]);
+ if (match[2].rm_eo == 4 && (*result)[0] == 'h' &&
+ (*result)[1] == 't' && (*result)[2] == 't' &&
+ (*result)[3] == 'p')
http = true;
}
/* make empty path into "/" */
if (match[5].rm_so != -1 && match[5].rm_so == match[5].rm_eo) {
- memmove(res + match[5].rm_so + 1, res + match[5].rm_so,
+ memmove((*result) + match[5].rm_so + 1,
+ (*result) + match[5].rm_so,
len - match[5].rm_so + 1);
- res[match[5].rm_so] = '/';
+ (*result)[match[5].rm_so] = '/';
len++;
}
/* make host lower-case */
if (match[4].rm_so != -1) {
for (i = match[4].rm_so; i != match[4].rm_eo; i++) {
- if (res[i] == ':') {
- if (http && res[i + 1] == '8' &&
- res[i + 2] == '0' &&
+ if ((*result)[i] == ':') {
+ if (http && (*result)[i + 1] == '8' &&
+ (*result)[i + 2] == '0' &&
i + 3 == match[4].rm_eo) {
- memmove(res + i, res + i + 3,
+ memmove((*result) + i,
+ (*result) + i + 3,
len - match[4].rm_eo);
len -= 3;
- res[len] = '\0';
+ (*result)[len] = '\0';
} else if (i + 1 == match[4].rm_eo) {
- memmove(res + i, res + i + 1,
+ memmove((*result) + i,
+ (*result) + i + 1,
len - match[4].rm_eo);
len--;
- res[len] = '\0';
+ (*result)[len] = '\0';
}
break;
}
- res[i] = tolower(res[i]);
+ (*result)[i] = tolower((*result)[i]);
}
}
/* unescape non-"reserved" escaped characters */
for (i = 0; i != len; i++) {
- if (res[i] != '%')
+ if ((*result)[i] != '%')
continue;
- c = tolower(res[i + 1]);
+ c = tolower((*result)[i + 1]);
if ('0' <= c && c <= '9')
m = 16 * (c - '0');
else if ('a' <= c && c <= 'f')
m = 16 * (c - 'a' + 10);
else
continue;
- c = tolower(res[i + 2]);
+ c = tolower((*result)[i + 2]);
if ('0' <= c && c <= '9')
m += c - '0';
else if ('a' <= c && c <= 'f')
@@ -175,12 +180,12 @@ char *url_normalize(const char *url)
continue;
}
- res[i] = m;
- memmove(res + i + 1, res + i + 3, len - i - 2);
+ (*result)[i] = m;
+ memmove((*result) + i + 1, (*result) + i + 3, len - i - 2);
len -= 2;
}
- return res;
+ return URL_FUNC_OK;
}
@@ -192,12 +197,11 @@ char *url_normalize(const char *url)
* \return an absolute URL, allocated on the heap, or 0 on failure
*/
-char *url_join(const char *rel, const char *base)
+url_func_result url_join(const char *rel, const char *base, char **result)
{
int m;
int i, j;
char *buf = 0;
- char *res;
const char *scheme = 0, *authority = 0, *path = 0, *query = 0,
*fragment = 0;
int scheme_len = 0, authority_len = 0, path_len = 0, query_len = 0,
@@ -206,11 +210,13 @@ char *url_join(const char *rel, const char *base)
regmatch_t rel_match[10];
regmatch_t up_match[3];
+ (*result) = 0;
+
/* see RFC 2396 section 5.2 */
m = regexec(&url_re, base, 10, base_match, 0);
if (m) {
LOG(("base url '%s' failed to match regex", base));
- return 0;
+ return URL_FUNC_FAILED;
}
/*for (unsigned int i = 0; i != 10; i++) {
if (base_match[i].rm_so == -1)
@@ -221,7 +227,7 @@ char *url_join(const char *rel, const char *base)
}*/
if (base_match[2].rm_so == -1) {
LOG(("base url '%s' is not absolute", base));
- return 0;
+ return URL_FUNC_FAILED;
}
scheme = base + base_match[2].rm_so;
scheme_len = base_match[2].rm_eo - base_match[2].rm_so;
@@ -236,7 +242,7 @@ char *url_join(const char *rel, const char *base)
m = regexec(&url_re, rel, 10, rel_match, 0);
if (m) {
LOG(("relative url '%s' failed to match regex", rel));
- return 0;
+ return URL_FUNC_FAILED;
}
/* 2) */
@@ -292,7 +298,7 @@ char *url_join(const char *rel, const char *base)
buf = malloc(path_len + rel_match[5].rm_eo + 10);
if (!buf) {
LOG(("malloc failed"));
- return 0;
+ return URL_FUNC_NOMEM;
}
/* a) */
strncpy(buf, path, path_len);
@@ -334,44 +340,44 @@ char *url_join(const char *rel, const char *base)
path = buf;
step7: /* 7) */
- res = malloc(scheme_len + 1 + 2 + authority_len + path_len + 1 + 1 +
+ (*result) = malloc(scheme_len + 1 + 2 + authority_len + path_len + 1 + 1 +
query_len + 1 + fragment_len + 1);
- if (!res) {
+ if (!(*result)) {
LOG(("malloc failed"));
free(buf);
- return 0;
+ return URL_FUNC_NOMEM;
}
- strncpy(res, scheme, scheme_len);
- res[scheme_len] = ':';
+ strncpy((*result), scheme, scheme_len);
+ (*result)[scheme_len] = ':';
i = scheme_len + 1;
if (authority) {
- res[i++] = '/';
- res[i++] = '/';
- strncpy(res + i, authority, authority_len);
+ (*result)[i++] = '/';
+ (*result)[i++] = '/';
+ strncpy((*result) + i, authority, authority_len);
i += authority_len;
}
if (path_len) {
- strncpy(res + i, path, path_len);
+ strncpy((*result) + i, path, path_len);
i += path_len;
} else {
- res[i++] = '/';
+ (*result)[i++] = '/';
}
if (query) {
- res[i++] = '?';
- strncpy(res + i, query, query_len);
+ (*result)[i++] = '?';
+ strncpy((*result) + i, query, query_len);
i += query_len;
}
if (fragment) {
- res[i++] = '#';
- strncpy(res + i, fragment, fragment_len);
+ (*result)[i++] = '#';
+ strncpy((*result) + i, fragment, fragment_len);
i += fragment_len;
}
- res[i] = 0;
+ (*result)[i] = 0;
free(buf);
- return res;
+ return URL_FUNC_OK;
}
@@ -382,29 +388,30 @@ step7: /* 7) */
* \returns host name allocated on heap, or 0 on failure
*/
-char *url_host(const char *url)
+url_func_result url_host(const char *url, char **result)
{
int m;
- char *host;
regmatch_t match[10];
+ (*result) = 0;
+
m = regexec(&url_re, url, 10, match, 0);
if (m) {
LOG(("url '%s' failed to match regex", url));
- return 0;
+ return URL_FUNC_FAILED;
}
if (match[4].rm_so == -1)
- return 0;
+ return URL_FUNC_FAILED;
- host = malloc(match[4].rm_eo - match[4].rm_so + 1);
- if (!host) {
+ (*result) = malloc(match[4].rm_eo - match[4].rm_so + 1);
+ if (!(*result)) {
LOG(("malloc failed"));
- return 0;
+ return URL_FUNC_NOMEM;
}
- strncpy(host, url + match[4].rm_so, match[4].rm_eo - match[4].rm_so);
- host[match[4].rm_eo - match[4].rm_so] = 0;
+ strncpy((*result), url + match[4].rm_so, match[4].rm_eo - match[4].rm_so);
+ (*result)[match[4].rm_eo - match[4].rm_so] = 0;
- return host;
+ return URL_FUNC_OK;
}
@@ -415,27 +422,29 @@ char *url_host(const char *url)
* \returns filename allocated on heap, or 0 on memory exhaustion
*/
-char *url_nice(const char *url)
+url_func_result url_nice(const char *url, char **result)
{
unsigned int i, j, k = 0, so;
unsigned int len;
const char *colon;
char buf[40];
- char *result;
char *rurl;
int m;
regmatch_t match[10];
- result = malloc(40);
- if (!result)
- return 0;
+ /* just in case */
+ (*result) = 0;
+
+ (*result) = malloc(40);
+ if (!(*result))
+ return URL_FUNC_NOMEM;
len = strlen(url);
assert(len != 0);
rurl = malloc(len + 1);
if (!rurl) {
- free(result);
- return 0;
+ free((*result));
+ return URL_FUNC_NOMEM;
}
/* reverse url into rurl */
@@ -447,11 +456,11 @@ char *url_nice(const char *url)
colon = strchr(url, ':');
if (colon)
url = colon + 1;
- strncpy(result, url, 15);
- result[15] = 0;
- for (i = 0; result[i]; i++)
- if (!isalnum(result[i]))
- result[i] = '_';
+ strncpy((*result), url, 15);
+ (*result)[15] = 0;
+ for (i = 0; (*result)[i]; i++)
+ if (!isalnum((*result)[i]))
+ (*result)[i] = '_';
/* append nice pieces */
j = 0;
@@ -481,19 +490,21 @@ char *url_nice(const char *url)
if (k == 0) {
free(rurl);
- return result;
+ return URL_FUNC_OK;
}
/* reverse back */
for (i = 0, j = k - 1; i != k; i++, j--)
- result[i] = buf[j];
- result[k] = 0;
+ (*result)[i] = buf[j];
+ (*result)[k] = 0;
for (i = 0; i != k; i++)
- if (result[i] != (char) 0xa0 && !isalnum(result[i]))
- result[i] = '_';
+ if ((*result)[i] != (char) 0xa0 && !isalnum((*result)[i]))
+ (*result)[i] = '_';
+
+ free(rurl);
- return result;
+ return URL_FUNC_OK;
}
@@ -503,26 +514,35 @@ char *url_nice(const char *url)
int main(int argc, char *argv[])
{
int i;
+ url_func_result res;
char *s;
url_init();
- for (i = 1; i != argc; i++) {
-/* printf("==> '%s'\n", argv[i]);
- s = url_normalize(argv[i]);
- if (s)
- printf("<== '%s'\n", s);*/
+/* for (i = 1; i != argc; i++) {
+ printf("==> '%s'\n", argv[i]);
+ res = url_normalize(argv[i], &s);
+ if (res == URL_FUNC_OK) {
+ printf("<== '%s'\n", s);
+ free(s);
+ }*/
/* printf("==> '%s'\n", argv[i]);
- s = url_host(argv[i]);
- if (s)
- printf("<== '%s'\n", s);*/
+ res = url_host(argv[i], &s);
+ if (res == URL_FUNC_OK) {
+ printf("<== '%s'\n", s);
+ free(s);
+ }*/
/* if (1 != i) {
- s = url_join(argv[i], argv[1]);
- if (s)
+ res = url_join(argv[i], argv[1], &s);
+ if (res == URL_FUNC_OK) {
printf("'%s' + '%s' \t= '%s'\n", argv[1],
argv[i], s);
+ free(s);
+ }
}*/
- s = url_nice(argv[i]);
- if (s)
+ res = url_nice(argv[i], &s);
+ if (res == URL_FUNC_OK) {
printf("'%s'\n", s);
+ free(s);
+ }
}
return 0;
}
diff --git a/utils/url.h b/utils/url.h
index 96aa947f5..cc373b257 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -12,10 +12,16 @@
#ifndef _NETSURF_UTILS_URL_H_
#define _NETSURF_UTILS_URL_H_
+typedef enum {
+ URL_FUNC_OK, /**< No error */
+ URL_FUNC_NOMEM, /**< Insufficient memory */
+ URL_FUNC_FAILED /**< Non fatal error (eg failed to match regex) */
+} url_func_result;
+
void url_init(void);
-char *url_normalize(const char *url);
-char *url_join(const char *rel, const char *base);
-char *url_host(const char *url);
-char *url_nice(const char *url);
+url_func_result url_normalize(const char *url, char **result);
+url_func_result url_join(const char *rel, const char *base, char **result);
+url_func_result url_host(const char *url, char **result);
+url_func_result url_nice(const char *url, char **result);
#endif