mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-26 14:07:05 +03:00
dfdf69fc91
Fix plugin memory leaks. svn path=/import/netsurf/; revision=177
284 lines
9.5 KiB
C
284 lines
9.5 KiB
C
/**
|
|
* $Id: plugin.c,v 1.9 2003/06/07 22:24:22 jmb Exp $
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "netsurf/content/content.h"
|
|
#include "netsurf/render/html.h"
|
|
#include "netsurf/riscos/plugin.h"
|
|
#include "netsurf/utils/log.h"
|
|
#include "netsurf/utils/utils.h"
|
|
|
|
#include "oslib/mimemap.h"
|
|
|
|
char* create_mime_from_ext(char* data);
|
|
char* create_sysvar(char* mime);
|
|
void plugin_fetch(struct plugin_object* po,
|
|
char* alias_sysvar/* vars here */);
|
|
|
|
/**
|
|
* plugin_decode
|
|
* Processes the contents of the plugin_object struct (defined in plugin.h)
|
|
* in order to work out if NetSurf can handle the object.
|
|
* For more information, read
|
|
* http://www.ecs.soton.ac.uk/~jmb202/riscos/acorn/browse-plugins.html
|
|
* as this code is based heavily on that description.
|
|
*/
|
|
void plugin_decode(struct content* content, char* url, struct box* box,
|
|
struct plugin_object* po) {
|
|
|
|
|
|
content_type mime_type;
|
|
bool can_handle = TRUE;
|
|
char* alias_sysvar;
|
|
|
|
|
|
if (po->data != NULL) {
|
|
|
|
if (po->type != NULL) {
|
|
|
|
/* acquire NS mime type from actual mime type */
|
|
mime_type = content_lookup((const char*)po->type);
|
|
}
|
|
else {
|
|
|
|
/* create actual mime type - if we're wrong,
|
|
* it doesn't matter as the HTTP content-type
|
|
* header should override whatever we think.
|
|
* however, checking the header hasn't been
|
|
* implemented yet so it will just b0rk :(
|
|
*/
|
|
po->type = strdup(create_mime_from_ext(po->data));
|
|
|
|
if (po->type != NULL)
|
|
mime_type = content_lookup((const char*)po->type);
|
|
|
|
else {
|
|
|
|
/* failed to create mime type, clean up and exit */
|
|
xfree(po);
|
|
can_handle = FALSE;
|
|
}
|
|
|
|
}
|
|
}
|
|
else {
|
|
|
|
/* no data so try using classid instead */
|
|
|
|
if (po->classid != NULL) {
|
|
|
|
po->data = strdup(po->classid);
|
|
|
|
if (strnicmp(po->data,"clsid:",6) == 0) {
|
|
|
|
/* We can't handle ActiveX objects */
|
|
LOG(("Can't Handle ActiveX"));
|
|
xfree(po);
|
|
can_handle = FALSE;
|
|
}
|
|
else {
|
|
|
|
if (po->codetype != NULL) {
|
|
|
|
/* use codetype instead of type if we can */
|
|
po->type = strdup(po->codetype);
|
|
mime_type = content_lookup(
|
|
(const char*)po->codetype);
|
|
}
|
|
else {
|
|
|
|
/* try ye olde file extension munging */
|
|
po->codetype = strdup(
|
|
create_mime_from_ext(po->data));
|
|
|
|
if (po->codetype != NULL) {
|
|
|
|
/* well, it appeared to work... */
|
|
mime_type = content_lookup(
|
|
(const char*)po->codetype);
|
|
po->type = strdup(
|
|
po->codetype);
|
|
}
|
|
else {
|
|
|
|
/* arse, failed. oh well */
|
|
xfree(po);
|
|
can_handle = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
/* we don't have sufficient data to handle this
|
|
* object :(
|
|
* TODO: start fetch anyway and check header.
|
|
* if we can handle the content, continue
|
|
* fetch and carry on as if the proper HTML
|
|
* was written.
|
|
* if we can't handle the content, stop fetch
|
|
* and clean up.
|
|
*/
|
|
xfree(po);
|
|
can_handle = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
/* so, you think you can handle it do you? */
|
|
if (can_handle == TRUE) {
|
|
|
|
/* We think we can handle this object. Now check that
|
|
* we can.
|
|
* 1) Is it an image? Yes - send to image handler
|
|
* No - continue checking
|
|
* 2) Is a suitable Alias$... System Variable set?
|
|
* Yes - invoke plugin
|
|
* No - we can't handle it. Display alternative HTML
|
|
*/
|
|
|
|
|
|
/* TODO: There must be a better way than this...
|
|
* Perhaps checking if the mime type begins "image/"
|
|
* would be better?
|
|
*/
|
|
if (mime_type == CONTENT_JPEG || mime_type == CONTENT_PNG
|
|
|| mime_type == CONTENT_GIF) {
|
|
|
|
/* OK, we have an image. Let's make the image handler
|
|
* deal with it.
|
|
*/
|
|
xfree(po);
|
|
LOG(("sending data to image handler"));
|
|
html_fetch_image(content, url, box);
|
|
return;
|
|
}
|
|
else { /* not an image; is sys var set? */
|
|
|
|
/* Create Alias variable */
|
|
alias_sysvar = create_sysvar(po->type);
|
|
if (alias_sysvar == NULL) {
|
|
|
|
/* oh dear, you can't handle it */
|
|
xfree(po);
|
|
xfree(alias_sysvar);
|
|
can_handle = FALSE;
|
|
}
|
|
else {
|
|
|
|
/* Right, we have a variable.
|
|
* Does it actually exist?
|
|
*/
|
|
int used;
|
|
xos_read_var_val_size(
|
|
(const char*)alias_sysvar,
|
|
0, os_VARTYPE_STRING,
|
|
&used, 0, os_VARTYPE_STRING);
|
|
|
|
if (used == 0) {
|
|
|
|
/* no, doesn't exist */
|
|
xfree(po);
|
|
xfree(alias_sysvar);
|
|
can_handle = FALSE;
|
|
}
|
|
else {
|
|
/* yes, it exists */
|
|
LOG(("%s exists", alias_sysvar));
|
|
plugin_fetch(po, alias_sysvar/* insert vars here */);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (can_handle == FALSE) {
|
|
|
|
/* Get alternative HTML as we can't handle the object */
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* create_mime_from_ext
|
|
* attempts to create a mime type from the filename extension.
|
|
* returns NULL if it fails.
|
|
*/
|
|
|
|
char* create_mime_from_ext(char* data){
|
|
|
|
char* ret;
|
|
os_error *e;
|
|
|
|
LOG(("Creating Mime Type from File Extension"));
|
|
|
|
ret = xcalloc(90, sizeof(char));
|
|
ret = strrchr(data, '.');
|
|
LOG(("Extension = %s", ret));
|
|
|
|
/* Let's make the mime map module do the work for us */
|
|
e = xmimemaptranslate_extension_to_mime_type((const char*)ret,
|
|
ret);
|
|
LOG(("Mime Type = %s", ret));
|
|
|
|
if (e != NULL) ret = NULL;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* create_sysvar
|
|
* attempts to create a system variable of the form Alias$@PlugInType_XXX
|
|
* where XXX is the filetype.
|
|
* returns NULL if unsuccessful.
|
|
*/
|
|
|
|
char* create_sysvar(char* mime) {
|
|
|
|
char* ret;
|
|
char* ft;
|
|
unsigned int* fv;
|
|
os_error *e;
|
|
|
|
LOG(("Creating System Variable from Mime Type"));
|
|
|
|
ret = xcalloc(22, sizeof(char));
|
|
ft = xcalloc(10, sizeof(char));
|
|
strcpy(ret, "Alias$@PlugInType_");
|
|
|
|
LOG(("Mime Type: %s", mime));
|
|
|
|
e = xmimemaptranslate_mime_type_to_filetype((const char*)mime,
|
|
(unsigned int*)&fv);
|
|
if (e != NULL) ret = NULL;
|
|
|
|
else {
|
|
|
|
sprintf(ft, "%x", (int)fv);
|
|
strcat(ret, ft);
|
|
LOG(("Alias Var: %s", ret));
|
|
}
|
|
|
|
xfree(ft);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* plugin_fetch
|
|
* attempts to negotiate with the plugin.
|
|
* also fetches the object for the plugin to handle.
|
|
*/
|
|
void plugin_fetch (struct plugin_object* po,
|
|
char* alias_sysvar/* insert vars here */) {
|
|
|
|
LOG(("Entering plugin_fetch"));
|
|
xfree(po);
|
|
xfree(alias_sysvar);
|
|
return;
|
|
}
|