fs: special input `-1` on `chown`, `lchown` and `fchown` · nodejs/node@38ffed8 · GitHub
Skip to content

Commit 38ffed8

Browse files
himself65aduh95
authored andcommitted
fs: special input -1 on chown, lchown and fchown
PR-URL: #58836 Fixes: #58826 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent b19ffeb commit 38ffed8

5 files changed

Lines changed: 126 additions & 9 deletions

File tree

src/node_file.cc

Lines changed: 6 additions & 6 deletions

src/util-inl.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,27 +607,36 @@ constexpr std::string_view FastStringKey::as_string_view() const {
607607

608608
// Converts a V8 numeric value to a corresponding C++ primitive or enum type.
609609
template <typename T,
610+
bool loose = false,
610611
typename = std::enable_if_t<std::numeric_limits<T>::is_specialized ||
611612
std::is_enum_v<T>>>
612613
T FromV8Value(v8::Local<v8::Value> value) {
613614
if constexpr (std::is_enum_v<T>) {
614615
using Underlying = std::underlying_type_t<T>;
615-
return static_cast<T>(FromV8Value<Underlying>(value));
616+
return static_cast<T>(FromV8Value<Underlying, loose>(value));
616617
} else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>) {
617618
static_assert(
618619
std::numeric_limits<T>::max() <= std::numeric_limits<uint32_t>::max() &&
619620
std::numeric_limits<T>::min() >=
620621
std::numeric_limits<uint32_t>::min(),
621622
"Type is out of unsigned integer range");
622-
CHECK(value->IsUint32());
623+
if constexpr (!loose) {
624+
CHECK(value->IsUint32());
625+
} else {
626+
CHECK(value->IsNumber());
627+
}
623628
return static_cast<T>(value.As<v8::Uint32>()->Value());
624629
} else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
625630
static_assert(
626631
std::numeric_limits<T>::max() <= std::numeric_limits<int32_t>::max() &&
627632
std::numeric_limits<T>::min() >=
628633
std::numeric_limits<int32_t>::min(),
629634
"Type is out of signed integer range");
630-
CHECK(value->IsInt32());
635+
if constexpr (!loose) {
636+
CHECK(value->IsInt32());
637+
} else {
638+
CHECK(value->IsNumber());
639+
}
631640
return static_cast<T>(value.As<v8::Int32>()->Value());
632641
} else {
633642
static_assert(std::is_floating_point_v<T>,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const fs = require('fs');
6+
const path = require('path');
7+
const tmpdir = require('../common/tmpdir');
8+
9+
tmpdir.refresh();
10+
11+
const testFile = path.join(tmpdir.path, 'chown-test-file.txt');
12+
13+
fs.writeFileSync(testFile, 'test content for chown');
14+
15+
const stats = fs.statSync(testFile);
16+
const uid = stats.uid;
17+
const gid = stats.gid;
18+
19+
// -1 for uid and gid means "don't change the value"
20+
{
21+
fs.chown(testFile, -1, -1, common.mustSucceed(() => {
22+
const stats = fs.statSync(testFile);
23+
assert.strictEqual(stats.uid, uid);
24+
assert.strictEqual(stats.gid, gid);
25+
}));
26+
}
27+
{
28+
fs.chownSync(testFile, -1, -1);
29+
const stats = fs.statSync(testFile);
30+
assert.strictEqual(stats.uid, uid);
31+
assert.strictEqual(stats.gid, gid);
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const fs = require('fs');
6+
const path = require('path');
7+
const tmpdir = require('../common/tmpdir');
8+
9+
tmpdir.refresh();
10+
11+
const testFilePath = path.join(tmpdir.path, 'fchown-test-file.txt');
12+
13+
fs.writeFileSync(testFilePath, 'test content for fchown');
14+
15+
{
16+
const fd = fs.openSync(testFilePath, 'r+');
17+
const stats = fs.fstatSync(fd);
18+
const uid = stats.uid;
19+
const gid = stats.gid;
20+
21+
fs.fchown(fd, -1, -1, common.mustSucceed(() => {
22+
const stats = fs.fstatSync(fd);
23+
assert.strictEqual(stats.uid, uid);
24+
assert.strictEqual(stats.gid, gid);
25+
fs.closeSync(fd);
26+
}));
27+
}
28+
29+
// Test sync fchown with -1 values
30+
{
31+
const fd = fs.openSync(testFilePath, 'r+');
32+
const stats = fs.fstatSync(fd);
33+
const uid = stats.uid;
34+
const gid = stats.gid;
35+
36+
fs.fchownSync(fd, -1, -1);
37+
const statsAfter = fs.fstatSync(fd);
38+
assert.strictEqual(statsAfter.uid, uid);
39+
assert.strictEqual(statsAfter.gid, gid);
40+
41+
fs.closeSync(fd);
42+
}
Lines changed: 34 additions & 0 deletions

0 commit comments

Comments
 (0)