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

952, 954: Add ecmascript_{detach,moved}_form_state stubs

Anything that frees or reallocates struct form_state must now call the
new functions ecmascript_detach_form_state or ecmascript_moved_form_state.
These functions should then clear out any dangling pointers, but that has
not yet been implemented.
This commit is contained in:
Kalle Olavi Niemitalo 2008-07-18 19:16:34 +03:00 committed by Kalle Olavi Niemitalo
parent 8f2f9e7265
commit bbadb99dd1
8 changed files with 77 additions and 9 deletions

View File

@ -337,8 +337,8 @@ render_document(struct view_state *vs, struct document_view *doc_view,
if (doc_view->session
&& doc_view->session->reloadlevel > CACHE_MODE_NORMAL)
while (vs->form_info_len)
mem_free_if(vs->form_info[--vs->form_info_len].value);
for (; vs->form_info_len > 0; vs->form_info_len--)
done_form_state(&vs->form_info[vs->form_info_len - 1]);
shrink_memory(0);

View File

@ -214,6 +214,23 @@ ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
return result;
}
void ecmascript_detach_form_state(struct form_state *fs)
{
#ifdef CONFIG_ECMASCRIPT_SEE
see_detach_form_state(fs);
#else
spidermonkey_detach_form_state(fs);
#endif
}
void ecmascript_moved_form_state(struct form_state *fs)
{
#ifdef CONFIG_ECMASCRIPT_SEE
see_moved_form_state(fs);
#else
spidermonkey_moved_form_state(fs);
#endif
}
void
ecmascript_reset_state(struct view_state *vs)
@ -221,14 +238,19 @@ ecmascript_reset_state(struct view_state *vs)
struct form_view *fv;
int i;
/* Normally, if vs->ecmascript == NULL, the associated
* ecmascript_obj pointers are also NULL. However, they might
* be non-NULL if the ECMAScript objects have been lazily
* created because of scripts running in sibling HTML frames. */
for (i = 0; i < vs->form_info_len; i++)
ecmascript_detach_form_state(&vs->form_info[i]);
vs->ecmascript_fragile = 0;
if (vs->ecmascript)
ecmascript_put_interpreter(vs->ecmascript);
foreach (fv, vs->forms)
fv->ecmascript_obj = NULL;
for (i = 0; i < vs->form_info_len; i++)
vs->form_info[i].ecmascript_obj = NULL;
vs->ecmascript = ecmascript_get_interpreter(vs);
if (!vs->ecmascript)

View File

@ -8,6 +8,7 @@
#include "main/module.h"
#include "util/time.h"
struct form_state;
struct string;
struct terminal;
struct uri;
@ -70,6 +71,9 @@ void ecmascript_free_urls(struct module *module);
struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs);
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter);
void ecmascript_detach_form_state(struct form_state *fs);
void ecmascript_moved_form_state(struct form_state *fs);
void ecmascript_reset_state(struct view_state *vs);
void ecmascript_eval(struct ecmascript_interpreter *interpreter, struct string *code, struct string *ret);

View File

@ -7,6 +7,9 @@ struct string;
void *see_get_interpreter(struct ecmascript_interpreter *interpreter);
void see_put_interpreter(struct ecmascript_interpreter *interpreter);
#define see_detach_form_state(fs) ((fs)->ecmascript_obj = NULL)
#define see_moved_form_state(fs) ((void) (fs))
void see_eval(struct ecmascript_interpreter *interpreter, struct string *code, struct string *ret);
unsigned char *see_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
int see_eval_boolback(struct ecmascript_interpreter *interpreter, struct string *code);

View File

@ -7,6 +7,9 @@ struct string;
void *spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter);
void spidermonkey_put_interpreter(struct ecmascript_interpreter *interpreter);
#define spidermonkey_detach_form_state(fs) ((fs)->ecmascript_obj = NULL)
#define spidermonkey_moved_form_state(fs) ((void) (fs))
void spidermonkey_eval(struct ecmascript_interpreter *interpreter, struct string *code, struct string *ret);
unsigned char *spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
int spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter, struct string *code);

View File

@ -31,6 +31,7 @@
#include "document/forms.h"
#include "document/html/parser.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "intl/gettext/libintl.h"
#include "formhist/formhist.h"
#include "mime/mime.h"
@ -239,11 +240,30 @@ find_form_state(struct document_view *doc_view, struct form_control *fc)
if (n >= vs->form_info_len) {
int nn = n + 1;
#ifdef CONFIG_ECMASCRIPT
const struct form_state *const old_form_info = vs->form_info;
#endif
fs = mem_align_alloc(&vs->form_info, vs->form_info_len, nn, 0);
if (!fs) return NULL;
vs->form_info = fs;
vs->form_info_len = nn;
#ifdef CONFIG_ECMASCRIPT
/* TODO: Standard C does not allow this comparison;
* if the memory to which old_form_info pointed has
* been freed, then the value of the pointer itself is
* indeterminate. Fixing this would require changing
* mem_align_alloc to tell the caller whether it did
* realloc or not. */
if (vs->form_info != old_form_info) {
/* vs->form_info[] was moved to a different address.
* Update all the ECMAScript objects that have
* pointers to its elements. */
for (nn = 0; nn < vs->form_info_len; nn++)
ecmascript_moved_form_state(&vs->form_info[nn]);
}
#endif /* CONFIG_ECMASCRIPT */
}
fs = &vs->form_info[n];
@ -315,6 +335,17 @@ find_form_by_form_view(struct document *document, struct form_view *fv)
return NULL;
}
/** Free any data owned by @a fs, but not the struct form_state
* itself, because that is normally allocated as part of an array.
* @relates form_state */
void
done_form_state(struct form_state *fs)
{
#ifdef CONFIG_ECMASCRIPT
ecmascript_detach_form_state(fs);
#endif
mem_free_if(fs->value);
}
int
get_current_state(struct session *ses)

View File

@ -113,6 +113,8 @@ struct form_view *find_form_view_in_vs(struct view_state *vs, int form_num);
struct form_view *find_form_view(struct document_view *doc_view, struct form *form);
struct form *find_form_by_form_view(struct document *document, struct form_view *fv);
void done_form_state(struct form_state *);
enum frame_event_status field_op(struct session *ses, struct document_view *doc_view, struct link *link, struct term_event *ev);
void draw_form_entry(struct terminal *term, struct document_view *doc_view, struct link *link);

View File

@ -45,13 +45,13 @@ init_vs(struct view_state *vs, struct uri *uri, int plain)
void
destroy_vs(struct view_state *vs, int blast_ecmascript)
{
int i;
for (i = 0; i < vs->form_info_len; i++)
mem_free_if(vs->form_info[i].value);
/* form_state contains a pointer to form_view, so it's safest
* to delete the form_state first. */
for (; vs->form_info_len > 0; vs->form_info_len--)
done_form_state(&vs->form_info[vs->form_info_len - 1]);
mem_free_set(&vs->form_info, NULL);
if (vs->uri) done_uri(vs->uri);
mem_free_if(vs->form_info);
free_list(vs->forms);
#ifdef CONFIG_ECMASCRIPT
if (blast_ecmascript && vs->ecmascript)
@ -114,6 +114,9 @@ copy_vs(struct view_state *dst, struct view_state *src)
struct form_state *srcfs = &src->form_info[i];
struct form_state *dstfs = &dst->form_info[i];
#ifdef CONFIG_ECMASCRIPT
dstfs->ecmascript_obj = NULL;
#endif
if (srcfs->value)
dstfs->value = stracpy(srcfs->value);
/* XXX: This makes it O(nm). */