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