@@ -190,7 +190,7 @@ test("the executable exists and is a (sym)link", (t) => {
190190 t . context . deps . which . returns ( resolvedExecutable ) ;
191191
192192 t . context . deps . readlink . onCall ( 0 ) . returns ( linkedExecutable ) ;
193- t . context . deps . readlink . onCall ( 1 ) . throws ( linkedExecutable ) ;
193+ t . context . deps . readlink . onCall ( 1 ) . throws ( ) ;
194194
195195 const result = resolveExecutable ( args , t . context . deps ) ;
196196 t . is ( result , linkedExecutable ) ;
@@ -224,3 +224,26 @@ test("the executable exists and is a (sym)link to a (sym)link", (t) => {
224224 t . is ( t . context . deps . which . callCount , 1 ) ;
225225 t . is ( t . context . deps . exists . callCount , 1 ) ;
226226} ) ;
227+
228+ testProp (
229+ "the executable exists but there is a link cycle" ,
230+ [ fc . array ( fc . string ( { minLength : 3 } ) , { minLength : 3 , maxLength : 64 } ) ] ,
231+ ( t , links ) => {
232+ const { env, executable, resolvedExecutable } = t . context ;
233+ const args = { env, executable } ;
234+
235+ t . context . deps . exists . returns ( true ) ;
236+ t . context . deps . which . returns ( resolvedExecutable ) ;
237+
238+ t . context . deps . readlink = sinon . stub ( ) ;
239+ for ( const index in links ) {
240+ t . context . deps . readlink . onCall ( index ) . returns ( links [ index ] ) ;
241+ }
242+ t . context . deps . readlink . onCall ( links . length ) . returns ( links [ 0 ] ) ;
243+
244+ t . throws ( ( ) => resolveExecutable ( args , t . context . deps ) , {
245+ instanceOf : Error ,
246+ message : `${ executable } points to a link loop, cannot resolve shell` ,
247+ } ) ;
248+ } ,
249+ ) ;
0 commit comments