1
0
mirror of https://github.com/rkd77/elinks.git synced 2025-02-02 15:09:23 -05:00

[quickjs] Check whether node is "active" before returning it

Deleted nodes by libdom are removed from map and next request for such
nodes in getOpaque will return NULL.
This commit is contained in:
Witold Filipczyk 2024-06-20 18:21:31 +02:00
parent acb33d3399
commit e8afed7c5c
5 changed files with 76 additions and 3 deletions

View File

@ -18,9 +18,60 @@
#include "document/document.h"
#include "document/libdom/corestrings.h"
#include "document/libdom/doc.h"
#ifdef CONFIG_QUICKJS
#include "ecmascript/quickjs/mapa.h"
#endif
#include "intl/charsets.h"
#include "util/string.h"
void
js_html_document_user_data_handler(dom_node_operation operation,
dom_string *key, void *data,
struct dom_node *src,
struct dom_node *dst)
{
if (dom_string_isequal(corestring_dom___ns_key_html_content_data,
key) == false) {
return;
}
switch (operation) {
case DOM_NODE_CLONED:
//fprintf(stderr, "CLONED: data=%p src=%p dst=%p\n", data, src, dst);
//NSLOG(netsurf, INFO, "Cloned");
break;
case DOM_NODE_RENAMED:
//fprintf(stderr, "RENAMED: data=%p src=%p dst=%p\n", data, src, dst);
//NSLOG(netsurf, INFO, "Renamed");
break;
case DOM_NODE_IMPORTED:
//fprintf(stderr, "IMPORTED: data=%p src=%p dst=%p\n", data, src, dst);
//NSLOG(netsurf, INFO, "imported");
break;
case DOM_NODE_ADOPTED:
//fprintf(stderr, "ADOPTED: data=%p src=%p dst=%p\n", data, src, dst);
//NSLOG(netsurf, INFO, "Adopted");
break;
case DOM_NODE_DELETED:
#ifdef CONFIG_QUICKJS
if (map_privates) {
attr_erase_from_map(map_privates, data);
}
if (map_elements) {
attr_erase_from_map(map_elements, data);
}
#endif
//fprintf(stderr, "DELETED: data=%p src=%p dst=%p\n", data, src, dst);
/* This is the only path I expect */
break;
default:
//NSLOG(netsurf, INFO, "User data operation not handled.");
//assert(0);
}
}
void *
document_parse_text(const char *charset, char *data, size_t length)
{
@ -66,6 +117,7 @@ document_parse_text(const char *charset, char *data, size_t length)
return doc;
}
void *
document_parse(struct document *document, struct string *source)
{

View File

@ -21,6 +21,8 @@ unicode_val_T convert_dom_string_to_keycode(dom_string *dom_key);
void keybstrings_init(void);
void keybstrings_fini(void);
void js_html_document_user_data_handler(dom_node_operation operation, dom_string *key, void *data, struct dom_node *src, struct dom_node *dst);
#ifdef __cplusplus
}
#endif

View File

@ -110,7 +110,9 @@ quickjs_done(struct module *xxx)
attr_delete_map_rev(map_rev_collections);
attr_delete_map(map_doctypes);
attr_delete_map(map_elements);
map_elements = NULL;
attr_delete_map_void(map_privates);
map_privates = NULL;
attr_delete_map(map_form);
attr_delete_map_rev(map_form_rev);
attr_delete_map(map_forms);

View File

@ -74,6 +74,12 @@ js_getopaque(JSValueConst obj, JSClassID class_id)
if (!res) {
return NULL;
}
void *v = attr_find_in_map_void(map_privates, res->node);
if (!v) {
return NULL;
}
return res->node;
}
@ -2591,10 +2597,15 @@ js_element_appendChild(JSContext *ctx, JSValueConst this_val, int argc, JSValueC
}
if (!el) {
return JS_NULL;
return JS_EXCEPTION;
}
dom_node_ref(el);
dom_node *el2 = (dom_node *)(js_getopaque(argv[0], js_element_class_id));
if (!el2) {
dom_node_unref(el);
return JS_EXCEPTION;
}
exc = dom_node_append_child(el, el2, &res);
if (exc == DOM_NO_ERR && res) {
@ -2605,7 +2616,7 @@ js_element_appendChild(JSContext *ctx, JSValueConst this_val, int argc, JSValueC
}
dom_node_unref(el);
return JS_NULL;
return JS_EXCEPTION;
}
/* @element_funcs{"blur"} */
@ -3824,6 +3835,12 @@ getElement(JSContext *ctx, void *node)
attr_save_in_map(map_elements, node, element_obj);
attr_save_in_map_void(map_privates, node, el_private);
void *old_node_data = NULL;
dom_node_set_user_data(node,
corestring_dom___ns_key_html_content_data,
(void *)node, js_html_document_user_data_handler,
(void *) &old_node_data);
JSValue rr = JS_DupValue(ctx, element_obj);
el_private->thisval = rr;
RETURN_JS(rr);

View File

@ -311,7 +311,7 @@ attr_erase_from_map(void *m, void *node)
if (item) {
mem_free_set(&item->key, NULL);
mem_free_set(&item->value, NULL);
//mem_free_set(&item->value, NULL);
del_hash_item(hash, item);
}
mem_free(key);