@@ -6,6 +6,9 @@ import { Volume, filenameToSteps, StatWatcher } from '../volume';
6
6
import hasBigInt from './hasBigInt' ;
7
7
import { tryGetChild , tryGetChildNode } from './util' ;
8
8
import { genRndStr6 } from '../node/util' ;
9
+ import { constants } from '../constants' ;
10
+
11
+ const { O_RDWR , O_SYMLINK } = constants ;
9
12
10
13
describe ( 'volume' , ( ) => {
11
14
describe ( 'filenameToSteps(filename): string[]' , ( ) => {
@@ -484,13 +487,26 @@ describe('volume', () => {
484
487
} ) ;
485
488
} ) ;
486
489
describe ( '.read(fd, buffer, offset, length, position, callback)' , ( ) => {
487
- xit ( '...' , ( ) => { } ) ;
490
+ const vol = new Volume ( ) ;
491
+ const data = 'trololo' ;
492
+ const fileNode = ( vol as any ) . createLink ( vol . root , 'text.txt' ) . getNode ( ) ;
493
+ fileNode . setString ( data ) ;
494
+ vol . symlinkSync ( '/text.txt' , '/link.txt' ) ;
495
+
496
+ it ( 'Attempt to read from a symlink should throw EPERM' , ( ) => {
497
+ const fd = vol . openSync ( '/link.txt' , O_SYMLINK ) ;
498
+ expect ( vol . fstatSync ( fd ) . isSymbolicLink ( ) ) . toBe ( true ) ;
499
+ const buf = Buffer . alloc ( 10 ) ;
500
+ const fn = ( ) => vol . readSync ( fd , buf , 0 , 10 , 0 ) ;
501
+ expect ( fn ) . toThrowError ( 'EPERM' ) ;
502
+ } ) ;
488
503
} ) ;
489
504
describe ( '.readFileSync(path[, options])' , ( ) => {
490
505
const vol = new Volume ( ) ;
491
506
const data = 'trololo' ;
492
507
const fileNode = ( vol as any ) . createLink ( vol . root , 'text.txt' ) . getNode ( ) ;
493
508
fileNode . setString ( data ) ;
509
+
494
510
it ( 'Read file at root (/text.txt)' , ( ) => {
495
511
const buf = vol . readFileSync ( '/text.txt' ) ;
496
512
const str = buf . toString ( ) ;
@@ -584,6 +600,16 @@ describe('volume', () => {
584
600
vol . closeSync ( fd ) ;
585
601
expect ( vol . readFileSync ( '/overwrite.txt' , 'utf8' ) ) . toBe ( 'mArmagedon' ) ;
586
602
} ) ;
603
+ it ( 'Attempt to write to a symlink should throw EBADF' , ( ) => {
604
+ const data = 'asdfasdf asdfasdf asdf' ;
605
+ vol . writeFileSync ( '/file.txt' , data ) ;
606
+ vol . symlinkSync ( '/file.txt' , '/link.txt' ) ;
607
+
608
+ const fd = vol . openSync ( '/link.txt' , O_SYMLINK | O_RDWR ) ;
609
+ expect ( vol . fstatSync ( fd ) . isSymbolicLink ( ) ) . toBe ( true ) ;
610
+ const fn = ( ) => vol . writeSync ( fd , 'hello' ) ;
611
+ expect ( fn ) . toThrowError ( 'EBADF' ) ;
612
+ } ) ;
587
613
} ) ;
588
614
describe ( '.write(fd, buffer, offset, length, position, callback)' , ( ) => {
589
615
it ( 'Simple write to a file descriptor' , done => {
@@ -834,6 +860,8 @@ describe('volume', () => {
834
860
const data = '(function(){})();' ;
835
861
dojo . getNode ( ) . setString ( data ) ;
836
862
863
+ vol . symlinkSync ( '/dojo.js' , '/link.js' ) ;
864
+
837
865
it ( 'Returns basic file stats' , ( ) => {
838
866
const fd = vol . openSync ( '/dojo.js' , 'r' ) ;
839
867
const stats = vol . fstatSync ( fd ) ;
@@ -855,6 +883,21 @@ describe('volume', () => {
855
883
expect ( ( ) => vol . fstatSync ( fd , { bigint : true } ) ) . toThrowError ( ) ;
856
884
}
857
885
} ) ;
886
+ it ( 'Returns stats about regular file for fd opened without O_SYMLINK' , ( ) => {
887
+ const fd = vol . openSync ( '/link.js' , 0 ) ;
888
+ const stats = vol . fstatSync ( fd ) ;
889
+ expect ( stats ) . toBeInstanceOf ( Stats ) ;
890
+ expect ( stats . size ) . toBe ( data . length ) ;
891
+ expect ( stats . isFile ( ) ) . toBe ( true ) ;
892
+ expect ( stats . isDirectory ( ) ) . toBe ( false ) ;
893
+ } ) ;
894
+ it ( 'Returns stats about symlink itself for fd opened with O_SYMLINK' , ( ) => {
895
+ const fd = vol . openSync ( '/link.js' , O_SYMLINK ) ;
896
+ const stats = vol . fstatSync ( fd ) ;
897
+ expect ( stats . isSymbolicLink ( ) ) . toBe ( true ) ;
898
+ expect ( stats . isFile ( ) ) . toBe ( false ) ;
899
+ expect ( stats . size ) . toBe ( 0 ) ;
900
+ } ) ;
858
901
} ) ;
859
902
describe ( '.fstat(fd, callback)' , ( ) => {
860
903
xit ( '...' , ( ) => { } ) ;
0 commit comments