Re: Please help with writing spec for async JSON APIs

2015-08-03 Thread James M Snell
On Mon, Aug 3, 2015 at 8:34 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
[snip]

 4) JSON.parse/stringify are pure computational  operations.  There is no
 perf benefit to making them asynchronous unless some of their computation
 can be performed concurrently.


If we're speaking strictly about making the JSON parsing asynchronous,
then correct, there is really no performance benefit to speak of. You
may be able to offload the parsing to a separate thread, but it's
going to take the same amount of time. The real benefit will come when
(a) JSON parsing becomes incremental and (b) a developer is given
greater control over exactly how the JSON is converted to/from
strings.

Something along the lines of...

JSON.parser(input).
  on('key', function(key, context) {
if (key === 'foo')
  console.log(context.value());
else if (key === 'bar')
  context.on('key', ...);
  }).
  on('end', function() {
  });

In other words: allowing for incremental access to the stream and fine
grained control over the parsing process, rather than having to block
while everything is parsed out, building up the in-memory object
model, then being forced to walk that model in order to do anything
interesting.

Personally, I'm not overly concerned about the possibility of races.

- James
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Please help with writing spec for async JSON APIs

2015-08-03 Thread James M Snell
On Mon, Aug 3, 2015 at 10:29 AM, Allen Wirfs-Brock
al...@wirfs-brock.com wrote:
[snip]

 I have to guess at your semantics, but what you are trying to express above 
 seems like something that can already be accomplished using the `reviver` 
 argument to JSON.parse.


Yes and no. `reviver` achieves part of goal but but still assumes that
parsing is fundamentally blocking and assumes that I want to return
something and have that in-memory obj built up and returned. However,
if what I want instead is to forgo the creation of an in memory model
altogether and working simply from an incremental, async stream of
events, then I'm out of luck.

 In other words: allowing for incremental access to the stream and fine
 grained control over the parsing process, rather than having to block
 while everything is parsed out, building up the in-memory object
 model, then being forced to walk that model in order to do anything
 interesting.

 Personally, I'm not overly concerned about the possibility of races.

 But, TC39 is concerned about races.


Granted ;-) ... there's a reason I prefixed that sentence with 'Personally' ;-)


 - James


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Named Arrow Functions

2015-08-11 Thread James M Snell
On Tue, Aug 11, 2015 at 2:21 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
[snip]

 let Y = F = (x=F(y=(x(x))(y)))(x=F(y=(x(x))(y)));


Aahh! my eyes! it burns!!!
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: import.meta and TC39 process as a whole

2017-08-04 Thread James M Snell
Dmitrii,

Quick aside: the rude manner in which you are communicating is interfering
with your goal of convincing anyone. Perhaps if you tried not being so
rude, people here would be more willing to listen to what you're saying.

- James

On Fri, Aug 4, 2017 at 1:09 AM Dmitrii Dimandt  wrote:

> Let’s continue with the trend of light reading. Let’s see the multitude of
> things that are in JS, and no one bats an eye:
>
> — start quote —
>
> Note that implements, let, private, public, interface, package, protected
> , static, and yield are disallowed in strict mode only.
>
> You may have noticed I included eval and arguments in the list. These are
> not strictly reserved words, but they sure act like them
>  — they’re
> disallowed in strict mode too.
>
> Also, the (unlisted) NaN, Infinity, and undefined properties of the
> global object are immutable or read-only properties in ES5. So even though var
> NaN = 42; in the global scope wouldn’t throw an error, it wouldn’t
> actually do anything. To avoid confusion, I’d suggest avoiding the use of
> these identifiers altogether, even though they’re not strictly reserved
> words.
>
> — end quote —
>
> Oh, hello. What do we have here? Non-reserved words like they are
> reserved, and JS treating them in a special way.
>
> So. The *only* reason *not* to introduce a proper global introspection API
> is?
>
> On Fri, 04 Aug 2017 at 10:03 dmit...@dmitriid.com 
> wrote:
>
>> I’d recommend you assume your opponent has done some light reading. And
>> I’d suggest you yourself read the links you post (that is, practice what
>> you preach).
>>
>> Multiple reserved keywords have been both added to the language and
>> removed from the language. Because *the language evolves*.
>>
>> However, you (and TC39 in general) keep insisting that short-sightedness
>> and ad-hoc solutions is the only way forward for JavaScript.
>>
>> You don’t like System, you think it cannot be used? Oh, introduce an
>> `introspect` keyword. Introduce a `system` keyword. Heck, nothing stopped
>> you from introducing a language-level built-in in the form of Symbol,
>> what’s stopping you now?
>>
>>
>>
>> On Fri, 04 Aug 2017 at 09:55 Jordan Harband > > wrote:
>>
>>> Because it's been reserved syntax since JavaScript's inception, and
>>> System hasn't.
>>>
>>> I'd recommend some light reading before attempting to continue arguing:
>>> https://mathiasbynens.be/notes/reserved-keywords
>>>
>>> On Fri, Aug 4, 2017 at 12:53 AM, Dmitrii Dimandt 
>>> wrote:
>>>
 But you can’t `var x = import`, for example. I guess you can’t `var
 import = {}`  either.

 Hmmm… I wonder why…



 On Fri, 04 Aug 2017 at 09:50 Jordan Harband >>> > wrote:

> It can't be made syntax, because `var System = {};` is valid code, and
> we can't break the web. (seriously)
>
> On Fri, Aug 4, 2017 at 12:31 AM, Dmitrii Dimandt  > wrote:
>
>> Make “System” syntax, and there you go.
>>
>> Instead we have multiple ad-hoc random additions to random keywords
>> just because someone needs something and since there are rarely any
>> long-term design decisions anymore, we’re stuck with new.target,
>> function.sent, import.meta (add your own)
>>
>> Seriously. How is new.target is “syntax that has context
>> information”, but System.whatever cannot be provided with context
>> information because it’s API?
>>
>>
>>
>> On Fri, 04 Aug 2017 at 09:26 Jordan Harband > > wrote:
>>
>>> > There’s nothing stopping you from providing context to
>>> System.load. Or Loader.import, or…
>>>
>>> Those are APIs. It is, in fact, impossible to provide context with
>>> API, since it's just normal functions - it must be with syntax.
>>>
>>> Additionally, please don't use sexual language, especially in a
>>> derogatory manner - that's against TC39's code of conduct, and I'm quite
>>> sure it won't be tolerated on this list.
>>>
>>> Criticism that's purely insult, and doesn't actually explain the
>>> cons of something, is also not productive or useful.
>>>
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>> On Fri, Aug 4, 2017 at 12:20 AM, Gil Tayar  wrote:
>>>
 Myself, and tens of programmers I know, use ES6 modules (and their
 precursors, CommonJS modules) for years now and can't even believe 
 there
 was a time when they didn't exist, given that they have totally 
 transformed
 (in a good way) the way we work. And that is also the vibe I am 

Re: Proxy target/handler access leak in Node

2018-09-17 Thread James M Snell
Some background as I am the one who added the showProxy feature into
Node.js...

util.inspect() is considered by Node.js to be a diagnostics API. The intent
is to allow adequate debugging in a variety of scenarios. This was added to
address a user issue where inspection of a Proxy object (that the user
didn't know was a proxy object) would cause an infinite loop when invoking
a certain getter that just happened to have a console.log statement (in
Node.js, console.log uses util.inspect in some cases. There are cases where
one does need to know when an object is a Proxy.

That said, the specific issue in this thread is a bit different. When
implementing showProxy, I took the additional step of introspecting the
component elements of the proxy because the goal of util.inspect is to
provide as much insight as possible about the object being inspected. The
ability to provide a custome stylize function for inspect is a long
standing feature of Node.js long before showProxy was introduced.

One thing I would not classify this as is an attack, exploit, or
vulnerability. The Node.js trust model assumes that all code is trusted. I
can, however, bring this issue to the Node.js project and see how folks
would feel about not exposing the internal objects when a Proxy is
detected. That would reduce the diagnostic utility of util.inspect with
Proxy objects, which is unfortunate, but it would resolve the issue here.
Removing this would likely require a proper deprecation of the existing
functionality which is a semver-major change.

The final thing I would say is: Node.js has a responsible disclosure
process for potential security vulnerability reports. If one feels that
some behavior implemented by node.js presents a vulnerability or attack
vector, I would encourage them to please use our HackerOne site (
https://hackerone.com/nodejs) to report the issue before discussing in a
public forum so that the potential risks can be evaluated before public
disclosure.



On Mon, Sep 17, 2018, 02:19 Darien Valentine  wrote:

> > What is going on here? Can you explain?
>
> A C++/V8 API is used to obtain references to the target and handler from
> only the proxy object, even though those objects aren’t supposed to be
> available to this ES scope:
>
> https://github.com/nodejs/node/blob/master/lib/util.js#L642-L647
>
> The pair of objects is passed to another function, which in turn may pass
> values to the method "ctx.stylize", but that property may have been
> previously overwritten from user code:
>
> https://github.com/nodejs/node/blob/master/lib/util.js#L566-L580
>
> AFAICT, fixing the leak (beyond util.js) would be possible by making
> `stylize` unconfigurable/unwritable. However there may be other avenues
> here — I’m not sure.
>
> > Does that mean this attack is impossible from code loaded into a new
> realm as made by the shim or SES?
>
> The exploit isn’t sensitive to realm-of-origin, since util is using v8
> internals to get the references, not e.g. a patched version of Proxy. But
> it still depends on the proxy object in question being exposed to a context
> where util.inspect exists.
>
> In the [issue comment](
> https://github.com/nodejs/node/issues/10731#issuecomment-419008987), I
> wrote this:
>
> > This exploit can be fixed pretty easily. But I think it’s symptomatic.
> My understanding was that V8’s C++ APIs are intended for making external
> functionality available to ECMAScript using ECMAScript values and
> ECMAScript semantics. Here though, it is being used to bypass ECMAScript
> semantics. The behavior seen in the above script isn’t possible in
> ECMAScript — but neither is distinguishing between objects which have been
> implemented as ordinary objects and objects implemented as proxy exotic
> objects.
>
>
> On Sun, Sep 16, 2018 at 8:06 PM Mark Miller  wrote:
>
>> This is indeed quite scary. I have never used of explored the Node `util`
>> API. What is going on here? Can you explain?
>>
>> The Realms shim and SES (which build on the Realms shim) create an
>> environment in which only those globals defined by EcmaScript, not by the
>> host, are present by default.
>> https://github.com/Agoric/SES/tree/master/demo
>> https://rawgit.com/Agoric/SES/master/demo/
>> Does that mean this attack is impossible from code loaded into a new
>> realm as made by the shim or SES?
>>
>>
>>
>> On Sun, Sep 16, 2018 at 12:10 PM Mike Samuel 
>> wrote:
>>
>>> Nicely done!
>>>
>>> One more reason to prefer WeakMaps to properties when relating objects
>>> and secrets.
>>>
>>>
>>>
>>> On Sun, Sep 16, 2018 at 2:59 PM Darien Valentine 
>>> wrote:
>>>
 A few weeks ago I’d commented on an open Node github issue regarding
 Proxies and inspection. While the bulk of the comment concerns an opinion
 that proxies should not be treated as special case, I included an example
 of a mechanism by which the current implementation allows outside code to
 access the target and handler objects of a proxy that it does not own.


Symbol.await proposal

2020-06-22 Thread James M Snell
For many legacy code bases that are based on callbacks mechanisms like
node.js' promisify function are required to help facilitate the transition
from callback centric code to Promise-centric. A lot of the time, these can
follow straightforward rules without requiring customization. However, at
other times it is necessary for user code to provide custom implementations
of the Promise-version of the function.

In Node.js, we accomplish this by allowing a function to have a symbol
attached whose value is an alternative function that is returned by the
promisify function

For instance,

  function myFunction(foo, bar, callback) {
callback(null, foo, bar);
  }
  myFunction[util.customPromisifySymbol] = async function(foo, bar) {
return [foo, bar];
  }

  const { promisify } = require('util');
  const mine = promisify(myFunction);
  (async () => console.log(await mine('a','b')))();

As a convenience built into the language, it would be nice to be able to
short-circuit the need to call promisify with a special language-level
Symbol used specifically for this purpose:

  function myFunction(foo, bar, callback) {
callback(null, foo, bar);
  }
  myFunction[Symbol.await] = async function(foo, bar) {
return [foo, bar];
  }

  (async () => console.log(await myFunction('a','b')))();

The idea here is that if the function being awaited has the [Symbol.await]
property whose value is a function, then that function is called when the
await keyword is used. That is,

  myFunction('a', 'b', callback); // Invokes myFunction directly
  await myFunction('a', 'b');  // Invokes myFunction[Symbol.await]

if the Symbol.await property is not set or is not callable, then it would
fallback to default behavior.

Automatic handling of this binding should also happen but has some
technical detail to work out:

  const obj = {
a: 1,
foo() {}
  };
  obj.foo[Symbol.await] = async function() {
return this.a;
  }
  await obj.foo();  // Calls await obj.foo[Symbol.await] with bound this

This approach would make it far easier for legacy code bases to make the
transition to async/await syntax while maintaining legacy compat.

Before writing up a formal proposal, I wanted to solicit some feedback on
this approach to see what folks thought.

- James
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise-returning delay function

2020-12-27 Thread James M Snell
For Node.js we implemented this as an alternative to the current setTimeout:

const { setTimeout } = require('timers/promises')

// Or

import { setTimeout } from 'timers/promises'

Then...

await setTimeout(500)

It works very well and is straightforward to implement on the browser-side.

On Sun, Dec 27, 2020, 09:56 Cyril Auburtin  wrote:

> Follow up on https://esdiscuss.org/topic/promise-returning-delay-function
>
> I think we really need that function, with AbortController support
>
> We could do things like
>
> ```js
> const abortFetch = new AbortController();
> const abortTimeout = new AbortController();
>
> await Promise.race([
>   Promise.delay(5000, {signal: abortTimeout.signal}),
>   fetch(url, {signal: abortFetch.signal}).then(r => r.json()).then(...),
> ])
>   .finally(() => {
> abortFetch.abort();
> abortTimeout.abort(); // avoid mem leaks, that would call clearTimeout
> under the hood
>   })
> ```
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss