[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
This commit is contained in:
John Mark Bell 2004-08-09 16:11:58 +00:00
parent 91e6c7c65b
commit c9bd6fa9fc
16 changed files with 273 additions and 197 deletions

View File

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

View File

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

View File

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

View File

@ -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:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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] = '_';
return result;
free(rurl);
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++) {
/* 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_normalize(argv[i]);
if (s)
printf("<== '%s'\n", 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;
}

View File

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