1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Change the pre-format event so that hooks are given the cache entry

instead of the URI, content, and length of the entry. Change the hooks
to use add_fragment. This should fix the memory leakage when multiple
hooks change the same document, closing bug 703.
This commit is contained in:
Miciah Dashiel Butler Masters 2005-12-17 06:32:08 +00:00 committed by Miciah Dashiel Butler Masters
parent 35aa8119e3
commit fdacffd113
8 changed files with 79 additions and 78 deletions

View File

@ -217,17 +217,16 @@ Triggered When:
Arguments:
unsigned char **html, int *html_len, struct session *ses, unsigned char *url
struct cache_entry *cached
Description:
Makes it possible to fix up bad HTML code, remove tags etc. The HTML source
is changed by making @html point to the new source. If @html is changed the
event propagation should be ended and @html_len should be updated to the new
length of the document content.
Possible values for @html includes:
- new document content in a dynamically allocated string; or
- NULL to keep the content unchanged.
Makes it possible to fix up bad HTML code, remove tags etc. The parameter
cached is guaranteed to have a single fragment. The HTML source is changed
by replacing this fragment:
add_fragment(cached, 0, new_string, new_len);
normalize_cache_entry(cached, new_len);
-------------------------------------------------------------------------------
Name: quit

View File

@ -8,7 +8,9 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/guile/hooks.h"
#include "session/session.h"
#include "util/string.h"
@ -116,27 +118,29 @@ script_hook_follow_url(va_list ap, void *data)
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
int len;
SCM proc;
SCM x;
evhook_use_params(html && html_len && ses && url);
evhook_use_params(ses && cached);
if (*html == NULL || *html_len == 0) return EVENT_HOOK_STATUS_NEXT;
if (!cached->length || !*fragment->data) return EVENT_HOOK_STATUS_NEXT;
proc = get_guile_hook("%pre-format-html-hook");
if (SCM_FALSEP(proc)) return EVENT_HOOK_STATUS_NEXT;
x = scm_call_2(SCM_VARIABLE_REF(proc), scm_makfrom0str(url),
scm_mem2string(*html, *html_len));
scm_mem2string(fragment->data, fragment->length));
if (!SCM_STRINGP(x)) return EVENT_HOOK_STATUS_NEXT;
*html_len = SCM_STRING_LENGTH(x);
*html = memacpy(SCM_STRING_UCHARS(x), *html_len);
len = SCM_STRING_LENGTH(x);
add_fragment(cached, 0, SCM_STRING_UCHARS(x), len);
normalize_cache_entry(cached, len);
return EVENT_HOOK_STATUS_NEXT;
}

View File

@ -6,6 +6,7 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/lua/core.h"
@ -114,13 +115,13 @@ static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
lua_State *L = lua_state;
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
int err;
if (*html == NULL || *html_len == 0) return EVENT_HOOK_STATUS_NEXT;
if (!cached->length || !*fragment->data) return EVENT_HOOK_STATUS_NEXT;
lua_getglobal(L, "pre_format_html_hook");
if (lua_isnil(L, -1)) {
@ -130,7 +131,7 @@ script_hook_pre_format_html(va_list ap, void *data)
}
lua_pushstring(L, url);
lua_pushlstring(L, *html, *html_len);
lua_pushlstring(L, fragment->data, fragment->length);
if (prepare_lua(ses)) return EVENT_HOOK_STATUS_NEXT;
@ -139,8 +140,10 @@ script_hook_pre_format_html(va_list ap, void *data)
if (err) return EVENT_HOOK_STATUS_NEXT;
if (lua_isstring(L, -1)) {
*html_len = lua_strlen(L, -1);
*html = memacpy((unsigned char *) lua_tostring(L, -1), *html_len);
int len = lua_strlen(L, -1);
add_fragment(cached, 0, (unsigned char *) lua_tostring(L, -1), len);
normalize_cache_entry(cached, len);
} else if (!lua_isnil(L, -1)) {
alert_lua_error("pre_format_html_hook must return a string or nil");
}

View File

@ -6,6 +6,7 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/perl/core.h"
@ -118,8 +119,8 @@ script_hook_follow_url(va_list ap, void *data)
}
static inline void
do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
int *html_len)
do_script_hook_pre_format_html(unsigned char *url, struct cache_entry *cached,
struct fragment *fragment)
{
int count;
dSP; /* Keep in variables declaration block. */
@ -129,7 +130,7 @@ do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
PUSHMARK(SP);
my_XPUSHs(url, strlen(url));
my_XPUSHs(*html, *html_len);
my_XPUSHs(fragment->data, fragment->length);
PUTBACK;
count = call_pv("pre_format_html_hook", G_EVAL | G_SCALAR);
@ -140,8 +141,10 @@ do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
unsigned char *new_html = POPpx;
if (new_html) {
*html_len = n_a;
*html = memacpy(new_html, *html_len);
int len = n_a;
add_fragment(cached, 0, new_html, len);
normalize_cache_entry(cached, len);
}
}
@ -153,13 +156,13 @@ do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
if (my_perl && ses && url && *html && *html_len)
do_script_hook_pre_format_html(url, html, html_len);
if (my_perl && ses && url && cached->length && *fragment->data)
do_script_hook_pre_format_html(url, cached, fragment);
return EVENT_HOOK_STATUS_NEXT;
}

View File

@ -8,6 +8,7 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/python/hooks.h"
@ -100,22 +101,23 @@ script_hook_follow_url(va_list ap, void *data)
}
static void
do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
int *html_len)
do_script_hook_pre_format_html(unsigned char *url, struct cache_entry *cached,
struct fragment *fragment)
{
PyObject *pFunc = PyDict_GetItemString(pDict, "pre_format_html_hook");
if (pFunc && PyCallable_Check(pFunc)) {
PyObject *pValue = PyObject_CallFunction(pFunc, "ss", url, *html);
PyObject *pValue = PyObject_CallFunction(pFunc, "ss", url,
fragment->data);
if (pValue && (pValue != Py_None)) {
const unsigned char *str = PyString_AsString(pValue);
if (str) {
*html_len = PyString_Size(pValue); /* strlen(str); */
*html = memacpy((unsigned char *)str, *html_len);
/* Isn't a memleak here? --witekfl */
if (!*html) *html_len = 0;
int len = PyString_Size(pValue); /* strlen(str); */
add_fragment(cached, 0, (unsigned char *) str, len);
normalize_cache_entry(cached, len);
}
Py_DECREF(pValue);
} else {
@ -130,13 +132,13 @@ do_script_hook_pre_format_html(unsigned char *url, unsigned char **html,
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
if (pDict && ses && url && *html && *html_len)
do_script_hook_pre_format_html(url, html, html_len);
if (pDict && ses && url && cached->length && *fragment->data)
do_script_hook_pre_format_html(url, cached, fragment);
return EVENT_HOOK_STATUS_NEXT;
}

View File

@ -8,6 +8,7 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/ruby/core.h"
@ -144,22 +145,22 @@ script_hook_follow_url(va_list ap, void *data)
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
int error;
VALUE args[2];
VALUE result;
evhook_use_params(url && ses);
evhook_use_params(ses, cached);
if (*html == NULL || *html_len == 0)
if (!cached->length || !*fragment->data)
return EVENT_HOOK_STATUS_NEXT;
args[0] = rb_str_new2(url);
/* FIXME: Use html_len */
args[1] = rb_str_new2(*html);
args[1] = rb_str_new2(fragment->data);
result = erb_protected_method_call("pre_format_html_hook", 2, args, &error);
if (error) {
@ -170,13 +171,11 @@ script_hook_pre_format_html(va_list ap, void *data)
switch (rb_type(result)) {
case T_STRING:
{
unsigned char *new_html;
int len = RSTRING(result)->len;
add_fragment(cached, 0, RSTRING(result)->ptr, len);
normalize_cache_entry(cached, len);
new_html = memacpy(RSTRING(result)->ptr, RSTRING(result)->len);
if (new_html) {
*html_len = RSTRING(result)->len;
*html = new_html;
}
break;
}
case T_NIL:

View File

@ -8,6 +8,7 @@
#include "elinks.h"
#include "cache/cache.h"
#include "main/event.h"
#include "protocol/uri.h"
#include "scripting/see/core.h"
@ -156,21 +157,21 @@ script_hook_follow_url(va_list ap, void *data)
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
unsigned char **html = va_arg(ap, unsigned char **);
int *html_len = va_arg(ap, int *);
struct session *ses = va_arg(ap, struct session *);
unsigned char *url = va_arg(ap, unsigned char *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
struct fragment *fragment = get_cache_fragment(cached);
unsigned char *url = struri(cached->uri);
struct SEE_interpreter *see = &see_interpreter;
struct SEE_value args_[2], *args[2] = { &args_[0], &args_[1] };
struct SEE_value result;
evhook_use_params(url && ses);
evhook_use_params(ses, cached);
if (*html == NULL || *html_len == 0)
if (!cached->length || !*fragment->data)
return EVENT_HOOK_STATUS_NEXT;
SEE_SET_STRING(args[0], SEE_string_sprintf(see, "%s", url));
SEE_SET_STRING(args[1], SEE_string_sprintf(see, "%s", *html));
SEE_SET_STRING(args[1], SEE_string_sprintf(see, "%s", fragment->data));
if (!call_see_hook(see, ses, "pre_format_html", args, sizeof_array(args), &result))
return EVENT_HOOK_STATUS_NEXT;
@ -181,8 +182,8 @@ script_hook_pre_format_html(va_list ap, void *data)
struct string new_html;
if (convert_see_string(&new_html, result.u.string)) {
mem_free_set(html, new_html.source);
*html_len = new_html.length;
add_fragment(cached, 0, new_html.source, new_html.length);
normalize_cache_entry(cached, new_html.length);
}
break;
}

View File

@ -500,8 +500,6 @@ static void
maybe_pre_format_html(struct cache_entry *cached, struct session *ses)
{
struct fragment *fragment;
unsigned char *src;
int len;
static int pre_format_html_event = EVENT_NONE;
if (!cached || cached->preformatted)
@ -513,19 +511,11 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses)
/* We cannot do anything if the data are fragmented. */
if (!list_is_singleton(cached->frag)) return;
src = fragment->data;
len = fragment->length;
set_event_id(pre_format_html_event, "pre-format-html");
trigger_event(pre_format_html_event, &src, &len, ses, struri(cached->uri));
trigger_event(pre_format_html_event, ses, cached);
if (src && src != fragment->data) {
add_fragment(cached, 0, src, len);
normalize_cache_entry(cached, len);
mem_free(src);
}
/* XXX: Keep after normalize_cache_entry()! */
/* XXX: Keep this after the trigger_event, because hooks might call
* normalize_cache_entry()! */
cached->preformatted = 1;
}
#endif