mirror of
https://github.com/golang/go
synced 2024-11-22 00:34:40 -07:00
crypto/openpgp/packet: add UserId packet type
This was split from CL 4124054 R=bradfitzgo CC=golang-dev https://golang.org/cl/4126057
This commit is contained in:
parent
e26b741523
commit
1b8d373463
105
src/pkg/crypto/openpgp/packet/userid.go
Normal file
105
src/pkg/crypto/openpgp/packet/userid.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UserId contains text that is intended to represent the name and email
|
||||||
|
// address of the key holder. See RFC 4880, section 5.11. By convention, this
|
||||||
|
// takes the form "Full Name (Comment) <email@example.com>"
|
||||||
|
type UserId struct {
|
||||||
|
Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
|
||||||
|
|
||||||
|
Name, Comment, Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uid *UserId) parse(r io.Reader) (err os.Error) {
|
||||||
|
// RFC 4880, section 5.11
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uid.Id = string(b)
|
||||||
|
uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseUserId extracts the name, comment and email from a user id string that
|
||||||
|
// is formatted as "Full Name (Comment) <email@example.com>".
|
||||||
|
func parseUserId(id string) (name, comment, email string) {
|
||||||
|
var n, c, e struct {
|
||||||
|
start, end int
|
||||||
|
}
|
||||||
|
var state int
|
||||||
|
|
||||||
|
for offset, rune := range id {
|
||||||
|
switch state {
|
||||||
|
case 0:
|
||||||
|
// Entering name
|
||||||
|
n.start = offset
|
||||||
|
state = 1
|
||||||
|
fallthrough
|
||||||
|
case 1:
|
||||||
|
// In name
|
||||||
|
if rune == '(' {
|
||||||
|
state = 2
|
||||||
|
n.end = offset
|
||||||
|
} else if rune == '<' {
|
||||||
|
state = 5
|
||||||
|
n.end = offset
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
// Entering comment
|
||||||
|
c.start = offset
|
||||||
|
state = 3
|
||||||
|
fallthrough
|
||||||
|
case 3:
|
||||||
|
// In comment
|
||||||
|
if rune == ')' {
|
||||||
|
state = 4
|
||||||
|
c.end = offset
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
// Between comment and email
|
||||||
|
if rune == '<' {
|
||||||
|
state = 5
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
// Entering email
|
||||||
|
e.start = offset
|
||||||
|
state = 6
|
||||||
|
fallthrough
|
||||||
|
case 6:
|
||||||
|
// In email
|
||||||
|
if rune == '>' {
|
||||||
|
state = 7
|
||||||
|
e.end = offset
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// After email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch state {
|
||||||
|
case 1:
|
||||||
|
// ended in the name
|
||||||
|
n.end = len(id)
|
||||||
|
case 3:
|
||||||
|
// ended in comment
|
||||||
|
c.end = len(id)
|
||||||
|
case 6:
|
||||||
|
// ended in email
|
||||||
|
e.end = len(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
name = strings.TrimSpace(id[n.start:n.end])
|
||||||
|
comment = strings.TrimSpace(id[c.start:c.end])
|
||||||
|
email = strings.TrimSpace(id[e.start:e.end])
|
||||||
|
return
|
||||||
|
}
|
42
src/pkg/crypto/openpgp/packet/userid_test.go
Normal file
42
src/pkg/crypto/openpgp/packet/userid_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userIdTests = []struct {
|
||||||
|
id string
|
||||||
|
name, comment, email string
|
||||||
|
}{
|
||||||
|
{"", "", "", ""},
|
||||||
|
{"John Smith", "John Smith", "", ""},
|
||||||
|
{"John Smith ()", "John Smith", "", ""},
|
||||||
|
{"John Smith () <>", "John Smith", "", ""},
|
||||||
|
{"(comment", "", "comment", ""},
|
||||||
|
{"(comment)", "", "comment", ""},
|
||||||
|
{"<email", "", "", "email"},
|
||||||
|
{"<email> sdfk", "", "", "email"},
|
||||||
|
{" John Smith ( Comment ) asdkflj < email > lksdfj", "John Smith", "Comment", "email"},
|
||||||
|
{" John Smith < email > lksdfj", "John Smith", "", "email"},
|
||||||
|
{"(<foo", "", "<foo", ""},
|
||||||
|
{"René Descartes (العربي)", "René Descartes", "العربي", ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseUserId(t *testing.T) {
|
||||||
|
for i, test := range userIdTests {
|
||||||
|
name, comment, email := parseUserId(test.id)
|
||||||
|
if name != test.name {
|
||||||
|
t.Errorf("%d: name mismatch got:%s want:%s", i, name, test.name)
|
||||||
|
}
|
||||||
|
if comment != test.comment {
|
||||||
|
t.Errorf("%d: comment mismatch got:%s want:%s", i, comment, test.comment)
|
||||||
|
}
|
||||||
|
if email != test.email {
|
||||||
|
t.Errorf("%d: email mismatch got:%s want:%s", i, email, test.email)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user