Dmitry Volyntsev [Wed, 17 May 2023 07:39:45 +0000 (00:39 -0700)]
Fixed evaluation of computed property names with function expressions.
Previously, while evaluating a property name expression with a function
expression as the right side, the evaluation modified the value used to
compute the property name in-place. The in-place modification changes
values not intended to be changed.
Sergey A. Osokin [Fri, 12 May 2023 23:38:29 +0000 (19:38 -0400)]
Always use a sharp (#) symbol as the sed separator.
sed(1) command line utility may fail with the following error:
sed: 1: "s, at EXTRA_LIBS@,-lm -L ...": bad in substitute command: '-'
when a replacement for @EXTRA_LIBS@ contains a comma symbol.
Dmitry Volyntsev [Thu, 11 May 2023 05:36:53 +0000 (22:36 -0700)]
Modules: added options to disable parts dependant on 3rd party libs.
The following environment variables are added: NJS_OPENSSL, NJS_LIBXSLT,
NJS_ZLIB. When a variable evaluates to "NO" the part of the module
related to the corresponsing library is disabled.
For example to disable libxslt related code:
NJS_LIBXSLT=NO ./configure .. --add-module=/path/to/njs/module
Dmitry Volyntsev [Wed, 10 May 2023 05:09:13 +0000 (22:09 -0700)]
Fetch: removed special treatment of forbidden headers.
In c43261bad627 (0.7.10), a notion of forbidden headers was introduced
in accordance in Fetch API. In the API the Forbidden headers are not
allowed to be changed from JavaScript code for security reasons.
The restriction is removed because there are use cases where Host (which
is considered forbidden) is different from the host address in
URL and JavaScript code is expected to be a trusted source (unlike a
browser context).
Previously, the completion logic was split between njs_vm_completion()
and njs_completion_generator() in shell. Now the completion part is
done in njs_vm_completion(), as a result njs_completion_generator()
is simplified.
Change: non-compliant deprecated String methods were removed.
The following methods were removed:
String.bytesFrom(),
String.prototype.fromBytes(),
String.prototype.fromUTF8(),
String.prototype.toBytes(),
String.prototype.toUTF8(),
String.prototype.toString(encoding).
Because String.bytesFrom() was used to test the existing code
which works with byte strings it was replaced with $262.bytesString()
which is only available in unit tests.
Change: native methods are provided with retval argument.
Previously, native methods were expected to return
their retval using vm->retval. This caused problem in the part
(1aa137411b09, 293fe42c5e1c) because vm->retval can be overwritten
unexpectedly as a side-effect of operations like ToString(), ToNumber().
The fix is to never used a global retval. Instead methods
are provided with a retval argument to store their retval value.
As a part of the change, retval and exception values are split.
The normal value is returned in the retval argument.
The exception value is thrown by njs_vm_throw() or njs_vm_error().
The exception value can be acquired using njs_vm_exception_get().
Dmitry Volyntsev [Thu, 30 Mar 2023 03:28:33 +0000 (20:28 -0700)]
Aligned Number constructor to the spec.
Previously, negative hexadecimal numbers were accepted as valid,
whereas they are invalid input for the constructor.
Also previously, the constructor did not accepted positive binary or
octadecimal numbers as valid.
Dmitry Volyntsev [Tue, 28 Mar 2023 05:41:27 +0000 (22:41 -0700)]
Added "zlib" module.
- zlib.deflateRawSync(string|buffer, options?) compresses data using
deflate, and do not append a zlib header, returns Buffer.
- zlib.deflateSync(string|buffer, options?) compresses data using
deflate, returns Buffer.
- zlib.inflateRawSync(string|buffer) decompresses a raw deflate
stream, returns Buffer.
- zlib.inflateSync(string|buffer) decompresses a deflate stream,
return Buffer.
Dmitry Volyntsev [Fri, 10 Mar 2023 22:15:29 +0000 (14:15 -0800)]
Fetch: fixed Headers() constructor.
Previously, the 'guard' field of ngx_js_headers_t structure was uninitialized,
that caused spurious exception "Error: cannot append to immutable object".
Fixed String.prototype.replace() with replacement containing "$'", "$`".
Previously, the resulting string was might be broken when the string to
replace and the search string were UTF-8. pos is always a character
offset, it should not be directly used as a byte size or offset.
Fixed Array.prototype.sort() when array is changed while sorting.
Previously, the fast-path check did not take into account the fact that
the flat array may be resized as a side effect of the array's values
evaluation.
In addition, the slow_path fix ensures that "this" array is repopulated
again even if the array was resized.
XML: removed XML_PARSE_DTDVALID during a document parsing.
When XML_PARSE_DTDVALID is enabled libxml2 parses and executes external
entities present inside an xml document. This can lead to all the
classic XXE exploits, including SSRF and local file disclosure.
The issue was introduced in 99b9f83e4d4d (0.7.10).
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>' */