From 676ac131e1f26caf2419d35e14d4cf63811d6544 Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Tue, 17 Dec 2013 12:14:27 +0400 Subject: [PATCH] dashboard/app: properly limit commit description length Ensure that we do not split UTF-8 rune in half. Otherwise appengine python scripts will break badly. R=adg, r CC=golang-dev https://golang.org/cl/42530043 --- dashboard/app/build/handler.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/dashboard/app/build/handler.go b/dashboard/app/build/handler.go index a6da710ab..347819b39 100644 --- a/dashboard/app/build/handler.go +++ b/dashboard/app/build/handler.go @@ -14,6 +14,7 @@ import ( "fmt" "net/http" "strings" + "unicode/utf8" "appengine" "appengine/datastore" @@ -57,9 +58,7 @@ func commitHandler(r *http.Request) (interface{}, error) { if err := json.NewDecoder(r.Body).Decode(com); err != nil { return nil, fmt.Errorf("decoding Body: %v", err) } - if len(com.Desc) > maxDatastoreStringLen { - com.Desc = com.Desc[:maxDatastoreStringLen] - } + com.Desc = limitStringLength(com.Desc, maxDatastoreStringLen) if err := com.Valid(); err != nil { return nil, fmt.Errorf("validating Commit: %v", err) } @@ -459,3 +458,20 @@ func logErr(w http.ResponseWriter, r *http.Request, err error) { func contextForRequest(r *http.Request) appengine.Context { return dashboardForRequest(r).Context(appengine.NewContext(r)) } + +// limitStringLength essentially does return s[:max], +// but it ensures that we dot not split UTF-8 rune in half. +// Otherwise appengine python scripts will break badly. +func limitStringLength(s string, max int) string { + if len(s) <= max { + return s + } + for { + s = s[:max] + r, size := utf8.DecodeLastRuneInString(s) + if r != utf8.RuneError || size != 1 { + return s + } + max-- + } +}