Duktape supports ES2015 Symbols and also provides a Duktape specific
hidden Symbol variant similar to internal strings in Duktape 1.x.
Hidden Symbols differ from ES2015 Symbols in that they're hidden from
ordinary Ecmascript code: they can't be created from Ecmascript code,
won't be enumerated or JSON-serialized, and won't be returned even from
Object.getOwnPropertyNames()
. Properties with hidden Symbol
keys can only be accessed by a direct property read/write when holding a
reference to a hidden Symbol.
Duktape uses hidden Symbols for various implementation specific purposes, such as storing an object's finalizer reference. User code can also use hidden Symbols for its own purposes, e.g. to store hidden state in objects. User code should never try to access Duktape's hidden Symbol keyed properties: the set of such properties can change arbitrarily between versions.
Symbols of all kinds are represented internally using byte sequences which
are invalid UTF-8; see
symbols.rst
for the current formats in use. When C code pushes a string using e.g.
duk_push_string()
and the byte sequence matches an internal
Symbol format, the string value is automatically interpreted as a Symbol.
\xFFxyz
, i.e. the byte sequence
ff 78 79 7a
, while the Ecmascript string "\u00ffxyz"
would be represented as the CESU-8 bytes c3 bf 78 79 7a
in memory.
Creating a Symbol is straightforward from C code:
/* Create a hidden Symbol which can then be used to read/write properties. * The Symbol can be passed on to Ecmascript code like any other string or * Symbol. Terminating a string literal after a hex escape is safest to * avoid some ambiguous cases like "\xffab". */ duk_push_string(ctx, "\xff" "mySymbol");
For more discussion on C string hex escaping, see c_hex_esc.c.
Hidden Symbols cannot be created from Ecmascript code using the default
built-ins alone. Standard ES2015 Symbols can be created using the
Symbol
built-in, e.g. as Symbol.for('foo')
.
When sandboxing, ensure that application C bindings don't accidentally provide
a mechanism to create hidden Symbols by e.g. converting an input buffer as-is
to a string without applying an encoding.
There's currently no special access control for properties with hidden Symbol keys: if user code has access to the Symbol, it can read/write the property value. This will most likely change in future major versions so that Ecmascript code cannot access a property with a hidden Symbol key, even when holding a reference to the hidden Symbol value.