Skip to content

Commit e52fc43

Browse files
Address review feedback
Change-Id: Ib6a8fb2f9b20dbff5f24b18cc5a217d95066a98f
1 parent 331ab1f commit e52fc43

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

src/encoding/asn1/marshal.go

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -80,26 +80,6 @@ func (m multiEncoder) Encode(dst []byte) {
8080
}
8181
}
8282

83-
type octetSorter [][]byte
84-
85-
func (s octetSorter) Len() int {
86-
return len(s)
87-
}
88-
89-
func (s octetSorter) Swap(i, j int) {
90-
s[i], s[j] = s[j], s[i]
91-
}
92-
93-
func (s octetSorter) Less(i, j int) bool {
94-
// Since we are using bytes.Compare to compare TLV encodings we
95-
// don't need to right pad s[i] and s[j] to the same length as
96-
// suggested in X690. If len(s[i]) < len(s[j]) the length octet of
97-
// s[i], which is the first determining byte, will inherently be
98-
// smaller than the length octet of s[j]. This lets us skip the
99-
// padding step.
100-
return bytes.Compare(s[i], s[j]) < 0
101-
}
102-
10383
type setEncoder []encoder
10484

10585
func (s setEncoder) Len() int {
@@ -125,7 +105,15 @@ func (s setEncoder) Encode(dst []byte) {
125105
e.Encode(l[i])
126106
}
127107

128-
sort.Sort(octetSorter(l))
108+
sort.Slice(l, func(i, j int) bool {
109+
// Since we are using bytes.Compare to compare TLV encodings we
110+
// don't need to right pad s[i] and s[j] to the same length as
111+
// suggested in X690. If len(s[i]) < len(s[j]) the length octet of
112+
// s[i], which is the first determining byte, will inherently be
113+
// smaller than the length octet of s[j]. This lets us skip the
114+
// padding step.
115+
return bytes.Compare(l[i], l[j]) < 0
116+
})
129117

130118
var off int
131119
for _, b := range l {
@@ -677,6 +665,15 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
677665
tag = TagSet
678666
}
679667

668+
// makeField can be called for a slice that should be treated as a SET
669+
// but doesn't have params.set set, for instance when using a slice
670+
// with the SET type name suffix. In this case getUniversalType returns
671+
// TagSet, but makeBody doesn't know about that so will treat the slice
672+
// as a sequence. To work around this we set params.set.
673+
if tag == TagSet && !params.set {
674+
params.set = true
675+
}
676+
680677
t := new(taggedEncoder)
681678

682679
t.body, err = makeBody(v, params)

src/encoding/asn1/marshal_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,32 @@ func TestSetEncoder(t *testing.T) {
347347
t.Error("Unmarshal returned extra garbage")
348348
}
349349
if !reflect.DeepEqual(expectedOrder, resultStruct.Strings) {
350-
t.Errorf("Unexpected SET content. got: %s, want: %s", resultStruct.Strings, resultStruct.Strings)
350+
t.Errorf("Unexpected SET content. got: %s, want: %s", resultStruct.Strings, expectedOrder)
351+
}
352+
}
353+
354+
func TestSetEncoderSETSliceSuffix(t *testing.T) {
355+
type testSetSET []string
356+
testSet := testSetSET{"a", "aa", "b", "bb", "c", "cc"}
357+
358+
// Expected ordering of the SET should be:
359+
// a, b, c, aa, bb, cc
360+
361+
output, err := Marshal(testSet)
362+
if err != nil {
363+
t.Errorf("%v", err)
364+
}
365+
366+
expectedOrder := testSetSET{"a", "b", "c", "aa", "bb", "cc"}
367+
var resultSet testSetSET
368+
rest, err := Unmarshal(output, &resultSet)
369+
if err != nil {
370+
t.Errorf("%v", err)
371+
}
372+
if len(rest) != 0 {
373+
t.Error("Unmarshal returned extra garbage")
374+
}
375+
if !reflect.DeepEqual(expectedOrder, resultSet) {
376+
t.Errorf("Unexpected SET content. got: %s, want: %s", resultSet, expectedOrder)
351377
}
352378
}

0 commit comments

Comments
 (0)