diff --git a/internal/web/uploads_badinput_handler_test.go b/internal/web/uploads_badinput_handler_test.go new file mode 100644 index 0000000..83ec4c4 --- /dev/null +++ b/internal/web/uploads_badinput_handler_test.go @@ -0,0 +1,48 @@ +package web_test + +import ( + "context" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// Input that cannot be right is the caller's to fix: a 4xx, never a 500 (adversarial +// review F7). No cross-tenant oracle either way: unknown and foreign ids look the same. + +func TestUploadRoutes_ANonUUIDIdIs404NotA500(t *testing.T) { + app, _ := newUploadApp(t, audioOK, 200<<20) + for _, path := range []string{"/uploads/not-a-uuid", "/uploads/not-a-uuid/status", "/uploads/not-a-uuid/chat", "/uploads/%00/status", "/uploads/1/status"} { + t.Run(path, func(t *testing.T) { + rec := do(t, app, get(path)) + + assert.Equal(t, http.StatusNotFound, rec.Code) + }) + } +} + +func TestUploadPost_ATitleWithControlCharactersOrInvalidUTF8IsCleanedNotA500(t *testing.T) { + tests := []struct{ name, title, filename string }{ + {"a NUL in the title", "Sprint\x00review", "a.m4a"}, + {"invalid UTF-8 in the title", "Sprint \xff\xfe review", "a.m4a"}, + {"a NUL in the file name, used as the title", "", "weekly\x00sync.m4a"}, + {"a newline in the title", "Sprint\nreview", "a.m4a"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + app, sub := newUploadApp(t, audioOK, 200<<20) + + rec := do(t, app, uploadReq(t, tt.title, tt.filename, []byte("synthetic audio bytes"))) + + require.Equal(t, http.StatusSeeOther, rec.Code, "bad bytes in a cosmetic title must not fail the upload: %s", body(t, rec)) + require.Len(t, sub.jobs, 1) + var title string + require.NoError(t, rawPool(t).QueryRow(context.Background(), `SELECT title FROM uploaded_transcripts WHERE id = $1`, sub.jobs[0].UploadID).Scan(&title)) + assert.NotContains(t, title, "\x00") + assert.NotContains(t, title, "\n") + assert.True(t, len(title) > 0, "a title is still shown") + }) + } +}