]> Cypherpunks repositories - gostls13.git/commitdiff
net/url: sort keys in Encode; don't enumerate map randomly
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 18 Jun 2012 19:54:36 +0000 (12:54 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 18 Jun 2012 19:54:36 +0000 (12:54 -0700)
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/6303098

src/pkg/net/url/url.go
src/pkg/net/url/url_test.go

index 17bf0d3a342f394b3db0b9921251829aa9c1423c..7b9289468bf482b772462627526df08bc246adbc 100644 (file)
@@ -7,7 +7,9 @@
 package url
 
 import (
+       "bytes"
        "errors"
+       "sort"
        "strconv"
        "strings"
 )
@@ -538,14 +540,24 @@ func (v Values) Encode() string {
        if v == nil {
                return ""
        }
-       parts := make([]string, 0, len(v)) // will be large enough for most uses
-       for k, vs := range v {
+       var buf bytes.Buffer
+       keys := make([]string, 0, len(v))
+       for k := range v {
+               keys = append(keys, k)
+       }
+       sort.Strings(keys)
+       for _, k := range keys {
+               vs := v[k]
                prefix := QueryEscape(k) + "="
                for _, v := range vs {
-                       parts = append(parts, prefix+QueryEscape(v))
+                       if buf.Len() > 0 {
+                               buf.WriteByte('&')
+                       }
+                       buf.WriteString(prefix)
+                       buf.WriteString(QueryEscape(v))
                }
        }
-       return strings.Join(parts, "&")
+       return buf.String()
 }
 
 // resolvePath applies special path segments from refs and applies
index 75e8abe4eb3ff74a099d77f960e1a9b2b6a32fc8..9ea8d7ecd120671efce724b45b49d1b04e917694 100644 (file)
@@ -453,20 +453,24 @@ func TestEscape(t *testing.T) {
 //}
 
 type EncodeQueryTest struct {
-       m         Values
-       expected  string
-       expected1 string
+       m        Values
+       expected string
 }
 
 var encodeQueryTests = []EncodeQueryTest{
-       {nil, "", ""},
-       {Values{"q": {"puppies"}, "oe": {"utf8"}}, "q=puppies&oe=utf8", "oe=utf8&q=puppies"},
-       {Values{"q": {"dogs", "&", "7"}}, "q=dogs&q=%26&q=7", "q=dogs&q=%26&q=7"},
+       {nil, ""},
+       {Values{"q": {"puppies"}, "oe": {"utf8"}}, "oe=utf8&q=puppies"},
+       {Values{"q": {"dogs", "&", "7"}}, "q=dogs&q=%26&q=7"},
+       {Values{
+               "a": {"a1", "a2", "a3"},
+               "b": {"b1", "b2", "b3"},
+               "c": {"c1", "c2", "c3"},
+       }, "a=a1&a=a2&a=a3&b=b1&b=b2&b=b3&c=c1&c=c2&c=c3"},
 }
 
 func TestEncodeQuery(t *testing.T) {
        for _, tt := range encodeQueryTests {
-               if q := tt.m.Encode(); q != tt.expected && q != tt.expected1 {
+               if q := tt.m.Encode(); q != tt.expected {
                        t.Errorf(`EncodeQuery(%+v) = %q, want %q`, tt.m, q, tt.expected)
                }
        }