fix(ingestion): close the PR #156 review findings on raw/ reads
- Reverting the ingest call sites to extract.Text(path) stayed green; a test now fails if anything outside internal/extract calls extract.Text( (only TextIn, through an os.Root, may be used). - The watcher symlink test passed for a watcher that ingested nothing, or stopped at the first symlink (SkipAll: one synced link halting all ingestion). It now plants a real note after the symlink and asserts exactly one ingest, and the symlinked-raw refusal has its own test. - A FIFO swapped in between Lstat and Open hung open(2) forever. extract.OpenRegular opens non-blocking and checks the type on the handle; readRawNote, TextIn and the watcher's archive copy use it. - The symlinked-root test covers pending, promote, reject, resolve and ReadIngestFile, and is named for exactly those. - The hard-link residual is documented where it is accepted. Out of scope, filed: #157 (symlinks elsewhere in the Syncthing-shared brain dir reach search and other readers), #158 (writes under raw/ follow symlinks). Refs #153 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package extract
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// PR #156 review: putting extract.Text(path) back at the ingest call sites
|
||||
// stayed green, because only TextIn itself was tested. Reading a caller-chosen
|
||||
// path by name reopens it after the containment check (hyperguild#153 item 3),
|
||||
// so outside this package only TextIn may be used.
|
||||
func TestNothingOutsideExtractCallsTextByPath(t *testing.T) {
|
||||
root := filepath.Join("..", "..")
|
||||
var offenders []string
|
||||
err := filepath.WalkDir(root, func(p string, d os.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() && (d.Name() == "vendor" || d.Name() == ".git") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if d.IsDir() || !strings.HasSuffix(p, ".go") || strings.HasSuffix(p, "_test.go") ||
|
||||
strings.Contains(filepath.ToSlash(p), "internal/extract/") {
|
||||
return nil
|
||||
}
|
||||
b, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(string(b), "extract.Text(") {
|
||||
offenders = append(offenders, p)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(offenders) > 0 {
|
||||
t.Fatalf("extract.Text( called outside internal/extract (use TextIn through an os.Root): %v", offenders)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user