Skip to content

Commit 87dae20

Browse files
Copilotstreamich
andcommitted
Initial analysis of copyFile readonly issue
Co-authored-by: streamich <9773803+streamich@users.noreply.github.com>
1 parent 064037f commit 87dae20

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { create } from '../../../__tests__/util';
2+
3+
describe('copyFile readonly source file issue', () => {
4+
it('copyFileSync on readonly source file should be allowed', () => {
5+
// Arrange
6+
const vol = create({
7+
'/path/to/file.txt': 'some text',
8+
});
9+
10+
vol.chmodSync('/path/to/file.txt', 0o400); // Readonly
11+
12+
// Act - this should NOT throw
13+
vol.copyFileSync('/path/to/file.txt', '/path/to/another.txt');
14+
15+
// Assert
16+
expect(vol.readFileSync('/path/to/file.txt', 'utf8')).toBe('some text');
17+
expect(vol.readFileSync('/path/to/another.txt', 'utf8')).toBe('some text');
18+
});
19+
20+
it('copyFile on readonly source file should be allowed', done => {
21+
// Arrange
22+
const vol = create({
23+
'/path/to/file.txt': 'some text',
24+
});
25+
26+
vol.chmodSync('/path/to/file.txt', 0o400); // Readonly
27+
28+
// Act - this should NOT throw
29+
vol.copyFile('/path/to/file.txt', '/path/to/another.txt', err => {
30+
try {
31+
expect(err).toBeNull();
32+
expect(vol.readFileSync('/path/to/file.txt', 'utf8')).toBe('some text');
33+
expect(vol.readFileSync('/path/to/another.txt', 'utf8')).toBe('some text');
34+
done();
35+
} catch (failure) {
36+
done(failure);
37+
}
38+
});
39+
});
40+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { create } from '../../../__tests__/util';
2+
3+
describe('permission debugging', () => {
4+
it('debug permission check for readonly file', () => {
5+
// Arrange
6+
const vol = create({
7+
'/test.txt': 'content',
8+
});
9+
10+
console.log('Initial file stats:', vol.statSync('/test.txt'));
11+
console.log('Initial file mode:', vol.statSync('/test.txt').mode.toString(8));
12+
13+
vol.chmodSync('/test.txt', 0o400);
14+
15+
console.log('After chmod 0o400 stats:', vol.statSync('/test.txt'));
16+
console.log('After chmod mode:', vol.statSync('/test.txt').mode.toString(8));
17+
console.log('Perm bits:', (vol.statSync('/test.txt').mode & ~0o170000).toString(8));
18+
19+
// Try to see what process uid/gid are
20+
console.log('Process getuid:', process.getuid ? process.getuid() : 'undefined');
21+
console.log('Process getgid:', process.getgid ? process.getgid() : 'undefined');
22+
23+
// Let's see the internal node
24+
const core = (vol as any)._core;
25+
const linkOrNode = core.getLink ? core.getLink('/test.txt') : core.root.getChild('test.txt');
26+
const node = linkOrNode.getNode ? linkOrNode.getNode() : linkOrNode.node;
27+
console.log('Node uid:', node.uid);
28+
console.log('Node gid:', node.gid);
29+
console.log('Node perm:', node.perm.toString(8));
30+
console.log('Node.canRead():', node.canRead());
31+
console.log('Node.canWrite():', node.canWrite());
32+
33+
// This should not throw
34+
expect(() => vol.readFileSync('/test.txt')).not.toThrow();
35+
});
36+
});

0 commit comments

Comments
 (0)