diff --git a/internal/web/uploads_badinput_handler_test.go b/internal/web/uploads_badinput_handler_test.go index 83ec4c4..cb338f7 100644 --- a/internal/web/uploads_badinput_handler_test.go +++ b/internal/web/uploads_badinput_handler_test.go @@ -2,6 +2,7 @@ package web_test import ( "context" + "log/slog" "net/http" "testing" @@ -27,7 +28,6 @@ func TestUploadPost_ATitleWithControlCharactersOrInvalidUTF8IsCleanedNotA500(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 { @@ -46,3 +46,17 @@ func TestUploadPost_ATitleWithControlCharactersOrInvalidUTF8IsCleanedNotA500(t * }) } } + +func TestUploadPost_AMalformedMultipartHeaderIsA400AndItsTextIsNotLogged(t *testing.T) { + // A control byte in the part's file name makes the multipart body malformed. It is the + // sender's to fix, and the parser's error quotes the header, which carries the name. + app, sub := newUploadApp(t, audioOK, 200<<20) + buf := &lockedBuf{} + app.Log = slog.New(slog.NewTextHandler(buf, nil)) + + rec := do(t, app, uploadReq(t, "", "zebrakaka\x00weekly.m4a", []byte("x"))) + + assert.Equal(t, http.StatusBadRequest, rec.Code) + assert.Empty(t, sub.jobs) + assert.NotContains(t, buf.String(), "zebrakaka", "a file name is private content") +}