package extract import ( "os" "path/filepath" "syscall" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // hyperguild#153 item 3: ingest checked a path, then extract.Text reopened it // by name, so a file swapped for a symlink in between was followed out of // raw/. TextIn reads through an os.Root, which refuses to leave the root. func TestTextInReadsInsideTheRootAndRefusesEscapes(t *testing.T) { root := t.TempDir() require.NoError(t, os.WriteFile(filepath.Join(root, "ok.md"), []byte("inside"), 0o644)) outside := filepath.Join(t.TempDir(), "secret.md") require.NoError(t, os.WriteFile(outside, []byte("SENTINEL-153-TEXTIN"), 0o644)) require.NoError(t, os.Symlink(outside, filepath.Join(root, "leak.md"))) r, err := os.OpenRoot(root) require.NoError(t, err) defer func() { _ = r.Close() }() got, err := TextIn(r, "ok.md") require.NoError(t, err) assert.Equal(t, "inside", got) got, err = TextIn(r, "leak.md") assert.Error(t, err) assert.NotContains(t, got, "SENTINEL-153-TEXTIN") _, err = TextIn(r, "../"+filepath.Base(outside)) assert.Error(t, err) } // PR #156 review: a regular file swapped for a FIFO between Lstat and Open // blocked open(2) forever. OpenRegular opens non-blocking and checks the type // on the opened handle, so a FIFO is refused promptly instead of hanging. func TestOpenRegularRefusesAFIFOWithoutBlocking(t *testing.T) { dir := t.TempDir() require.NoError(t, syscall.Mkfifo(filepath.Join(dir, "pipe.md"), 0o644)) r, err := os.OpenRoot(dir) require.NoError(t, err) defer func() { _ = r.Close() }() done := make(chan error, 1) go func() { f, _, err := OpenRegular(r, "pipe.md") if f != nil { _ = f.Close() } done <- err }() select { case err := <-done: assert.Error(t, err) case <-time.After(2 * time.Second): t.Fatal("OpenRegular blocked on a FIFO") } }