Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 67 additions & 5 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8002,7 +8002,26 @@ added:

* Type: {number|bigint}

Free blocks available to unprivileged users.
Free blocks available to unprivileged users. Multiply by [`statfs.bsize`][]
to get the number of available bytes.

```mjs
import { statfs } from 'node:fs/promises';

const stats = await statfs('/');
const availableBytes = stats.bsize * stats.bavail;
console.log(`Available space: ${availableBytes} bytes`);
```

```cjs
const { statfs } = require('node:fs/promises');

(async () => {
const stats = await statfs('/');
const availableBytes = stats.bsize * stats.bavail;
console.log(`Available space: ${availableBytes} bytes`);
})();
```

#### `statfs.bfree`

Expand All @@ -8014,7 +8033,26 @@ added:

* Type: {number|bigint}

Free blocks in file system.
Free blocks in file system. Multiply by [`statfs.bsize`][] to get the number
of free bytes.

```mjs
import { statfs } from 'node:fs/promises';

const stats = await statfs('/');
const freeBytes = stats.bsize * stats.bfree;
console.log(`Free space: ${freeBytes} bytes`);
```

```cjs
const { statfs } = require('node:fs/promises');

(async () => {
const stats = await statfs('/');
const freeBytes = stats.bsize * stats.bfree;
console.log(`Free space: ${freeBytes} bytes`);
})();
```

#### `statfs.blocks`

Expand All @@ -8026,7 +8064,26 @@ added:

* Type: {number|bigint}

Total data blocks in file system.
Total data blocks in file system. Multiply by [`statfs.bsize`][] to get the
total size in bytes.

```mjs
import { statfs } from 'node:fs/promises';

const stats = await statfs('/');
const totalBytes = stats.bsize * stats.blocks;
console.log(`Total space: ${totalBytes} bytes`);
```

```cjs
const { statfs } = require('node:fs/promises');

(async () => {
const stats = await statfs('/');
const totalBytes = stats.bsize * stats.blocks;
console.log(`Total space: ${totalBytes} bytes`);
})();
```

#### `statfs.bsize`

Expand All @@ -8038,7 +8095,7 @@ added:

* Type: {number|bigint}

Optimal transfer block size.
Optimal transfer block size in bytes.

#### `statfs.frsize`

Expand Down Expand Up @@ -8086,7 +8143,11 @@ added:

* Type: {number|bigint}

Type of file system.
Type of file system. A platform-specific numeric identifier for the type of
file system. This value corresponds to the `f_type` field returned by
`statfs(2)` on POSIX systems (for example, `0xEF53` for ext4 on Linux). Its
meaning is OS-dependent and is not guaranteed to be consistent across
platforms.

### Class: `fs.Utf8Stream`

Expand Down Expand Up @@ -9139,6 +9200,7 @@ the file contents.
[`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
[`minimatch`]: https://github.com/isaacs/minimatch
[`node:stream/iter`]: stream_iter.md
[`statfs.bsize`]: #statfsbsize
[`stream/iter pipeTo()`]: stream_iter.md#pipetosource-transforms-writer
[`stream/iter pull()`]: stream_iter.md#pullsource-transforms-options
[`stream/iter pullSync()`]: stream_iter.md#pullsyncsource-transforms
Expand Down
6 changes: 3 additions & 3 deletions lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,16 @@ class ModuleLoader {
let job = this.loadCache.get(url, kImplicitTypeAttribute);
// This module job is already created:
// 1. If it was loaded by `require()` before, at this point the instantiation
// is already completed and we can check the whether it is in a cycle
// (in that case the module status is kEvaluaing), and whether the
// is already completed and we can check whether it is in a cycle
// (in that case the module status is kEvaluating), and whether the
// required graph is synchronous.
// 2. If it was loaded by `import` before, only allow it if it's already evaluated
// to forbid cycles.
// TODO(joyeecheung): ensure that imported synchronous graphs are evaluated
// synchronously so that any previously imported synchronous graph is already
// evaluated at this point.
// TODO(joyeecheung): add something similar to CJS loader's requireStack to help
// debugging the the problematic links in the graph for import.
// debugging the problematic links in the graph for import.
debug('importSyncForRequire', parent?.filename, '->', filename, job);
if (job !== undefined) {
mod[kRequiredModuleSymbol] = job.module;
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/streams/iter/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ class PushQueue {
pending.reject(this.#error);
} else if (this.#consumerState === 'returned') {
const pending = this.#pendingReads.shift();
pending.resolve({ __proto__: null, value: undefined, done: true });
pending.resolve({ __proto__: null, done: true, value: undefined });
} else {
break;
}
Expand Down
17 changes: 8 additions & 9 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -700,32 +700,31 @@ Intercepted ContextifyContext::PropertyDefinerCallback(
if (desc.has_configurable()) {
desc_for_sandbox->set_configurable(desc.configurable());
}
// Set the property on the sandbox.
USE(sandbox->DefineProperty(context, property, *desc_for_sandbox));
return sandbox->DefineProperty(context, property, *desc_for_sandbox);
};

if (desc.has_get() || desc.has_set()) {
PropertyDescriptor desc_for_sandbox(
desc.has_get() ? desc.get() : Undefined(isolate).As<Value>(),
desc.has_set() ? desc.set() : Undefined(isolate).As<Value>());

define_prop_on_sandbox(&desc_for_sandbox);
// TODO(https://github.com/nodejs/node/issues/52634): this should return
// kYes to behave according to the expected semantics.
if (define_prop_on_sandbox(&desc_for_sandbox).FromMaybe(false))
return Intercepted::kYes;
return Intercepted::kNo;
} else {
Local<Value> value =
desc.has_value() ? desc.value() : Undefined(isolate).As<Value>();

Maybe<bool> result;
if (desc.has_writable()) {
PropertyDescriptor desc_for_sandbox(value, desc.writable());
define_prop_on_sandbox(&desc_for_sandbox);
result = define_prop_on_sandbox(&desc_for_sandbox);
} else {
PropertyDescriptor desc_for_sandbox(value);
define_prop_on_sandbox(&desc_for_sandbox);
result = define_prop_on_sandbox(&desc_for_sandbox);
}
// TODO(https://github.com/nodejs/node/issues/52634): this should return
// kYes to behave according to the expected semantics.

if (result.FromMaybe(false)) return Intercepted::kYes;
return Intercepted::kNo;
}
}
Expand Down
24 changes: 24 additions & 0 deletions test/parallel/test-vm-property-definer-interception.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

require('../common');
const vm = require('vm');
const assert = require('assert');

// Each [[DefineOwnProperty]] intercepted by the definer should invoke the
// sandbox's [[DefineOwnProperty]] exactly once.
{
let count = 0;
const sandbox = new Proxy({}, {
defineProperty(target, key, desc) {
count++;
return Reflect.defineProperty(target, key, desc);
},
});
const ctx = vm.createContext(sandbox);
vm.runInContext(`
Object.defineProperty(this, 'a', { value: 1 });
Object.defineProperty(this, 'b', { value: 2, writable: true });
Object.defineProperty(this, 'c', { get() { return 3; } });
`, ctx);
assert.strictEqual(count, 3);
}
Loading
Loading