jscript: Correctly handle deleted entries in iterate_map.

Based on patch by Gabriel Ivăncescu.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This commit is contained in:
Jacek Caban 2022-06-07 18:40:09 +02:00 committed by Alexandre Julliard
parent bae77953ed
commit 6010e6b8cb
2 changed files with 33 additions and 3 deletions

View file

@ -183,7 +183,7 @@ static HRESULT set_map_entry(MapInstance *map, jsval_t key, jsval_t value, jsval
static HRESULT iterate_map(MapInstance *map, script_ctx_t *ctx, unsigned argc, jsval_t *argv, jsval_t *r) static HRESULT iterate_map(MapInstance *map, script_ctx_t *ctx, unsigned argc, jsval_t *argv, jsval_t *r)
{ {
struct jsval_map_entry *entry; struct list *iter = list_head(&map->entries);
IDispatch *context_obj = NULL; IDispatch *context_obj = NULL;
HRESULT hres; HRESULT hres;
@ -200,16 +200,22 @@ static HRESULT iterate_map(MapInstance *map, script_ctx_t *ctx, unsigned argc, j
context_obj = get_object(argv[1]); context_obj = get_object(argv[1]);
} }
LIST_FOR_EACH_ENTRY(entry, &map->entries, struct jsval_map_entry, list_entry) { while(iter) {
struct jsval_map_entry *entry = LIST_ENTRY(iter, struct jsval_map_entry, list_entry);
jsval_t args[3], v; jsval_t args[3], v;
if(entry->deleted)
if(entry->deleted) {
iter = list_next(&map->entries, iter);
continue; continue;
}
args[0] = entry->value; args[0] = entry->value;
args[1] = entry->key; args[1] = entry->key;
args[2] = jsval_obj(&map->dispex); args[2] = jsval_obj(&map->dispex);
grab_map_entry(entry); grab_map_entry(entry);
hres = disp_call_value(ctx, get_object(argv[0]), context_obj, hres = disp_call_value(ctx, get_object(argv[0]), context_obj,
DISPATCH_METHOD, ARRAY_SIZE(args), args, &v); DISPATCH_METHOD, ARRAY_SIZE(args), args, &v);
iter = list_next(&map->entries, iter);
release_map_entry(entry); release_map_entry(entry);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;

View file

@ -1019,6 +1019,18 @@ sync_test("set_obj", function() {
s = new Set([1, 2, 3]); s = new Set([1, 2, 3]);
ok(s.size === 0, "size = " + s.size); ok(s.size === 0, "size = " + s.size);
s = new Set();
s.add(1);
s.add(2);
s.add(3);
r = 0;
s.forEach(function(value, key, obj) {
r++;
s.clear();
ok(s.size === 0, "size = " + s.size);
});
ok(r === 1, "r = " + r);
}); });
sync_test("map_obj", function() { sync_test("map_obj", function() {
@ -1161,6 +1173,18 @@ sync_test("map_obj", function() {
}catch(e) { }catch(e) {
ok(e.number === 0xa13fc - 0x80000000, "e.number = " + e.number); ok(e.number === 0xa13fc - 0x80000000, "e.number = " + e.number);
} }
s = new Map();
s.set(1, 10);
s.set(2, 20);
s.set(3, 30);
r = 0;
s.forEach(function(value, key) {
r++;
s.clear();
ok(s.size === 0, "size = " + s.size);
});
ok(r === 1, "r = " + r);
}); });
sync_test("elem_attr", function() { sync_test("elem_attr", function() {