Harden sessions, uploads, admin demotion, and HTTP timeouts.
Address PR review findings: renew session tokens on auth, sniff/re-encode avatars, serialize last-admin checks, bound server timeouts, rune-safe truncation, and TEST_DATABASE_URL-only integration tests.
This commit is contained in:
+19
-4
@@ -311,13 +311,13 @@ func (s *Server) handleSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
if len(title) > 120 {
|
||||
title = title[:120]
|
||||
title = truncateRunes(title, 120)
|
||||
}
|
||||
if len(body) > 8000 {
|
||||
body = body[:8000]
|
||||
body = truncateRunes(body, 8000)
|
||||
}
|
||||
if len(city) > 80 {
|
||||
city = city[:80]
|
||||
city = truncateRunes(city, 80)
|
||||
}
|
||||
q := store.NewQuestion(s.db)
|
||||
q.AuthorID = u.ID
|
||||
@@ -449,7 +449,7 @@ func (s *Server) handleAnswer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
if len(body) > 12000 {
|
||||
body = body[:12000]
|
||||
body = truncateRunes(body, 12000)
|
||||
}
|
||||
ans := store.NewAnswer(s.db)
|
||||
ans.QuestionID = id
|
||||
@@ -518,6 +518,21 @@ func (s *Server) exec(w http.ResponseWriter, name string, data any) {
|
||||
}
|
||||
}
|
||||
|
||||
// truncateRunes shortens s to at most max runes without splitting a code point.
|
||||
func truncateRunes(s string, max int) string {
|
||||
if max <= 0 {
|
||||
return ""
|
||||
}
|
||||
n := 0
|
||||
for byteIdx := range s {
|
||||
if n == max {
|
||||
return s[:byteIdx]
|
||||
}
|
||||
n++
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func randomHex(n int) string {
|
||||
b := make([]byte, n)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user