@@ -1269,8 +1269,8 @@ func TestRunInit_Add_UnknownPack_ExitsTwo(t *testing.T) {
12691269func TestRunInit_Add_ScaffoldError (t * testing.T ) {
12701270 dir := t .TempDir ()
12711271 t .Chdir (dir )
1272- // .mdsmith is a regular file, so the pack's MkdirAll fails and runInit
1273- // must surface it as exit 2.
1272+ // .mdsmith is a regular file, so the pack's parent-directory checks
1273+ // fail and runInit must surface the scaffold error as exit 2.
12741274 require .NoError (t , os .WriteFile (".mdsmith" , []byte ("x" ), 0o644 ))
12751275
12761276 captureStderr (func () {
@@ -1344,14 +1344,18 @@ func TestWriteScaffolds_WritesAndSkips(t *testing.T) {
13441344func TestWriteScaffolds_MkdirError (t * testing.T ) {
13451345 dir := t .TempDir ()
13461346 t .Chdir (dir )
1347- // .mdsmith is a regular file, so MkdirAll(.mdsmith/wordlists) fails
1348- // with ENOTDIR — driving the directory-creation error branch.
1349- require .NoError (t , os .WriteFile (".mdsmith" , []byte ("x" ), 0o644 ))
1347+ // .mdsmith is a real directory, but .mdsmith/wordlists is a regular
1348+ // file. The parent chain has no symlink, so refuseSymlinkedParents
1349+ // passes and MkdirAll(.mdsmith/wordlists) then fails because the target
1350+ // already exists as a file — driving the directory-creation error
1351+ // branch.
1352+ require .NoError (t , os .Mkdir (".mdsmith" , 0o755 ))
1353+ require .NoError (t , os .WriteFile (filepath .Join (".mdsmith" , "wordlists" ), []byte ("x" ), 0o644 ))
13501354
13511355 files := []pack.File {{Path : filepath .Join (".mdsmith" , "wordlists" , "a.yaml" ), Data : []byte ("entries:\n - x\n " )}}
13521356 err := writeScaffolds (files , io .Discard )
13531357 require .Error (t , err )
1354- assert .Contains (t , err .Error (), filepath .Join (".mdsmith" , "wordlists" ))
1358+ assert .Contains (t , err .Error (), "creating " + filepath .Join (".mdsmith" , "wordlists" ))
13551359}
13561360
13571361func TestWriteScaffolds_RefusesSymlink (t * testing.T ) {
@@ -1482,6 +1486,53 @@ func TestWriteScaffolds_RefusesSymlinkedMdsmithDir(t *testing.T) {
14821486 assert .True (t , os .IsNotExist (statErr ), "nothing written through the symlinked .mdsmith" )
14831487}
14841488
1489+ func TestWriteScaffolds_RefusesSymlinkedIntermediateDir (t * testing.T ) {
1490+ dir := t .TempDir ()
1491+ t .Chdir (dir )
1492+ require .NoError (t , os .Mkdir (".mdsmith" , 0o755 ))
1493+ target := filepath .Join (dir , "elsewhere" )
1494+ require .NoError (t , os .Mkdir (target , 0o755 ))
1495+ // .mdsmith is a real directory, but an intermediate component
1496+ // (.mdsmith/wordlists) is a symlink out of tree. The write must still
1497+ // be refused rather than following it.
1498+ require .NoError (t , os .Symlink (target , filepath .Join (".mdsmith" , "wordlists" )))
1499+
1500+ files := []pack.File {{Path : filepath .Join (".mdsmith" , "wordlists" , "a.yaml" ), Data : []byte ("x" )}}
1501+ err := writeScaffolds (files , io .Discard )
1502+ require .Error (t , err )
1503+ assert .Contains (t , err .Error (), "symlink" )
1504+ _ , statErr := os .Stat (filepath .Join (target , "a.yaml" ))
1505+ assert .True (t , os .IsNotExist (statErr ), "nothing written through the intermediate symlink" )
1506+ }
1507+
1508+ func TestRefuseSymlinkedParents (t * testing.T ) {
1509+ dir := t .TempDir ()
1510+ t .Chdir (dir )
1511+
1512+ // A path whose parent is the cwd (dir == ".") has nothing to check.
1513+ require .NoError (t , refuseSymlinkedParents ("a.yaml" ))
1514+
1515+ // Parents that don't exist yet are fine — MkdirAll makes them real.
1516+ require .NoError (t , refuseSymlinkedParents (filepath .Join (".mdsmith" , "wordlists" , "a.yaml" )))
1517+
1518+ // A fully real parent chain passes.
1519+ require .NoError (t , os .MkdirAll (filepath .Join (".mdsmith" , "wordlists" ), 0o755 ))
1520+ require .NoError (t , refuseSymlinkedParents (filepath .Join (".mdsmith" , "wordlists" , "a.yaml" )))
1521+
1522+ // A symlinked component is refused.
1523+ require .NoError (t , os .Symlink (dir , filepath .Join (".mdsmith" , "link" )))
1524+ err := refuseSymlinkedParents (filepath .Join (".mdsmith" , "link" , "a.yaml" ))
1525+ require .Error (t , err )
1526+ assert .Contains (t , err .Error (), "symlink" )
1527+
1528+ // A non-ENOENT lstat error — a component is a file, so ENOTDIR — is
1529+ // surfaced as a checking error.
1530+ require .NoError (t , os .WriteFile (filepath .Join (".mdsmith" , "afile" ), []byte ("x" ), 0o644 ))
1531+ err = refuseSymlinkedParents (filepath .Join (".mdsmith" , "afile" , "child" , "a.yaml" ))
1532+ require .Error (t , err )
1533+ assert .Contains (t , err .Error (), "checking" )
1534+ }
1535+
14851536// --- runHelp ---
14861537
14871538func TestRunHelp_NoArgs_ExitsZero (t * testing.T ) {
0 commit comments