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

View File

@ -8,7 +8,9 @@
#include "elinks.h" #include "elinks.h"
#include "cache/cache.h"
#include "main/event.h" #include "main/event.h"
#include "protocol/uri.h"
#include "scripting/guile/hooks.h" #include "scripting/guile/hooks.h"
#include "session/session.h" #include "session/session.h"
#include "util/string.h" #include "util/string.h"
@ -116,27 +118,29 @@ script_hook_follow_url(va_list ap, void *data)
static enum evhook_status static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data) 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 *); 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 proc;
SCM x; 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"); proc = get_guile_hook("%pre-format-html-hook");
if (SCM_FALSEP(proc)) return EVENT_HOOK_STATUS_NEXT; if (SCM_FALSEP(proc)) return EVENT_HOOK_STATUS_NEXT;
x = scm_call_2(SCM_VARIABLE_REF(proc), scm_makfrom0str(url), 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; if (!SCM_STRINGP(x)) return EVENT_HOOK_STATUS_NEXT;
*html_len = SCM_STRING_LENGTH(x); len = SCM_STRING_LENGTH(x);
*html = memacpy(SCM_STRING_UCHARS(x), *html_len); add_fragment(cached, 0, SCM_STRING_UCHARS(x), len);
normalize_cache_entry(cached, len);
return EVENT_HOOK_STATUS_NEXT; return EVENT_HOOK_STATUS_NEXT;
} }

View File

@ -6,6 +6,7 @@
#include "elinks.h" #include "elinks.h"
#include "cache/cache.h"
#include "main/event.h" #include "main/event.h"
#include "protocol/uri.h" #include "protocol/uri.h"
#include "scripting/lua/core.h" #include "scripting/lua/core.h"
@ -114,13 +115,13 @@ static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data) script_hook_pre_format_html(va_list ap, void *data)
{ {
lua_State *L = lua_state; 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 *); 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; 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"); lua_getglobal(L, "pre_format_html_hook");
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
@ -130,7 +131,7 @@ script_hook_pre_format_html(va_list ap, void *data)
} }
lua_pushstring(L, url); 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; 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 (err) return EVENT_HOOK_STATUS_NEXT;
if (lua_isstring(L, -1)) { if (lua_isstring(L, -1)) {
*html_len = lua_strlen(L, -1); int len = lua_strlen(L, -1);
*html = memacpy((unsigned char *) lua_tostring(L, -1), *html_len);
add_fragment(cached, 0, (unsigned char *) lua_tostring(L, -1), len);
normalize_cache_entry(cached, len);
} else if (!lua_isnil(L, -1)) { } else if (!lua_isnil(L, -1)) {
alert_lua_error("pre_format_html_hook must return a string or nil"); alert_lua_error("pre_format_html_hook must return a string or nil");
} }

View File

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

View File

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

View File

@ -8,6 +8,7 @@
#include "elinks.h" #include "elinks.h"
#include "cache/cache.h"
#include "main/event.h" #include "main/event.h"
#include "protocol/uri.h" #include "protocol/uri.h"
#include "scripting/ruby/core.h" #include "scripting/ruby/core.h"
@ -144,22 +145,22 @@ script_hook_follow_url(va_list ap, void *data)
static enum evhook_status static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data) 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 *); 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; int error;
VALUE args[2]; VALUE args[2];
VALUE result; 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; return EVENT_HOOK_STATUS_NEXT;
args[0] = rb_str_new2(url); args[0] = rb_str_new2(url);
/* FIXME: Use html_len */ /* 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); result = erb_protected_method_call("pre_format_html_hook", 2, args, &error);
if (error) { if (error) {
@ -170,13 +171,11 @@ script_hook_pre_format_html(va_list ap, void *data)
switch (rb_type(result)) { switch (rb_type(result)) {
case T_STRING: 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; break;
} }
case T_NIL: case T_NIL:

View File

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

View File

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