ref: 09b3fcb1e7ec420926affc4b6959cd5d8740c02a
parent: f882c6c5fea88ca1eca664b6755ba1d2a7c2b3f5
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Nov 14 12:43:20 EST 2022
Bug 706075: Fix errors in property deletion. 1) Copy "level" from the replacement node. 2) Fix rebalancing by using exact algorithm from AA-tree paper.
--- a/jsproperty.c
+++ b/jsproperty.c
@@ -104,36 +104,43 @@
--obj->count;
}
-static js_Property *unlinkproperty(js_State *J, js_Object *obj, js_Property *node, const char *name, js_Property **garbage)
+static js_Property *unlinkproperty(js_Property *node, const char *name, js_Property **garbage)
{
- js_Property *temp, *succ;
-
+ js_Property *temp, *a, *b;
if (node != &sentinel) {
int c = strcmp(name, node->name);
if (c < 0) {
- node->left = unlinkproperty(J, obj, node->left, name, garbage);
+ node->left = unlinkproperty(node->left, name, garbage);
} else if (c > 0) {
- node->right = unlinkproperty(J, obj, node->right, name, garbage);
+ node->right = unlinkproperty(node->right, name, garbage);
} else {
- if (node->left == &sentinel) {
- *garbage = node;
- node = node->right;
- } else if (node->right == &sentinel) {
- *garbage = node;
- node = node->left;
- } else {
- *garbage = node;
- succ = node->right;
- while (succ->left != &sentinel)
- succ = succ->left;
- succ->right = unlinkproperty(J, obj, node->right, succ->name, &temp);
- succ->left = node->left;
- node = succ;
+ *garbage = node;
+ if (node->left == &sentinel && node->right == &sentinel) {
+ return &sentinel;
}
+ else if (node->left == &sentinel) {
+ a = node->right;
+ while (a->left != &sentinel)
+ a = a->left;
+ b = unlinkproperty(node->right, a->name, &temp);
+ temp->level = node->level;
+ temp->left = node->left;
+ temp->right = b;
+ node = temp;
+ }
+ else {
+ a = node->left;
+ while (a->right != &sentinel)
+ a = a->right;
+ b = unlinkproperty(node->left, a->name, &temp);
+ temp->level = node->level;
+ temp->left = b;
+ temp->right = node->right;
+ node = temp;
+ }
}
- if (node->left->level < node->level - 1 ||
- node->right->level < node->level - 1)
+ if (node->left->level < node->level - 1 || node->right->level < node->level - 1)
{
if (node->right->level > --node->level)
node->right->level = node->level;
@@ -149,9 +156,9 @@
static js_Property *deleteproperty(js_State *J, js_Object *obj, js_Property *tree, const char *name)
{
- js_Property *garbage = NULL;
- tree = unlinkproperty(J, obj, tree, name, &garbage);
- if (garbage != NULL)
+ js_Property *garbage = &sentinel;
+ tree = unlinkproperty(tree, name, &garbage);
+ if (garbage != &sentinel)
freeproperty(J, obj, garbage);
return tree;
}