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 if (doc_view->session
&& doc_view->session->reloadlevel > CACHE_MODE_NORMAL) && doc_view->session->reloadlevel > CACHE_MODE_NORMAL)
while (vs->form_info_len) for (; vs->form_info_len > 0; vs->form_info_len--)
mem_free_if(vs->form_info[--vs->form_info_len].value); done_form_state(&vs->form_info[vs->form_info_len - 1]);
shrink_memory(0); shrink_memory(0);

View File

@ -214,6 +214,23 @@ ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
return result; 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 void
ecmascript_reset_state(struct view_state *vs) ecmascript_reset_state(struct view_state *vs)
@ -221,14 +238,19 @@ ecmascript_reset_state(struct view_state *vs)
struct form_view *fv; struct form_view *fv;
int i; 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; vs->ecmascript_fragile = 0;
if (vs->ecmascript) if (vs->ecmascript)
ecmascript_put_interpreter(vs->ecmascript); ecmascript_put_interpreter(vs->ecmascript);
foreach (fv, vs->forms) foreach (fv, vs->forms)
fv->ecmascript_obj = NULL; 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); vs->ecmascript = ecmascript_get_interpreter(vs);
if (!vs->ecmascript) if (!vs->ecmascript)

View File

@ -8,6 +8,7 @@
#include "main/module.h" #include "main/module.h"
#include "util/time.h" #include "util/time.h"
struct form_state;
struct string; struct string;
struct terminal; struct terminal;
struct uri; struct uri;
@ -70,6 +71,9 @@ void ecmascript_free_urls(struct module *module);
struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs); struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs);
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter); 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_reset_state(struct view_state *vs);
void ecmascript_eval(struct ecmascript_interpreter *interpreter, struct string *code, struct string *ret); 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_get_interpreter(struct ecmascript_interpreter *interpreter);
void see_put_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); 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); unsigned char *see_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
int see_eval_boolback(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_get_interpreter(struct ecmascript_interpreter *interpreter);
void spidermonkey_put_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); 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); unsigned char *spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
int spidermonkey_eval_boolback(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/forms.h"
#include "document/html/parser.h" #include "document/html/parser.h"
#include "document/view.h" #include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "intl/gettext/libintl.h" #include "intl/gettext/libintl.h"
#include "formhist/formhist.h" #include "formhist/formhist.h"
#include "mime/mime.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) { if (n >= vs->form_info_len) {
int nn = n + 1; 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); fs = mem_align_alloc(&vs->form_info, vs->form_info_len, nn, 0);
if (!fs) return NULL; if (!fs) return NULL;
vs->form_info = fs; vs->form_info = fs;
vs->form_info_len = nn; 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]; fs = &vs->form_info[n];
@ -315,6 +335,17 @@ find_form_by_form_view(struct document *document, struct form_view *fv)
return NULL; 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 int
get_current_state(struct session *ses) 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_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); 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); 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); 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 void
destroy_vs(struct view_state *vs, int blast_ecmascript) destroy_vs(struct view_state *vs, int blast_ecmascript)
{ {
int i; /* form_state contains a pointer to form_view, so it's safest
* to delete the form_state first. */
for (i = 0; i < vs->form_info_len; i++) for (; vs->form_info_len > 0; vs->form_info_len--)
mem_free_if(vs->form_info[i].value); 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); if (vs->uri) done_uri(vs->uri);
mem_free_if(vs->form_info);
free_list(vs->forms); free_list(vs->forms);
#ifdef CONFIG_ECMASCRIPT #ifdef CONFIG_ECMASCRIPT
if (blast_ecmascript && vs->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 *srcfs = &src->form_info[i];
struct form_state *dstfs = &dst->form_info[i]; struct form_state *dstfs = &dst->form_info[i];
#ifdef CONFIG_ECMASCRIPT
dstfs->ecmascript_obj = NULL;
#endif
if (srcfs->value) if (srcfs->value)
dstfs->value = stracpy(srcfs->value); dstfs->value = stracpy(srcfs->value);
/* XXX: This makes it O(nm). */ /* XXX: This makes it O(nm). */