From 09b3fcb1e7ec420926affc4b6959cd5d8740c02a Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 14 Nov 2022 17:43:20 +0100 Subject: [PATCH] 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. --- jsproperty.c | 55 +++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/jsproperty.c b/jsproperty.c index 9b2d9f2..4371d9c 100644 --- a/jsproperty.c +++ b/jsproperty.c @@ -104,36 +104,43 @@ static void freeproperty(js_State *J, js_Object *obj, js_Property *node) --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 *unlinkproperty(js_State *J, js_Object *obj, js_Property *nod 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; }