Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(621)

Side by Side Diff: src/pkg/encoding/asn1/marshal.go

Issue 6348074: code review 6348074: encoding/asn1: promote untyped strings to UTF8 as needed. (Closed)
Patch Set: diff -r 8241ffc8686e https://code.google.com/p/go/ Created 12 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/encoding/asn1/common.go ('k') | src/pkg/encoding/asn1/marshal_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package asn1 5 package asn1
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "errors"
9 "fmt" 10 "fmt"
10 "io" 11 "io"
11 "math/big" 12 "math/big"
12 "reflect" 13 "reflect"
13 "time" 14 "time"
15 "unicode/utf8"
14 ) 16 )
15 17
16 // A forkableWriter is an in-memory buffer that can be 18 // A forkableWriter is an in-memory buffer that can be
17 // 'forked' to create new forkableWriters that bracket the 19 // 'forked' to create new forkableWriters that bracket the
18 // original. After 20 // original. After
19 // pre, post := w.fork(); 21 // pre, post := w.fork();
20 // the overall sequence of bytes represented is logically w+pre+post. 22 // the overall sequence of bytes represented is logically w+pre+post.
21 type forkableWriter struct { 23 type forkableWriter struct {
22 *bytes.Buffer 24 *bytes.Buffer
23 pre, post *forkableWriter 25 pre, post *forkableWriter
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 for _, c := range b { 275 for _, c := range b {
274 if c > 127 { 276 if c > 127 {
275 return StructuralError{"IA5String contains invalid chara cter"} 277 return StructuralError{"IA5String contains invalid chara cter"}
276 } 278 }
277 } 279 }
278 280
279 _, err = out.Write(b) 281 _, err = out.Write(b)
280 return 282 return
281 } 283 }
282 284
285 func marshalUTF8String(out *forkableWriter, s string) (err error) {
286 _, err = out.Write([]byte(s))
287 return
288 }
289
283 func marshalTwoDigits(out *forkableWriter, v int) (err error) { 290 func marshalTwoDigits(out *forkableWriter, v int) (err error) {
284 err = out.WriteByte(byte('0' + (v/10)%10)) 291 err = out.WriteByte(byte('0' + (v/10)%10))
285 if err != nil { 292 if err != nil {
286 return 293 return
287 } 294 }
288 return out.WriteByte(byte('0' + v%10)) 295 return out.WriteByte(byte('0' + v%10))
289 } 296 }
290 297
291 func marshalUTCTime(out *forkableWriter, t time.Time) (err error) { 298 func marshalUTCTime(out *forkableWriter, t time.Time) (err error) {
292 utc := t.UTC() 299 utc := t.UTC()
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 for i := 0; i < v.Len(); i++ { 446 for i := 0; i < v.Len(); i++ {
440 var pre *forkableWriter 447 var pre *forkableWriter
441 pre, out = out.fork() 448 pre, out = out.fork()
442 err = marshalField(pre, v.Index(i), params) 449 err = marshalField(pre, v.Index(i), params)
443 if err != nil { 450 if err != nil {
444 return 451 return
445 } 452 }
446 } 453 }
447 return 454 return
448 case reflect.String: 455 case reflect.String:
449 » » if params.stringType == tagIA5String { 456 » » switch params.stringType {
457 » » case tagIA5String:
450 return marshalIA5String(out, v.String()) 458 return marshalIA5String(out, v.String())
451 » » } else { 459 » » case tagPrintableString:
452 return marshalPrintableString(out, v.String()) 460 return marshalPrintableString(out, v.String())
461 default:
462 return marshalUTF8String(out, v.String())
453 } 463 }
454 return 464 return
455 } 465 }
456 466
457 return StructuralError{"unknown Go type"} 467 return StructuralError{"unknown Go type"}
458 } 468 }
459 469
460 func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err error) { 470 func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err error) {
461 // If the field is an interface{} then recurse into it. 471 // If the field is an interface{} then recurse into it.
462 if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 { 472 if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 {
(...skipping 22 matching lines...) Expand all
485 return 495 return
486 } 496 }
487 497
488 tag, isCompound, ok := getUniversalType(v.Type()) 498 tag, isCompound, ok := getUniversalType(v.Type())
489 if !ok { 499 if !ok {
490 err = StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type( ))} 500 err = StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type( ))}
491 return 501 return
492 } 502 }
493 class := classUniversal 503 class := classUniversal
494 504
495 » if params.stringType != 0 { 505 » if params.stringType != 0 && tag != tagPrintableString {
496 » » if tag != tagPrintableString { 506 » » return StructuralError{"Explicit string type given to non-string member"}
497 » » » return StructuralError{"Explicit string type given to no n-string member"} 507 » }
508
509 » if tag == tagPrintableString {
510 » » if params.stringType == 0 {
511 » » » // This is a string without an explicit string type. We' ll use
512 » » » // a PrintableString if the character set in the string is
513 » » » // sufficiently limited, otherwise we'll use a UTF8Strin g.
514 » » » for _, r := range v.String() {
515 » » » » if r >= utf8.RuneSelf || !isPrintable(byte(r)) {
516 » » » » » if !utf8.ValidString(v.String()) {
517 » » » » » » return errors.New("asn1: string not valid UTF-8")
518 » » » » » }
519 » » » » » tag = tagUTF8String
520 » » » » » break
521 » » » » }
522 » » » }
523 » » } else {
524 » » » tag = params.stringType
498 } 525 }
499 tag = params.stringType
500 } 526 }
501 527
502 if params.set { 528 if params.set {
503 if tag != tagSequence { 529 if tag != tagSequence {
504 return StructuralError{"Non sequence tagged as set"} 530 return StructuralError{"Non sequence tagged as set"}
505 } 531 }
506 tag = tagSet 532 tag = tagSet
507 } 533 }
508 534
509 tags, body := out.fork() 535 tags, body := out.fork()
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 var out bytes.Buffer 574 var out bytes.Buffer
549 v := reflect.ValueOf(val) 575 v := reflect.ValueOf(val)
550 f := newForkableWriter() 576 f := newForkableWriter()
551 err := marshalField(f, v, fieldParameters{}) 577 err := marshalField(f, v, fieldParameters{})
552 if err != nil { 578 if err != nil {
553 return nil, err 579 return nil, err
554 } 580 }
555 _, err = f.writeTo(&out) 581 _, err = f.writeTo(&out)
556 return out.Bytes(), nil 582 return out.Bytes(), nil
557 } 583 }
OLDNEW
« no previous file with comments | « src/pkg/encoding/asn1/common.go ('k') | src/pkg/encoding/asn1/marshal_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b