Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 47 additions & 37 deletions external/njs_xml_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ static njs_int_t njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *prop,

static njs_int_t njs_xml_node_attr_handler(njs_vm_t *vm, xmlNode *current,
njs_str_t *name, njs_value_t *setval, njs_value_t *retval);
static njs_int_t njs_xml_node_tag_remove(njs_vm_t *vm, xmlNode *current,
static njs_int_t njs_xml_node_tag_remove(njs_vm_t *vm, njs_value_t *value,
njs_str_t *name);
static njs_int_t njs_xml_node_tag_handler(njs_vm_t *vm, xmlNode *current,
static njs_int_t njs_xml_node_tag_handler(njs_vm_t *vm, njs_value_t *value,
njs_str_t *name, njs_value_t *setval, njs_value_t *retval);
static njs_int_t njs_xml_node_tags_handler(njs_vm_t *vm, xmlNode *current,
static njs_int_t njs_xml_node_tags_handler(njs_vm_t *vm, njs_value_t *value,
njs_str_t *name, njs_value_t *setval, njs_value_t *retval);

static xmlNode *njs_xml_external_node(njs_vm_t *vm, njs_value_t *value);
Expand All @@ -110,7 +110,7 @@ static const u_char *njs_xml_value_to_c_string(njs_vm_t *vm, njs_value_t *value,
u_char *dst, size_t size);
static njs_int_t njs_xml_encode_special_chars(njs_vm_t *vm, njs_str_t *src,
njs_str_t *out);
static njs_int_t njs_xml_replace_node(njs_vm_t *vm, xmlNode *old,
static njs_int_t njs_xml_replace_node(njs_vm_t *vm, njs_value_t *value,
xmlNode *current);
static void njs_xml_node_cleanup(void *data);
static void njs_xml_doc_cleanup(void *data);
Expand Down Expand Up @@ -706,7 +706,7 @@ njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
name.length -= njs_length("$tag$");
name.start += njs_length("$tag$");

return njs_xml_node_tag_handler(vm, current, &name, setval, retval);
return njs_xml_node_tag_handler(vm, value, &name, setval, retval);
}

if (name.length >= njs_length("$tags$")
Expand All @@ -715,12 +715,11 @@ njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
name.length -= njs_length("$tags$");
name.start += njs_length("$tags$");

return njs_xml_node_tags_handler(vm, current, &name, setval,
retval);
return njs_xml_node_tags_handler(vm, value, &name, setval, retval);
}
}

return njs_xml_node_tag_handler(vm, current, &name, setval, retval);
return njs_xml_node_tag_handler(vm, value, &name, setval, retval);
}


Expand Down Expand Up @@ -770,7 +769,7 @@ njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args,

njs_value_undefined_set(retval);

return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, njs_argument(args, 0), copy);

error:

Expand All @@ -792,8 +791,8 @@ njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
return NJS_DECLINED;
}

return njs_vm_external_create(vm, retval, njs_xml_attr_proto_id,
current->properties, 0);
return njs_vm_external_create(vm, retval, njs_xml_attr_proto_id, current,
0);
}


Expand Down Expand Up @@ -909,7 +908,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args,

njs_value_string_get(vm, selector, &name);

return njs_xml_node_tag_remove(vm, current, &name);
return njs_xml_node_tag_remove(vm, njs_argument(args, 0), &name);
}

/* all. */
Expand All @@ -925,7 +924,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args,
copy->children = NULL;
}

return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, njs_argument(args, 0), copy);
}


Expand Down Expand Up @@ -990,7 +989,7 @@ njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
name.start = NULL;
name.length = 0;

return njs_xml_node_tags_handler(vm, current, &name, setval, retval);
return njs_xml_node_tags_handler(vm, value, &name, setval, retval);
}


Expand Down Expand Up @@ -1051,7 +1050,7 @@ njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused, uint32_t unused1,
njs_value_undefined_set(retval);
}

return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, value, copy);
}


Expand Down Expand Up @@ -1143,11 +1142,12 @@ njs_xml_node_attr_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,


static njs_int_t
njs_xml_node_tag_remove(njs_vm_t *vm, xmlNode *current, njs_str_t *name)
njs_xml_node_tag_remove(njs_vm_t *vm, njs_value_t *value, njs_str_t *name)
{
size_t size;
xmlNode *node, *next, *copy;
njs_int_t ret;
xmlNode *current, *node, *next, *copy;

current = njs_vm_external(vm, njs_xml_node_proto_id, value);

copy = xmlDocCopyNode(current, current->doc, 1);
if (njs_slow_path(copy == NULL)) {
Expand All @@ -1170,23 +1170,22 @@ njs_xml_node_tag_remove(njs_vm_t *vm, xmlNode *current, njs_str_t *name)
continue;
}

ret = njs_xml_replace_node(vm, node, NULL);
if (njs_slow_path(ret != NJS_OK)) {
xmlFreeNode(copy);
return NJS_ERROR;
}
xmlUnlinkNode(node);
xmlFreeNode(node);
}

return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, value, copy);
}


static njs_int_t
njs_xml_node_tag_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,
njs_xml_node_tag_handler(njs_vm_t *vm, njs_value_t *value, njs_str_t *name,
njs_value_t *setval, njs_value_t *retval)
{
size_t size;
xmlNode *node;
xmlNode *current, *node;

current = njs_vm_external(vm, njs_xml_node_proto_id, value);

if (retval != NULL && setval == NULL) {

Expand Down Expand Up @@ -1223,21 +1222,23 @@ njs_xml_node_tag_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,

/* delete. */

return njs_xml_node_tag_remove(vm, current, name);
return njs_xml_node_tag_remove(vm, value, name);
}


static njs_int_t
njs_xml_node_tags_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,
njs_xml_node_tags_handler(njs_vm_t *vm, njs_value_t *value, njs_str_t *name,
njs_value_t *setval, njs_value_t *retval)
{
size_t size;
int64_t i, length;
xmlNode *node, *rnode, *copy;
xmlNode *current, *node, *rnode, *copy;
njs_int_t ret;
njs_value_t *push;
njs_opaque_value_t *start;

current = njs_vm_external(vm, njs_xml_node_proto_id, value);

if (retval != NULL && setval == NULL) {

/* get. */
Expand Down Expand Up @@ -1294,7 +1295,7 @@ njs_xml_node_tags_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,

if (retval == NULL) {
/* delete. */
return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, value, copy);
}

if (!njs_value_is_array(setval)) {
Expand Down Expand Up @@ -1338,7 +1339,7 @@ njs_xml_node_tags_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name,

njs_value_undefined_set(retval);

return njs_xml_replace_node(vm, current, copy);
return njs_xml_replace_node(vm, value, copy);

error:

Expand Down Expand Up @@ -1512,9 +1513,12 @@ njs_xml_encode_special_chars(njs_vm_t *vm, njs_str_t *src, njs_str_t *out)


static njs_int_t
njs_xml_replace_node(njs_vm_t *vm, xmlNode *old, xmlNode *current)
njs_xml_replace_node(njs_vm_t *vm, njs_value_t *value, xmlNode *current)
{
njs_mp_cleanup_t *cln;
xmlNode *old;
njs_mp_cleanup_t *cln;

old = njs_vm_external(vm, njs_xml_node_proto_id, value);

if (current != NULL) {
old = xmlReplaceNode(old, current);
Expand All @@ -1523,6 +1527,8 @@ njs_xml_replace_node(njs_vm_t *vm, xmlNode *old, xmlNode *current)
xmlUnlinkNode(old);
}

njs_value_external_set(value, current);

cln = njs_mp_cleanup_add(njs_vm_memory_pool(vm), 0);
if (njs_slow_path(cln == NULL)) {
njs_vm_memory_error(vm);
Expand Down Expand Up @@ -1846,7 +1852,8 @@ njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
static njs_int_t
njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
{
xmlAttr *node, *current;
xmlAttr *node;
xmlNode *current;
njs_int_t ret;
njs_value_t *push;

Expand All @@ -1861,7 +1868,7 @@ njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
return NJS_ERROR;
}

for (node = current; node != NULL; node = node->next) {
for (node = current->properties; node != NULL; node = node->next) {
if (node->type != XML_ATTRIBUTE_NODE) {
continue;
}
Expand All @@ -1888,7 +1895,8 @@ njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *retval)
{
size_t size;
xmlAttr *node, *current;
xmlAttr *node;
xmlNode *current;
njs_int_t ret;
njs_str_t name;

Expand All @@ -1904,7 +1912,7 @@ njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
return NJS_DECLINED;
}

for (node = current; node != NULL; node = node->next) {
for (node = current->properties; node != NULL; node = node->next) {
if (node->type != XML_ATTRIBUTE_NODE) {
continue;
}
Expand All @@ -1921,6 +1929,8 @@ njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
njs_strlen(node->children->content));
}

njs_value_undefined_set(retval);

return NJS_OK;
}

Expand Down
17 changes: 9 additions & 8 deletions external/qjs_xml_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ typedef struct {


typedef struct {
xmlAttr *attr;
xmlNode *node;
qjs_xml_doc_t *doc;
} qjs_xml_attr_t;

Expand Down Expand Up @@ -93,7 +93,7 @@ static void qjs_xml_node_finalizer(JSRuntime *rt, JSValue val);
static xmlNode *qjs_xml_node(JSContext *cx, JSValueConst val, xmlDoc **doc);

static JSValue qjs_xml_attr_make(JSContext *cx, qjs_xml_doc_t *doc,
xmlAttr *attr);
xmlNode *node);
static int qjs_xml_attr_get_own_property(JSContext *cx,
JSPropertyDescriptor *pdesc, JSValueConst obj, JSAtom prop);
static int qjs_xml_attr_get_own_property_names(JSContext *cx,
Expand Down Expand Up @@ -955,8 +955,7 @@ qjs_xml_node_get_own_property(JSContext *cx, JSPropertyDescriptor *pdesc,
pdesc->flags = JS_PROP_ENUMERABLE;
pdesc->getter = JS_UNDEFINED;
pdesc->setter = JS_UNDEFINED;
pdesc->value = qjs_xml_attr_make(cx, current->doc,
node->properties);
pdesc->value = qjs_xml_attr_make(cx, current->doc, node);
if (JS_IsException(pdesc->value)) {
return -1;
}
Expand Down Expand Up @@ -1573,7 +1572,7 @@ qjs_xml_node(JSContext *cx, JSValueConst val, xmlDoc **doc)


static JSValue
qjs_xml_attr_make(JSContext *cx, qjs_xml_doc_t *doc, xmlAttr *attr)
qjs_xml_attr_make(JSContext *cx, qjs_xml_doc_t *doc, xmlNode *node)
{
JSValue ret;
qjs_xml_attr_t *current;
Expand All @@ -1584,7 +1583,7 @@ qjs_xml_attr_make(JSContext *cx, qjs_xml_doc_t *doc, xmlAttr *attr)
return JS_EXCEPTION;
}

current->attr = attr;
current->node = node;
current->doc = doc;
doc->ref_count++;

Expand Down Expand Up @@ -1623,7 +1622,7 @@ qjs_xml_attr_get_own_property(JSContext *cx, JSPropertyDescriptor *pdesc,

name.length = njs_strlen(name.start);

for (attr = current->attr; attr != NULL; attr = attr->next) {
for (attr = current->node->properties; attr != NULL; attr = attr->next) {
if (attr->type != XML_ATTRIBUTE_NODE) {
continue;
}
Expand Down Expand Up @@ -1685,7 +1684,7 @@ qjs_xml_attr_get_own_property_names(JSContext *cx, JSPropertyEnum **ptab,
return -1;
}

for (attr = current->attr; attr != NULL; attr = attr->next) {
for (attr = current->node->properties; attr != NULL; attr = attr->next) {
if (attr->type != XML_ATTRIBUTE_NODE) {
continue;
}
Expand Down Expand Up @@ -2033,6 +2032,8 @@ qjs_xml_replace_node(JSContext *cx, qjs_xml_node_t *node, xmlNode *current)
xmlUnlinkNode(old);
}

node->node = current;

old->next = node->doc->free;
node->doc->free = old;
}
Expand Down
38 changes: 38 additions & 0 deletions test/xml/xml.t.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,25 @@ let modify_tsuite = {
return doc.note.$text;
},
expected: 'WAKA' },
{ get: (doc) => {
doc.note.setText('WAKA');
doc.note.setText('OVERWRITE');
return doc.note.$text;
},
expected: 'OVERWRITE' },
{ get: (doc) => {
let note = doc.note;
note.setText('WAKA');
note.setText('OVERWRITE');
return note.$text;
},
expected: 'OVERWRITE' },
{ get: (doc) => {
let note = doc.note;
note.setText('WAKA');
return doc.note.$text;
},
expected: 'WAKA' },
{ get: (doc) => {
doc.note.setText('WAKA');
return xml.serializeToString(doc);
Expand Down Expand Up @@ -275,6 +294,19 @@ let modify_tsuite = {
return xml.serializeToString(doc.note.to);
},
expected: `<to>Tove</to>` },
{ get: (doc) => {
let attrs = doc.note.to.$attrs;
doc.note.to.removeAllAttributes();
return attrs.a;
},
expected: undefined },
{ get: (doc) => {
let to = doc.note.to;
let attrs = doc.note.to.$attrs;
to.removeAllAttributes();
return attrs.a;
},
expected: undefined },
{ get: (doc) => {
delete doc.note.to.$attr$a;
return xml.serializeToString(doc.note.to);
Expand Down Expand Up @@ -308,6 +340,12 @@ let modify_tsuite = {
return xml.serializeToString(doc);
},
expected: `<note><from>Jani</from></note>` },
{ get: (doc) => {
let note = doc.note;
note.removeChildren('to');
return xml.serializeToString(doc);
},
expected: `<note><from>Jani</from></note>` },
{ get: (doc) => {
delete doc.note.$tag$to;
return xml.serializeToString(doc);
Expand Down