From: Dmitry Volyntsev Date: Thu, 13 Jan 2022 18:30:31 +0000 (+0000) Subject: Simplified element access in Array.prototype.shift(). X-Git-Tag: 0.7.2~10 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=3eadf4228a9f9dc4fc5f9bcc9c05d7f5a9084cf8;p=njs.git 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. --- diff --git a/src/njs_array.c b/src/njs_array.c index 0f0854b5..112f9152 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -1135,78 +1135,67 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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_object_length_set(vm, this, length); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; + } + + njs_set_undefined(&vm->retval); + + return NJS_OK; } - ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval); + ret = njs_value_property_i64(vm, this, 0, &vm->retval); if (njs_slow_path(ret == NJS_ERROR)) { - return ret; + return NJS_ERROR; } - for (i = 1; i < length; i++) { - ret = njs_value_property_i64_delete(vm, this, i, &entry); + 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; } - if (ret == NJS_OK) { - ret = njs_value_property_i64_set(vm, this, i - 1, &entry); + 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; } - } - } - - length--; -done: + if (ret == NJS_OK) { + ret = njs_value_property_i64_set(vm, this, i - 1, &entry); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; + } + } + } - 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;