[project @ 2004-05-13 14:39:43 by bursa]

Fix URL protocol termination bug (reported by Fred Bambrough). Change from xcalloc to malloc and add error handling.

svn path=/import/netsurf/; revision=859
This commit is contained in:
James Bursa 2004-05-13 14:39:43 +00:00
parent 59d25c3a02
commit 837d60cc37
4 changed files with 155 additions and 140 deletions

View File

@ -60,7 +60,7 @@ void gui_gadget_combo(struct browser_window* bw, struct form_control* g, unsigne
void gui_window_place_caret(gui_window *g, int x, int y, int height);
void gui_launch_url(char *url);
void gui_launch_url(const char *url);
void warn_user(const char *warning, const char *detail);

View File

@ -587,15 +587,6 @@ void ro_gui_null_reason_code(void)
}
}
void gui_launch_url(char *url) {
/* Try ant broadcast first */
if (!ro_url_broadcast(url))
/* then uri */
if (!ro_uri_launch(url))
/* then ant load */
ro_url_load(url);
}
/**
* Handle Redraw_Window_Request events.
@ -782,7 +773,7 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
case message_HELP_REQUEST:
ro_gui_interactive_help_request(message);
break;
case message_DATA_SAVE:
ro_msg_datasave(message);
break;
@ -1295,6 +1286,17 @@ void ro_gui_view_source(struct content *content)
}
/**
* Broadcast an URL that we can't handle.
*/
void gui_launch_url(const char *url)
{
/* Try ant broadcast first */
ro_url_broadcast(url);
}
static char warn_buffer[300];
/**

View File

@ -3,9 +3,17 @@
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
* Shamelessly hacked from Rob Jackson's URI handler (see uri.c)
* Copyright 2003 Rob Jackson <jacko@xms.ms>
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
*/
/** \file
* ANT URL launching protocol (implementation).
*
* See http://www.vigay.com/inet/inet_url.html
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "oslib/inetsuite.h"
@ -13,169 +21,170 @@
#include "netsurf/utils/config.h"
#include "netsurf/content/fetch.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/riscos/theme.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/uri.h"
#include "netsurf/riscos/url_protocol.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
/* Define this to allow posting of data to an URL */
#undef ALLOW_POST
static char *read_string_value(os_string_value string, char *msg);
/**
* Handle a Message_InetSuiteOpenURL.
*/
void ro_url_message_received(wimp_message* message)
void ro_url_message_received(wimp_message *message)
{
char* uri_requested = NULL;
#ifdef ALLOW_POST
char* filename = NULL, *mimetype = NULL;
bool post=false;
struct browser_window* bw;
#endif
inetsuite_message_open_url *url_message = (inetsuite_message_open_url*)&message->data;
char *url;
int i;
inetsuite_message_open_url *url_message =
(inetsuite_message_open_url*) &message->data;
os_error *error;
/* If the url_message->indirect.tag is non-zero,
* then the message data is contained within the message block.
*/
if (url_message->indirect.tag != 0) {
uri_requested = xstrdup(url_message->url);
LOG(("%s", url_message->url));
}
else {
/* Get URL */
if (read_string_value(url_message->indirect.url,
(char*)url_message) != 0) {
uri_requested = xstrdup(read_string_value(url_message->indirect.url,
(char*)url_message));
}
else {
return;
}
LOG(("%s", uri_requested));
/* If the url_message->indirect.tag is non-zero,
* then the message data is contained within the message block.
*/
if (url_message->indirect.tag != 0) {
url = strndup(url_message->url, 236);
if (!url) {
warn_user("NoMemory", 0);
return;
}
/* terminate at first control character */
for (i = 0; !iscntrl(url[i]); i++)
;
url[i] = 0;
#ifdef ALLOW_POST
/* Get filename */
if (read_string_value(url_message->indirect.body_file,
(char*)url_message) != 0) {
filename = xstrdup(read_string_value(url_message->indirect.body_file,
(char*)url_message));
}
/* We ignore the target window. Just open a new window. */
/* Get mimetype */
if (url_message->indirect.flags & inetsuite_USE_MIME_TYPE) {
if (read_string_value(url_message->indirect.body_mimetype,
(char*)url_message) != 0) {
mimetype = xstrdup(read_string_value(url_message->indirect.body_mimetype,
(char*)url_message));
}
else {
mimetype = xstrdup("application/x-www-form-urlencoded");
}
}
else {
mimetype = xstrdup("application/x-www-form-urlencoded");
}
} else {
if (!url_message->indirect.url.offset) {
LOG(("no URL in message"));
return;
}
if (28 < message->size &&
url_message->indirect.body_file.offset) {
LOG(("POST for URL message not implemented"));
return;
}
if (url_message->indirect.url.offset < 28 ||
236 <= url_message->indirect.url.offset) {
LOG(("external pointers in URL message unimplemented"));
/* these messages have never been seen in the wild,
* and there is the problem of invalid addresses which
* would cause an abort */
return;
}
/* Indicate a post request */
if (filename && message->size > 28)
post = true;
#endif
}
url = strndup((char *) url_message +
url_message->indirect.url.offset,
236 - url_message->indirect.url.offset);
if (!url) {
warn_user("NoMemory", 0);
return;
}
for (i = 0; !iscntrl(url[i]); i++)
;
url[i] = 0;
}
if (!fetch_can_fetch(uri_requested)) {
#ifdef ALLOW_POST
xfree(filename);
xfree(mimetype);
#endif
xfree(uri_requested);
return;
}
if (!fetch_can_fetch(url)) {
free(url);
return;
}
/* send ack */
message->your_ref = message->my_ref;
xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, message,
message->sender);
/* send ack */
message->your_ref = message->my_ref;
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, message,
message->sender);
if (error) {
LOG(("xwimp_send_message: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
/* create new browser window */
browser_window_create(uri_requested, NULL);
/* create new browser window */
browser_window_create(url, 0);
#if 0
if (post) {
/* TODO - create urlencoded data from file contents.
* Delete the file when finished with it.
*/
browser_window_open_location_historical(bw, uri_requested, /*data*/0, 0);
}
#endif
#ifdef ALLOW_POST
xfree(filename);
xfree(mimetype);
#endif
xfree(uri_requested);
return;
free(url);
}
char *read_string_value(os_string_value string, char *msg) {
if(string.offset == 0) return NULL;
if(string.offset > 256) return string.pointer;
return &msg[string.offset];
}
bool ro_url_broadcast(char *url) {
/**
* Broadcast an ANT URL message.
*/
void ro_url_broadcast(const char *url)
{
inetsuite_full_message_open_url_direct message;
os_error *e;
int len = ((strlen(url)+1)>235) ? 235 : strlen(url)+1;
os_error *error;
int len = strlen(url) + 1;
if (236 < len)
len = 236;
message.size = ((20+len+3) & ~3);
message.your_ref = 0;
message.action = message_INET_SUITE_OPEN_URL;
*message.url = 0;
strncat(message.url, url, 235);
message.url[len-1] = 0;
e = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
(wimp_message*)&message, 0);
if (e) {
return false;
strncpy(message.url, url, 235);
message.url[235] = 0;
error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
(wimp_message *) &message, 0);
if (error) {
LOG(("xwimp_send_message: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
return true;
}
bool ro_url_load(char *url) {
char url_buf[512];
/**
* Launch a program to handle an URL, using the ANT protocol
* Alias$URLOpen_ system.
*/
void ro_url_load(const char *url)
{
char *command;
char *colon;
os_error *e;
os_error *error;
colon = strchr(url, ':');
if (!colon) return false;
strcpy(url_buf, "Alias$URLOpen_");
strncat(url_buf, url, colon-url);
if (!getenv(url_buf)) return false;
strcat(url_buf, " ");
strncat(url_buf, url, 512-strlen(url_buf)-1);
e = xwimp_start_task(url_buf+5, 0);
if (e) {
return false;
if (!colon) {
LOG(("invalid url '%s'", url));
return;
}
return true;
command = malloc(40 + (colon - url) + strlen(url));
if (!command) {
warn_user("NoMemory", 0);
return;
}
sprintf(command, "Alias$URLOpen_%.*s", colon - url, url);
if (!getenv(command)) {
free(command);
return;
}
sprintf(command, "URLOpen_%.*s %s", colon - url, url, url);
error = xwimp_start_task(command, 0);
if (error) {
LOG(("xwimp_start_task: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
free(command);
}
void ro_url_bounce(wimp_message *message) {
inetsuite_message_open_url *url_message = (inetsuite_message_open_url*)&message->data;
/**
* Handle a bounced Message_InetSuiteOpenURL.
*/
void ro_url_bounce(wimp_message *message)
{
inetsuite_message_open_url *url_message =
(inetsuite_message_open_url*) &message->data;
/* ant broadcast bounced -> try uri broadcast / load */
ro_uri_launch(url_message->url);

View File

@ -5,14 +5,18 @@
* Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
*/
/** \file
* ANT URL launching protocol (interface).
*/
#ifndef _NETSURF_RISCOS_URL_H_
#define _NETSURF_RISCOS_URL_H_
#include "oslib/wimp.h"
void ro_url_message_received(wimp_message *message);
bool ro_url_broadcast(char *url);
bool ro_url_load(char *url);
void ro_url_broadcast(const char *url);
void ro_url_load(const char *url);
void ro_url_bounce(wimp_message *message);
#endif