Dmitry Volyntsev [Tue, 28 Feb 2023 08:26:45 +0000 (00:26 -0800)]
Fixed attaching of a stack to an error object.
This problem is similar to previous commits. When
njs_error_stack_attach() accepted the value as a pointer to vm->retval
that value might be changed as a side effert of njs_error_stack_new()
evaluation. This may result in a garbage value for
njs_object(value) expression.
The workaround fix is to make a copy of vm->retval to ensure its
intergrity and to preserve it as a retval. The proper fix is to
eliminate vm->retval altogether.
Dmitry Volyntsev [Tue, 28 Feb 2023 06:14:36 +0000 (22:14 -0800)]
Fixed njs_object_property() with NJS_WHITEOUT properties.
Previosly, an error object dumping might result in invalid pointer
dereference when 'name' or 'message' property of accessor descriptor
type was added and removed before.
The fix is to properly handle NJS_WHITEOUT properties.
Dmitry Volyntsev [Tue, 28 Feb 2023 06:14:34 +0000 (22:14 -0800)]
Fixed Error() instance dumping when "name" prop is not primitive.
Previously, njs_error_to_string2() might be invoked with error argument
pointing to vm->retval. When "name" prop was not primitive vm->retval
might be overwritten. As a result error pointer might be referencing a
primitive value. In turn the second call of njs_object_property()
received an invalid object pointer because it expects only object value
types.
The fix is to ensure that error object pointer is never overwritten.
Fetch: fixed compatibility with nginx-1.22 and below.
Previously, ngx_table_elt_t structure was used directly in njs fetch
code. This prevents from building with nginx-1.22 as the structure
was changed after nginx-1.22.
The fix is to use njs defined structure instead of ngx_table_elt_t.
Vadim Zhestikov [Thu, 2 Feb 2023 18:01:26 +0000 (10:01 -0800)]
Fixed RegExp.prototype[@@replace]().
Previously, when RegExpExec() returned a fast-array with gaps
String.prototype.replace() might return erroneous exception
TypeError: Cannot convert object to primitive value.
Dmitry Volyntsev [Thu, 26 Jan 2023 05:54:47 +0000 (21:54 -0800)]
Added "xml" module for working with XML documents.
- xml.parse(string|buffer) returns an XMLDoc wrapper object around
XML structure.
- xml.c14n(root_node[, excluding_node]]) canonicalizes root_node and
its children according to https://www.w3.org/TR/xml-c14n, optionally
excluding_node allows to omit from the output a part of the
document.
- xml.exclusiveC14n(root_node[, excluding_node[, withComments [,
prefix_list]]]) canonicalizes root_node and its children
according to https://www.w3.org/TR/xml-exc-c14n/. excluding_node
allows to omit from the output a part of the document
corresponding to the node and its children. withComments
is a boolean and is false by default. When withComments is true
canonicalization corresponds to
http://www.w3.org/2001/10/xml-exc-c14n#WithComments. prefix_list is
an optional string with a space separated namespace prefixes for
namespaces that should also be included into the output.
- XMLDoc an XMLDoc wrapper object around XML structure.
doc.xxx returns the first root tag named "xxx" as XMLNode wrapper
object.
- XMLNode an XMLNode wrapper object around XML tag node.
node.$tag$xxx returns the first child tag named "xxx" as XMLNode
wrapper object.
node.xxx a shorthand syntax for node.$tag$xxx.
node.$tags$xxx? returns an array of all children tags named xxx.
node.$attr$xxx returns an attribute value of xxx.
node.$attrs returns an XMLAttr wrapper object.
node.$name returns the tag name of the node.
node.$ns returns the namespace of the node.
node.$parent returns the parent of the node.
node.$text returns the node's content.
- XMLAttrs an XMLAttrs wrapper object around XML node attributes.
attrs.xxx returns a value of the xxx attribute.
- Example:
const xml = require("xml");
let data = `<note><to b="bar" a= "foo" >Tove</to><from>Jani</from></note>`;
let doc = xml.parse(data);
let dec = new TextDecoder();
let c14n = dec.decode(xml.exclusiveC14n(doc.note));
console.log(c14n) /* '<note><to a="foo" b="bar">Tove</to><from>Jani</from></note>' */
The following functionality for HMAC and AES-* keys were added:
importKey() supporting 'jwk' format,
exportKey() supporting 'jwk' and 'raw' formats,
generateKey().
The following functionality for RSA and EC keys were added:
importKey() supporting 'jwk' format,
also 'raw' format for EC public keys.
exportKey() supporting 'pksc8', 'spki', 'jwk' format,
also 'raw' format for EC public keys.
generateKey().
Previously, since 446a1cb64a6a (0.7.7), when at least one js_import directive
was declared in both HTTP and Stream, ngx.fetch() returned inapproriate
response in Stream.
The prototype for Response object was created two times for HTTP and STREAM,
but the second initialization of global variable with the index of the
Response() prototype overwrites the first value with a different value. This
caused a problem in Stream code which manifested itself as a `Stream flags`
object returned as a result of ngx.fetch() call instead of a Response instance.
The fix is to ensure that shared prototypes like a Response prototype
have indentical index value in all the modules.
Dmitry Volyntsev [Thu, 10 Nov 2022 17:33:36 +0000 (09:33 -0800)]
Change: the default JS stack size is reduced to 64k.
After 86784a68e8c8 (Computed goto) the size of a stack frame
njs_vmcode_interpreter() when -O0 is specified during compilation
increased significantly. This might cause system stack overflow for very
deep recursive calls because system stack is exausted faster than JS
stack.
It is possible now to specify JS stack size for CLI.
Dmitry Volyntsev [Tue, 25 Oct 2022 16:19:32 +0000 (09:19 -0700)]
Refactored working with an object properties.
1) njs_object_prop_t is compacted from 72 to 40 bytes on 64bit
platforms.
2) njs_object_prop_define() is revorked to accomodate fast
property creation using njs_value_create_data_prop()
which corresponds to CreateDataProperty() from the specs.
Previously, a direct pointer to the first element of an array of
rejected promise values was used to convert that element to a string.
This is not correct because that pointer may become invalid if rejected
promise values array is resized between invocation of "toString" and
"valueOf" methods which are called while converting the element to a
string.
The fix is to ensure that the rejected promise value is never changed.
Stream: improved async callback support for s.send().
Previously, the "from_upstream" flag (introduced in b33aae5e8dc6) was
ignored for s.send() calls invoked directly from a body filter.
This makes the s.send() behaviour context dependent.
The fix is to always take "from_upstream" flag into account when it is
provided.