details: https://hg.nginx.org/njs/rev/dfbde7620ced branches: changeset: 1806:dfbde7620ced user: Dmitry Volyntsev <xei...@nginx.com> date: Thu Jan 13 18:30:31 2022 +0000 description: Simplified element access in Array.prototype.shift().
Previously, array structure may be left in inconsistent state when a custom getter in a proto array changes array size. The change is similar to the previous commits. diffstat: src/njs_array.c | 89 ++++++++++++++++++++++++-------------------------------- 1 files changed, 39 insertions(+), 50 deletions(-) diffs (121 lines): diff -r 762774041f05 -r dfbde7620ced src/njs_array.c --- a/src/njs_array.c Thu Jan 13 18:30:31 2022 +0000 +++ b/src/njs_array.c Thu Jan 13 18:30:31 2022 +0000 @@ -1135,78 +1135,67 @@ njs_array_prototype_shift(njs_vm_t *vm, int64_t i, length; njs_int_t ret; njs_array_t *array; - njs_value_t *this, *item, entry; + njs_value_t *this, entry; this = njs_argument(args, 0); - length = 0; ret = njs_value_to_object(vm, this); if (njs_slow_path(ret != NJS_OK)) { return ret; } - njs_set_undefined(&vm->retval); - - if (njs_is_fast_array(this)) { - array = njs_array(this); - - if (array->length != 0) { - array->length--; - item = &array->start[0]; - - if (njs_is_valid(item)) { - vm->retval = *item; - - } else { - /* src value may be in Array.prototype object. */ - - ret = njs_value_property_i64(vm, this, 0, &vm->retval); - if (njs_slow_path(ret == NJS_ERROR)) { - return NJS_ERROR; - } - } - - array->start++; - } - - return NJS_OK; - } - ret = njs_object_length(vm, this, &length); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } if (length == 0) { - goto done; - } - - ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval); - if (njs_slow_path(ret == NJS_ERROR)) { - return ret; - } - - for (i = 1; i < length; i++) { - ret = njs_value_property_i64_delete(vm, this, i, &entry); + ret = njs_object_length_set(vm, this, length); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } - if (ret == NJS_OK) { - ret = njs_value_property_i64_set(vm, this, i - 1, &entry); + njs_set_undefined(&vm->retval); + + return NJS_OK; + } + + ret = njs_value_property_i64(vm, this, 0, &vm->retval); + if (njs_slow_path(ret == NJS_ERROR)) { + return NJS_ERROR; + } + + if (njs_is_fast_array(this)) { + array = njs_array(this); + + array->start++; + array->length--; + + } else { + + ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; + } + + for (i = 1; i < length; i++) { + ret = njs_value_property_i64_delete(vm, this, i, &entry); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } + + if (ret == NJS_OK) { + ret = njs_value_property_i64_set(vm, this, i - 1, &entry); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; + } + } } - } - - length--; - -done: - - ret = njs_object_length_set(vm, this, length); - if (njs_slow_path(ret == NJS_ERROR)) { - return ret; + + ret = njs_object_length_set(vm, this, length - 1); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; + } } return NJS_OK; _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org