Dmitry Volyntsev [Thu, 13 Jan 2022 16:20:58 +0000 (16:20 +0000)]
Fixed Array.prototype.concat() when array is changed while iterating.
Previously, the flat array may be converted to a slow one as a
side-effect of a custom getter invocation for a proto array object.
The function erroneously assumed that the this array remains flat
while iterating.
The fix is to eliminate the micro-optimization which uses direct
pointers.
Dmitry Volyntsev [Thu, 13 Jan 2022 15:59:08 +0000 (15:59 +0000)]
Fixed Array.prototype.slice() when array is changed while iterating.
Previously, the flat array may be converted to a slow one as a
side-effect of a custom getter invocation for a proto array object.
The function erroneously assumed that the this array remains flat
while iterating.
The fix is to eliminate the micro-optimization which uses direct
pointers.
The problem is similar to the previous (9578cc729205) commit.
Dmitry Volyntsev [Wed, 12 Jan 2022 17:59:42 +0000 (17:59 +0000)]
Fixed Array.prototype.join() when array is changed while iterating.
Previously, the function used optimization for ordinary arrays with no
gaps (so called fast arrays). For a fast array code took elements
directly from internal flat C array. The direct pointer may become
invalid as side-effect of custom toString() method for an element.
Specifically, the pointer was passed directly to
njs_value_to_primitive() which attempts to call toString() followed by
valueOf(). When the array size is changed as a side-effect of
toString() and not a string value is returned by toString() the pointer
becomes invalid and is passed to valueOf() which causes use-after-free.
The fix is to eliminate the micro-optimization which uses direct pointers.
Dmitry Volyntsev [Tue, 11 Jan 2022 13:02:33 +0000 (13:02 +0000)]
Fixed fuzzing target bug introduced in 4d4657128baf (0.7.1).
Previously, njs_process_script() took vm pointer from console object,
but after 4d4657128baf the object is not initialized in
LLVMFuzzerTestOneInput().
Dmitry Volyntsev [Fri, 24 Dec 2021 15:48:11 +0000 (15:48 +0000)]
Building regexp backend as an external.
This allows not to build PCRE specific code as a part of libnjs.a thus
supporting nginx builds with flags like --with-pcre=PCRE_DIR. When
--no-pcre configure option is provided external code have to implement
methods declared in njs_regex.h.
Dmitry Volyntsev [Wed, 17 Nov 2021 17:01:07 +0000 (17:01 +0000)]
SSL: fixed reporting of the detected library version.
Previously, `openssl version` command was used to report the OpenSSL
version. Whereas, when provided with custom CFLAGS and LDFLAGS the
used library may differ from the system one.
The fix is to report OpenSSL version using the provided library.
Dmitry Volyntsev [Thu, 11 Nov 2021 14:26:41 +0000 (14:26 +0000)]
RegExp: improved source string treatment.
Previously, njs_regexp_pattern_create() in addition to a pattern
compilation made a string representation for a RegExp which was returned
by RegExp.prototype.toString() as is.
After 02444445df29 (0.6.0), RegExp.prototype.toString() was implemented
according to the spec, and since then it creates a RegExp string on the fly.
This patch removes the extra code which was left.
In addition, as a source string may not be a valid UTF-8 string (in
RegExp literals), RegExp.prototype.toString() now ensures that a
valid UTF-8 string is returned.
After 0a2a0b5a74f4 (0.6.0), the referencing of a closure value inside of
a nested function may result in heap-use-after-free. For this to happen
the closure value have to be referenced in a function invoked asynchronously.
For example if a closure value is referenced in r.subrequest() or setTimeout()
handler.
The problem was that closure values of nested function were assigned during
the function call and the memory shared between all the cloned VMs was used
to store temporary assignments until the moment the declared function was
referenced. When two VMs executed concurrently, the first VM might see
the changed made by the second VM if the first one was suspended.
The fix is to copy all declared functions at the time of the call.
Similar to the connection hang fixed in 058a67435e83 in nginx,
it is possible that an established connection is ready for reading
after the handshake. Further, events might be already disabled
in case of level-triggered event methods.
Fix is to post a read event if the c->read->ready flag is set.
The fetch API now accepts an extra parameters:
- verify: boolean (default true) to control server certificate
verification.
Verification process can be controlled with the following directives
from the http js and stream js modules:
- js_fetch_ciphers
- js_fetch_protocols
- js_fetch_verify_depth
- js_fetch_trusted_certificate
Previously a shared "keywords_hash" and "values_hash" were used while
compiling functions in runtime. This led to populating a shared hash
with elements allocated in a cloned VM. Which resulted in
heap-use-after-free when next cloned VM accesses the shared hashes.
Previously, njs_buffer_slot() might return NULL value without setting
corresponding exception where user code expects it.
In addition the function is split into two functions. The internal one
does not set anything to vm->retval. This function has to be used by
property handlers, because they are expected not to modify vm->retval.