package main // The disk map page: the layout, the drawing, and the four properties the page // is not allowed to lose — no inline style, no unescaped filename, no poll that // walks a disk, and nothing rendered for a path this machine never scanned. import ( "context" "encoding/xml" "fmt" "html" "io" "math" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" "regexp" "runtime" "strings" "testing" "time" ) // dmTestInstall swaps the machine-wide map for one the test controls, so no // test ever walks the disk of whoever is running it. func dmTestInstall(t *testing.T, res *dmResult) *dmState { t.Helper() old := diskMap s := &dmState{ res: res, scan: dmScan, roots: func(dmScope) ([]string, []string) { return nil, nil }, } diskMap = s t.Cleanup(func() { diskMap = old }) return s } // dmBigTree writes a tree with enough in it to draw a real picture: a few // heavy files, a long tail of small ones, and several types. func dmBigTree(t *testing.T) string { t.Helper() root := t.TempDir() write := func(rel string, n int) { p := filepath.Join(root, filepath.FromSlash(rel)) if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(p, make([]byte, n), 0o644); err != nil { t.Fatal(err) } } write("Videos/holiday.mp4", 900000) write("Videos/wedding.mov", 400000) write("Models/qwen.gguf", 600000) write("Photos/a.jpg", 30000) write("Photos/b.jpg", 25000) write("Photos/c.png", 18000) write("Docs/report.pdf", 40000) write("Docs/notes.md", 900) write("code/main.go", 1200) write("code/vendor/dep.go", 700) for i := 0; i < 200; i++ { write(fmt.Sprintf("cache/tiny/%d.tmp", i), 40) } return root } func dmRender(t *testing.T, u *uiServer, cookie, path string) string { t.Helper() target := "/diskmap" if path != "" { target += "?p=" + url.QueryEscape(path) } r := uiReq(http.MethodGet, target) r.Header.Set("Cookie", cookie) w := httptest.NewRecorder() u.handler().ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("GET %s = %d: %s", target, w.Code, w.Body.String()) } return w.Body.String() } // ── the CSP property the whole design turns on ────────────────────────────── // TestTheMapNeverEmitsInlineStyle is the assertion behind uidiskmap.go's // header. The page's CSP is `default-src 'self'` with no 'unsafe-inline' // (ui.go renderWith), so an inline style silently does nothing — app.css:169 // records the last time that happened here. A treemap is the single most // natural thing in this codebase to write as inline styles, so the ban has to // be mechanical. func TestTheMapNeverEmitsInlineStyle(t *testing.T) { uiTestConfigDir(t) dmTestInstall(t, dmScanTree(t, dmBigTree(t))) u := uiTestServer(t) body := dmRender(t, u, uiSignedIn(t, u), "") if !strings.Contains(body, "`, and a `/` cannot be in a filename on any filesystem, so // os.WriteFile failed and the test t.Skip'd — silently, and it would have // skipped just as silently with dmEsc replaced by the identity function. The // names below use only characters a real file can actually carry, and the // fixture failing is now a FATAL rather than a skip anywhere but Windows. func TestAFilenameCannotInjectMarkupIntoTheMap(t *testing.T) { root := t.TempDir() names := []string{ `