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:
parent
35aa8119e3
commit
fdacffd113
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user