libgo: Update to weekly.2011-12-06.

From-SVN: r182338
This commit is contained in:
Ian Lance Taylor 2011-12-14 15:41:54 +00:00
parent ef0d4c4d99
commit d536359059
139 changed files with 1443 additions and 1333 deletions

View File

@ -41,16 +41,16 @@ func main() {
ok := true
for i := 0; i < len(tests); i++ {
t := tests[i]
v := strconv.Ftoa64(t.f, 'g', -1)
v := strconv.FormatFloat(t.f, 'g', -1, 64)
if v != t.out {
println("Bad float64 const:", t.in, "want", t.out, "got", v)
x, err := strconv.Atof64(t.out)
x, err := strconv.ParseFloat(t.out, 64)
if err != nil {
println("bug120: strconv.Atof64", t.out)
panic("fail")
}
println("\twant exact:", strconv.Ftoa64(x, 'g', 1000))
println("\tgot exact: ", strconv.Ftoa64(t.f, 'g', 1000))
println("\twant exact:", strconv.FormatFloat(x, 'g', 1000, 64))
println("\tgot exact: ", strconv.FormatFloat(t.f, 'g', 1000, 64))
ok = false
}
}

View File

@ -24,8 +24,8 @@ func main() {
report := len(os.Args) > 1
status := 0
var b1 [10]T1
a0, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[0])[2:], 16)
a1, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[1])[2:], 16)
a0, _ := strconv.ParseUint(fmt.Sprintf("%p", &b1[0])[2:], 16, 64)
a1, _ := strconv.ParseUint(fmt.Sprintf("%p", &b1[1])[2:], 16, 64)
if a1 != a0+1 {
fmt.Println("FAIL")
if report {
@ -34,8 +34,8 @@ func main() {
status = 1
}
var b2 [10]T2
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[0])[2:], 16)
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[1])[2:], 16)
a0, _ = strconv.ParseUint(fmt.Sprintf("%p", &b2[0])[2:], 16, 64)
a1, _ = strconv.ParseUint(fmt.Sprintf("%p", &b2[1])[2:], 16, 64)
if a1 != a0+2 {
if status == 0 {
fmt.Println("FAIL")
@ -46,8 +46,8 @@ func main() {
}
}
var b4 [10]T4
a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[0])[2:], 16)
a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[1])[2:], 16)
a0, _ = strconv.ParseUint(fmt.Sprintf("%p", &b4[0])[2:], 16, 64)
a1, _ = strconv.ParseUint(fmt.Sprintf("%p", &b4[1])[2:], 16, 64)
if a1 != a0+4 {
if status == 0 {
fmt.Println("FAIL")

View File

@ -1,4 +1,4 @@
0beb796b4ef8
0c39eee85b0d
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.

View File

@ -80,7 +80,7 @@ func (tr *Reader) octal(b []byte) int64 {
for len(b) > 0 && (b[len(b)-1] == ' ' || b[len(b)-1] == '\x00') {
b = b[0 : len(b)-1]
}
x, err := strconv.Btoui64(cString(b), 8)
x, err := strconv.ParseUint(cString(b), 8, 64)
if err != nil {
tr.err = err
}

View File

@ -24,7 +24,7 @@ type untarTest struct {
var gnuTarTest = &untarTest{
file: "testdata/gnu.tar",
headers: []*Header{
&Header{
{
Name: "small.txt",
Mode: 0640,
Uid: 73025,
@ -35,7 +35,7 @@ var gnuTarTest = &untarTest{
Uname: "dsymonds",
Gname: "eng",
},
&Header{
{
Name: "small2.txt",
Mode: 0640,
Uid: 73025,
@ -55,10 +55,10 @@ var gnuTarTest = &untarTest{
var untarTests = []*untarTest{
gnuTarTest,
&untarTest{
{
file: "testdata/star.tar",
headers: []*Header{
&Header{
{
Name: "small.txt",
Mode: 0640,
Uid: 73025,
@ -71,7 +71,7 @@ var untarTests = []*untarTest{
AccessTime: time.Unix(1244592783, 0),
ChangeTime: time.Unix(1244592783, 0),
},
&Header{
{
Name: "small2.txt",
Mode: 0640,
Uid: 73025,
@ -86,10 +86,10 @@ var untarTests = []*untarTest{
},
},
},
&untarTest{
{
file: "testdata/v7.tar",
headers: []*Header{
&Header{
{
Name: "small.txt",
Mode: 0444,
Uid: 73025,
@ -98,7 +98,7 @@ var untarTests = []*untarTest{
ModTime: time.Unix(1244593104, 0),
Typeflag: '\x00',
},
&Header{
{
Name: "small2.txt",
Mode: 0444,
Uid: 73025,

View File

@ -79,7 +79,7 @@ func (tw *Writer) cString(b []byte, s string) {
// Encode x as an octal ASCII string and write it into b with leading zeros.
func (tw *Writer) octal(b []byte, x int64) {
s := strconv.Itob64(x, 8)
s := strconv.FormatInt(x, 8)
// leading zeros, but leave room for a NUL.
for len(s)+1 < len(b) {
s = "0" + s
@ -90,7 +90,7 @@ func (tw *Writer) octal(b []byte, x int64) {
// Write x into b, either as octal or as binary (GNUtar/star extension).
func (tw *Writer) numeric(b []byte, x int64) {
// Try octal first.
s := strconv.Itob64(x, 8)
s := strconv.FormatInt(x, 8)
if len(s) < len(b) {
tw.octal(b, x)
return

View File

@ -29,10 +29,10 @@ var writerTests = []*writerTest{
// tar (GNU tar) 1.26
// ln -s small.txt link.txt
// tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt
&writerTest{
{
file: "testdata/writer.tar",
entries: []*writerTestEntry{
&writerTestEntry{
{
header: &Header{
Name: "small.txt",
Mode: 0640,
@ -46,7 +46,7 @@ var writerTests = []*writerTest{
},
contents: "Kilts",
},
&writerTestEntry{
{
header: &Header{
Name: "small2.txt",
Mode: 0640,
@ -60,7 +60,7 @@ var writerTests = []*writerTest{
},
contents: "Google.com\n",
},
&writerTestEntry{
{
header: &Header{
Name: "link.txt",
Mode: 0777,
@ -80,10 +80,10 @@ var writerTests = []*writerTest{
// The truncated test file was produced using these commands:
// dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt
// tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar
&writerTest{
{
file: "testdata/writer-big.tar",
entries: []*writerTestEntry{
&writerTestEntry{
{
header: &Header{
Name: "tmp/16gig.txt",
Mode: 0640,

View File

@ -21,12 +21,12 @@ type WriteTest struct {
}
var writeTests = []WriteTest{
WriteTest{
{
Name: "foo",
Data: []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
Method: Store,
},
WriteTest{
{
Name: "bar",
Data: nil, // large data set in the test
Method: Deflate,

View File

@ -20,7 +20,7 @@ type bitReader struct {
err error
}
// bitReader needs to read bytes from an io.Reader. We attempt to cast the
// bitReader needs to read bytes from an io.Reader. We attempt to convert the
// given io.Reader to this interface and, if it doesn't already fit, we wrap in
// a bufio.Reader.
type byteReader interface {

View File

@ -30,44 +30,44 @@ type reverseBitsTest struct {
}
var deflateTests = []*deflateTest{
&deflateTest{[]byte{}, 0, []byte{1, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}},
{[]byte{}, 0, []byte{1, 0, 0, 255, 255}},
{[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}},
{[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
{[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
[]byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255},
},
&deflateTest{[]byte{}, 1, []byte{1, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 1, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
&deflateTest{[]byte{}, 9, []byte{1, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
&deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
{[]byte{}, 1, []byte{1, 0, 0, 255, 255}},
{[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}},
{[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 1, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
{[]byte{}, 9, []byte{1, 0, 0, 255, 255}},
{[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}},
{[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
}
var deflateInflateTests = []*deflateInflateTest{
&deflateInflateTest{[]byte{}},
&deflateInflateTest{[]byte{0x11}},
&deflateInflateTest{[]byte{0x11, 0x12}},
&deflateInflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
&deflateInflateTest{[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}},
&deflateInflateTest{largeDataChunk()},
{[]byte{}},
{[]byte{0x11}},
{[]byte{0x11, 0x12}},
{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
{[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}},
{largeDataChunk()},
}
var reverseBitsTests = []*reverseBitsTest{
&reverseBitsTest{1, 1, 1},
&reverseBitsTest{1, 2, 2},
&reverseBitsTest{1, 3, 4},
&reverseBitsTest{1, 4, 8},
&reverseBitsTest{1, 5, 16},
&reverseBitsTest{17, 5, 17},
&reverseBitsTest{257, 9, 257},
&reverseBitsTest{29, 5, 23},
{1, 1, 1},
{1, 2, 2},
{1, 3, 4},
{1, 4, 8},
{1, 5, 16},
{17, 5, 17},
{257, 9, 257},
{29, 5, 23},
}
func largeDataChunk() []byte {

View File

@ -52,7 +52,7 @@ type InitDecoderTest struct {
var initDecoderTests = []*InitDecoderTest{
// Example from Connell 1973,
&InitDecoderTest{
{
[]int{3, 5, 2, 4, 3, 5, 5, 4, 4, 3, 4, 5},
huffmanDecoder{
2, 5,
@ -68,7 +68,7 @@ var initDecoderTests = []*InitDecoderTest{
},
// Example from RFC 1951 section 3.2.2
&InitDecoderTest{
{
[]int{2, 1, 3, 3},
huffmanDecoder{
1, 3,
@ -80,7 +80,7 @@ var initDecoderTests = []*InitDecoderTest{
},
// Second example from RFC 1951 section 3.2.2
&InitDecoderTest{
{
[]int{3, 3, 3, 3, 3, 2, 4, 4},
huffmanDecoder{
2, 4,
@ -92,21 +92,21 @@ var initDecoderTests = []*InitDecoderTest{
},
// Static Huffman codes (RFC 1951 section 3.2.6)
&InitDecoderTest{
{
fixedHuffmanBits[0:],
fixedHuffmanDecoder,
true,
},
// Illegal input.
&InitDecoderTest{
{
[]int{},
huffmanDecoder{},
false,
},
// Illegal input.
&InitDecoderTest{
{
[]int{0, 0, 0, 0, 0, 0, 0},
huffmanDecoder{},
false,

View File

@ -106,8 +106,8 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
}
func (err WrongValueError) Error() string {
return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.Itoa64(int64(err.from)) + ";" +
strconv.Itoa64(int64(err.to)) + "] but actual value is " + strconv.Itoa64(int64(err.value))
return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.FormatInt(int64(err.from), 10) + ";" +
strconv.FormatInt(int64(err.to), 10) + "] but actual value is " + strconv.FormatInt(int64(err.value), 10)
}
func (w *huffmanBitWriter) flushBits() {

View File

@ -25,7 +25,7 @@ const (
type CorruptInputError int64
func (e CorruptInputError) Error() string {
return "flate: corrupt input before offset " + strconv.Itoa64(int64(e))
return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
}
// An InternalError reports an error in the flate code itself.
@ -40,7 +40,7 @@ type ReadError struct {
}
func (e *ReadError) Error() string {
return "flate: read error at offset " + strconv.Itoa64(e.Offset) + ": " + e.Err.Error()
return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
}
// A WriteError reports an error encountered while writing output.
@ -50,7 +50,7 @@ type WriteError struct {
}
func (e *WriteError) Error() string {
return "flate: write error at offset " + strconv.Itoa64(e.Offset) + ": " + e.Err.Error()
return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
}
// Huffman decoder is based on

View File

@ -348,3 +348,17 @@ func TestCipherDecrypt(t *testing.T) {
}
}
}
func BenchmarkEncrypt(b *testing.B) {
b.StopTimer()
tt := encryptTests[0]
c, err := NewCipher(tt.key)
if err != nil {
panic("NewCipher")
}
out := make([]byte, len(tt.in))
b.StartTimer()
for i := 0; i < b.N; i++ {
c.Encrypt(out, tt.in)
}
}

View File

@ -56,10 +56,10 @@ func encryptBlock(xk []uint32, dst, src []byte) {
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ te[0][s0>>24] ^ te[1][s1>>16&0xff] ^ te[2][s2>>8&0xff] ^ te[3][s3&0xff]
t1 = xk[k+1] ^ te[0][s1>>24] ^ te[1][s2>>16&0xff] ^ te[2][s3>>8&0xff] ^ te[3][s0&0xff]
t2 = xk[k+2] ^ te[0][s2>>24] ^ te[1][s3>>16&0xff] ^ te[2][s0>>8&0xff] ^ te[3][s1&0xff]
t3 = xk[k+3] ^ te[0][s3>>24] ^ te[1][s0>>16&0xff] ^ te[2][s1>>8&0xff] ^ te[3][s2&0xff]
t0 = xk[k+0] ^ te[0][uint8(s0>>24)] ^ te[1][uint8(s1>>16)] ^ te[2][uint8(s2>>8)] ^ te[3][uint8(s3)]
t1 = xk[k+1] ^ te[0][uint8(s1>>24)] ^ te[1][uint8(s2>>16)] ^ te[2][uint8(s3>>8)] ^ te[3][uint8(s0)]
t2 = xk[k+2] ^ te[0][uint8(s2>>24)] ^ te[1][uint8(s3>>16)] ^ te[2][uint8(s0>>8)] ^ te[3][uint8(s1)]
t3 = xk[k+3] ^ te[0][uint8(s3>>24)] ^ te[1][uint8(s0>>16)] ^ te[2][uint8(s1>>8)] ^ te[3][uint8(s2)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}
@ -101,10 +101,10 @@ func decryptBlock(xk []uint32, dst, src []byte) {
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ td[0][s0>>24] ^ td[1][s3>>16&0xff] ^ td[2][s2>>8&0xff] ^ td[3][s1&0xff]
t1 = xk[k+1] ^ td[0][s1>>24] ^ td[1][s0>>16&0xff] ^ td[2][s3>>8&0xff] ^ td[3][s2&0xff]
t2 = xk[k+2] ^ td[0][s2>>24] ^ td[1][s1>>16&0xff] ^ td[2][s0>>8&0xff] ^ td[3][s3&0xff]
t3 = xk[k+3] ^ td[0][s3>>24] ^ td[1][s2>>16&0xff] ^ td[2][s1>>8&0xff] ^ td[3][s0&0xff]
t0 = xk[k+0] ^ td[0][uint8(s0>>24)] ^ td[1][uint8(s3>>16)] ^ td[2][uint8(s2>>8)] ^ td[3][uint8(s1)]
t1 = xk[k+1] ^ td[0][uint8(s1>>24)] ^ td[1][uint8(s0>>16)] ^ td[2][uint8(s3>>8)] ^ td[3][uint8(s2)]
t2 = xk[k+2] ^ td[0][uint8(s2>>24)] ^ td[1][uint8(s1>>16)] ^ td[2][uint8(s0>>8)] ^ td[3][uint8(s3)]
t3 = xk[k+3] ^ td[0][uint8(s3>>24)] ^ td[1][uint8(s2>>16)] ^ td[2][uint8(s1>>8)] ^ td[3][uint8(s0)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}

View File

@ -49,14 +49,13 @@ func (h *hmac) tmpPad(xor byte) {
}
func (h *hmac) Sum(in []byte) []byte {
sum := h.inner.Sum(nil)
origLen := len(in)
in = h.inner.Sum(in)
h.tmpPad(0x5c)
for i, b := range sum {
h.tmp[padSize+i] = b
}
copy(h.tmp[padSize:], in[origLen:])
h.outer.Reset()
h.outer.Write(h.tmp)
return h.outer.Sum(in)
return h.outer.Sum(in[:origLen])
}
func (h *hmac) Write(p []byte) (n int, err error) {

View File

@ -79,8 +79,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := new(digest)
*d = *d0
d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
@ -103,11 +102,13 @@ func (d0 *digest) Sum(in []byte) []byte {
panic("d.nx != 0")
}
for _, s := range d.s {
in = append(in, byte(s>>0))
in = append(in, byte(s>>8))
in = append(in, byte(s>>16))
in = append(in, byte(s>>24))
var digest [Size]byte
for i, s := range d.s {
digest[i*4] = byte(s)
digest[i*4+1] = byte(s >> 8)
digest[i*4+2] = byte(s >> 16)
digest[i*4+3] = byte(s >> 24)
}
return in
return append(in, digest[:]...)
}

View File

@ -26,6 +26,7 @@ var zero [1]byte
// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
done := 0
var digest []byte
for i := 0; done < len(out); i++ {
h.Reset()
@ -34,7 +35,8 @@ func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
}
h.Write(salt)
h.Write(in)
n := copy(out[done:], h.Sum(nil))
digest = h.Sum(digest[:0])
n := copy(out[done:], digest)
done += n
}
}
@ -52,6 +54,7 @@ func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
}
done := 0
var digest []byte
for i := 0; done < len(out); i++ {
h.Reset()
for j := 0; j < i; j++ {
@ -68,7 +71,8 @@ func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
written += len(combined)
}
}
n := copy(out[done:], h.Sum(nil))
digest = h.Sum(digest[:0])
n := copy(out[done:], digest)
done += n
}
}

View File

@ -183,7 +183,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
for i := range to {
encryptKeys[i] = to[i].encryptionKey()
if encryptKeys[i].PublicKey == nil {
return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.Uitob64(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
}
sig := to[i].primaryIdentity().SelfSignature

View File

@ -83,8 +83,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := new(digest)
*d = *d0
d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
tc := d.tc
@ -107,11 +106,13 @@ func (d0 *digest) Sum(in []byte) []byte {
panic("d.nx != 0")
}
for _, s := range d.s {
in = append(in, byte(s))
in = append(in, byte(s>>8))
in = append(in, byte(s>>16))
in = append(in, byte(s>>24))
var digest [Size]byte
for i, s := range d.s {
digest[i*4] = byte(s)
digest[i*4+1] = byte(s >> 8)
digest[i*4+2] = byte(s >> 16)
digest[i*4+3] = byte(s >> 24)
}
return in
return append(in, digest[:]...)
}

View File

@ -189,12 +189,13 @@ func incCounter(c *[4]byte) {
// specified in PKCS#1 v2.1.
func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
var counter [4]byte
var digest []byte
done := 0
for done < len(out) {
hash.Write(seed)
hash.Write(counter[0:4])
digest := hash.Sum(nil)
digest = hash.Sum(digest[:0])
hash.Reset()
for i := 0; i < len(digest) && done < len(out); i++ {

View File

@ -81,8 +81,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := new(digest)
*d = *d0
d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
@ -105,11 +104,13 @@ func (d0 *digest) Sum(in []byte) []byte {
panic("d.nx != 0")
}
for _, s := range d.h {
in = append(in, byte(s>>24))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
var digest [Size]byte
for i, s := range d.h {
digest[i*4] = byte(s >> 24)
digest[i*4+1] = byte(s >> 16)
digest[i*4+2] = byte(s >> 8)
digest[i*4+3] = byte(s)
}
return in
return append(in, digest[:]...)
}

View File

@ -125,8 +125,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := new(digest)
*d = *d0
d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
@ -150,14 +149,19 @@ func (d0 *digest) Sum(in []byte) []byte {
}
h := d.h[:]
size := Size
if d.is224 {
h = d.h[:7]
size = Size224
}
for _, s := range h {
in = append(in, byte(s>>24))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
var digest [Size]byte
for i, s := range h {
digest[i*4] = byte(s >> 24)
digest[i*4+1] = byte(s >> 16)
digest[i*4+2] = byte(s >> 8)
digest[i*4+3] = byte(s)
}
return in
return append(in, digest[:size]...)
}

View File

@ -150,18 +150,23 @@ func (d0 *digest) Sum(in []byte) []byte {
}
h := d.h[:]
size := Size
if d.is384 {
h = d.h[:6]
size = Size384
}
for _, s := range h {
in = append(in, byte(s>>56))
in = append(in, byte(s>>48))
in = append(in, byte(s>>40))
in = append(in, byte(s>>32))
in = append(in, byte(s>>24))
in = append(in, byte(s>>16))
in = append(in, byte(s>>8))
in = append(in, byte(s))
var digest [Size]byte
for i, s := range h {
digest[i*8] = byte(s >> 56)
digest[i*8+1] = byte(s >> 48)
digest[i*8+2] = byte(s >> 40)
digest[i*8+3] = byte(s >> 32)
digest[i*8+4] = byte(s >> 24)
digest[i*8+5] = byte(s >> 16)
digest[i*8+6] = byte(s >> 8)
digest[i*8+7] = byte(s)
}
return in
return append(in, digest[:size]...)
}

View File

@ -52,12 +52,12 @@ type cipherSuite struct {
}
var cipherSuites = []*cipherSuite{
&cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
&cipherSuite{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
&cipherSuite{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
&cipherSuite{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
&cipherSuite{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
&cipherSuite{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
}
func cipherRC4(key, iv []byte, isRead bool) interface{} {
@ -96,7 +96,7 @@ func macSHA1(version uint16, key []byte) macFunction {
type macFunction interface {
Size() int
MAC(seq, data []byte) []byte
MAC(digestBuf, seq, data []byte) []byte
}
// ssl30MAC implements the SSLv3 MAC function, as defined in
@ -114,7 +114,7 @@ var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0
var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
func (s ssl30MAC) MAC(seq, record []byte) []byte {
func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte {
padLength := 48
if s.h.Size() == 20 {
padLength = 40
@ -127,13 +127,13 @@ func (s ssl30MAC) MAC(seq, record []byte) []byte {
s.h.Write(record[:1])
s.h.Write(record[3:5])
s.h.Write(record[recordHeaderLen:])
digest := s.h.Sum(nil)
digestBuf = s.h.Sum(digestBuf[:0])
s.h.Reset()
s.h.Write(s.key)
s.h.Write(ssl30Pad2[:padLength])
s.h.Write(digest)
return s.h.Sum(nil)
s.h.Write(digestBuf)
return s.h.Sum(digestBuf[:0])
}
// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
@ -145,11 +145,11 @@ func (s tls10MAC) Size() int {
return s.h.Size()
}
func (s tls10MAC) MAC(seq, record []byte) []byte {
func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte {
s.h.Reset()
s.h.Write(seq)
s.h.Write(record)
return s.h.Sum(nil)
return s.h.Sum(digestBuf[:0])
}
func rsaKA() keyAgreement {

View File

@ -118,6 +118,9 @@ type halfConn struct {
nextCipher interface{} // next encryption state
nextMac macFunction // next MAC algorithm
// used to save allocating a new buffer for each MAC.
inDigestBuf, outDigestBuf []byte
}
// prepareCipherSpec sets the encryption and MAC states
@ -280,12 +283,13 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) {
b.data[4] = byte(n)
b.resize(recordHeaderLen + n)
remoteMAC := payload[n:]
localMAC := hc.mac.MAC(hc.seq[0:], b.data)
localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data)
hc.incSeq()
if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
return false, alertBadRecordMAC
}
hc.inDigestBuf = localMAC
}
return true, 0
@ -312,12 +316,13 @@ func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
func (hc *halfConn) encrypt(b *block) (bool, alert) {
// mac
if hc.mac != nil {
mac := hc.mac.MAC(hc.seq[0:], b.data)
mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data)
hc.incSeq()
n := len(b.data)
b.resize(n + len(mac))
copy(b.data[n:], mac)
hc.outDigestBuf = mac
}
payload := b.data[recordHeaderLen:]

View File

@ -231,10 +231,10 @@ func (c *Conn) clientHandshake() error {
if cert != nil {
certVerify := new(certificateVerifyMsg)
var digest [36]byte
copy(digest[0:16], finishedHash.serverMD5.Sum(nil))
copy(digest[16:36], finishedHash.serverSHA1.Sum(nil))
signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest[0:])
digest := make([]byte, 0, 36)
digest = finishedHash.serverMD5.Sum(digest)
digest = finishedHash.serverSHA1.Sum(digest)
signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest)
if err != nil {
return c.sendAlert(alertInternalError)
}

View File

@ -234,9 +234,9 @@ FindCipherSuite:
return c.sendAlert(alertUnexpectedMessage)
}
digest := make([]byte, 36)
copy(digest[0:16], finishedHash.serverMD5.Sum(nil))
copy(digest[16:36], finishedHash.serverSHA1.Sum(nil))
digest := make([]byte, 0, 36)
digest = finishedHash.serverMD5.Sum(digest)
digest = finishedHash.serverSHA1.Sum(digest)
err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature)
if err != nil {
c.sendAlert(alertBadCertificate)

View File

@ -159,7 +159,7 @@ func TestHandshakeServerSSLv3(t *testing.T) {
var serve = flag.Bool("serve", false, "run a TLS server on :10443")
var testCipherSuites = flag.String("ciphersuites",
"0x"+strconv.Itob(int(TLS_RSA_WITH_RC4_128_SHA), 16),
"0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16),
"cipher suites to accept in serving mode")
func TestRunServer(t *testing.T) {
@ -170,7 +170,7 @@ func TestRunServer(t *testing.T) {
suites := strings.Split(*testCipherSuites, ",")
testConfig.CipherSuites = make([]uint16, len(suites))
for i := range suites {
suite, err := strconv.Btoui64(suites[i], 0)
suite, err := strconv.ParseUint(suites[i], 0, 64)
if err != nil {
panic(err)
}

View File

@ -927,10 +927,15 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub *rsa.P
return
}
asn1Issuer, err := asn1.Marshal(parent.Subject.ToRDNSequence())
if err != nil {
return
var asn1Issuer []byte
if len(parent.RawSubject) > 0 {
asn1Issuer = parent.RawSubject
} else {
if asn1Issuer, err = asn1.Marshal(parent.Subject.ToRDNSequence()); err != nil {
return
}
}
asn1Subject, err := asn1.Marshal(template.Subject.ToRDNSequence())
if err != nil {
return

View File

@ -149,5 +149,5 @@ type DecodeError struct {
}
func (e DecodeError) Error() string {
return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.Itob64(int64(e.Offset), 16) + ": " + e.Err
return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
}

View File

@ -178,7 +178,7 @@ func (a Attr) GoString() string {
return "dwarf.Attr" + s
}
}
return "dwarf.Attr(" + strconv.Itoa64(int64(a)) + ")"
return "dwarf.Attr(" + strconv.FormatInt(int64(a), 10) + ")"
}
// A format is a DWARF data encoding format.
@ -347,7 +347,7 @@ func (t Tag) GoString() string {
return "dwarf.Tag" + s
}
}
return "dwarf.Tag(" + strconv.Itoa64(int64(t)) + ")"
return "dwarf.Tag(" + strconv.FormatInt(int64(t), 10) + ")"
}
// Location expression operators.

View File

@ -110,7 +110,7 @@ type ArrayType struct {
}
func (t *ArrayType) String() string {
return "[" + strconv.Itoa64(t.Count) + "]" + t.Type.String()
return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
}
func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
@ -171,10 +171,10 @@ func (t *StructType) Defn() string {
s += "; "
}
s += f.Name + " " + f.Type.String()
s += "@" + strconv.Itoa64(f.ByteOffset)
s += "@" + strconv.FormatInt(f.ByteOffset, 10)
if f.BitSize > 0 {
s += " : " + strconv.Itoa64(f.BitSize)
s += "@" + strconv.Itoa64(f.BitOffset)
s += " : " + strconv.FormatInt(f.BitSize, 10)
s += "@" + strconv.FormatInt(f.BitOffset, 10)
}
}
s += "}"
@ -206,7 +206,7 @@ func (t *EnumType) String() string {
if i > 0 {
s += "; "
}
s += v.Name + "=" + strconv.Itoa64(v.Val)
s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
}
s += "}"
return s

View File

@ -1490,11 +1490,11 @@ func stringName(i uint32, names []intName, goSyntax bool) string {
if goSyntax {
s = "elf." + s
}
return s + "+" + strconv.Uitoa64(uint64(i-n.i))
return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
}
}
return strconv.Uitoa64(uint64(i))
return strconv.FormatUint(uint64(i), 10)
}
func flagName(i uint32, names []intName, goSyntax bool) string {
@ -1512,10 +1512,10 @@ func flagName(i uint32, names []intName, goSyntax bool) string {
}
}
if len(s) == 0 {
return "0x" + strconv.Uitob64(uint64(i), 16)
return "0x" + strconv.FormatUint(uint64(i), 16)
}
if i != 0 {
s += "+0x" + strconv.Uitob64(uint64(i), 16)
s += "+0x" + strconv.FormatUint(uint64(i), 16)
}
return s
}

View File

@ -21,11 +21,11 @@ var fileTests = []fileTest{
"testdata/gcc-386-darwin-exec",
FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85},
[]*SegmentHeader{
&SegmentHeader{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
&SegmentHeader{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
&SegmentHeader{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
&SegmentHeader{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
&SegmentHeader{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
nil,
nil,
nil,
@ -35,21 +35,21 @@ var fileTests = []fileTest{
nil,
},
[]*SectionHeader{
&SectionHeader{"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400},
&SectionHeader{"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2},
&SectionHeader{"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0},
&SectionHeader{"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0},
&SectionHeader{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
{"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400},
{"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2},
{"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0},
{"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0},
{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
},
},
{
"testdata/gcc-amd64-darwin-exec",
FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85},
[]*SegmentHeader{
&SegmentHeader{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
&SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
&SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
&SegmentHeader{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
nil,
nil,
nil,
@ -59,14 +59,14 @@ var fileTests = []fileTest{
nil,
},
[]*SectionHeader{
&SectionHeader{"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400},
&SectionHeader{"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408},
&SectionHeader{"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0},
&SectionHeader{"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2},
&SectionHeader{"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b},
&SectionHeader{"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0},
&SectionHeader{"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0},
&SectionHeader{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
{"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400},
{"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408},
{"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0},
{"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2},
{"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b},
{"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0},
{"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0},
{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
},
},
{
@ -74,26 +74,26 @@ var fileTests = []fileTest{
FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0},
[]*SegmentHeader{
nil,
&SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
&SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
&SegmentHeader{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
},
[]*SectionHeader{
&SectionHeader{"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400},
&SectionHeader{"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408},
&SectionHeader{"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0},
&SectionHeader{"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
&SectionHeader{"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b},
&SectionHeader{"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
&SectionHeader{"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
&SectionHeader{"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7},
&SectionHeader{"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0},
&SectionHeader{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
{"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400},
{"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408},
{"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0},
{"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
{"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b},
{"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
{"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
{"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7},
{"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0},
{"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0},
{"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0},
{"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0},
{"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0},
{"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0},
{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
},
},
}

View File

@ -278,7 +278,7 @@ func stringName(i uint32, names []intName, goSyntax bool) string {
return n.s
}
}
return strconv.Uitoa64(uint64(i))
return strconv.FormatUint(uint64(i), 10)
}
func flagName(i uint32, names []intName, goSyntax bool) string {
@ -296,10 +296,10 @@ func flagName(i uint32, names []intName, goSyntax bool) string {
}
}
if len(s) == 0 {
return "0x" + strconv.Uitob64(uint64(i), 16)
return "0x" + strconv.FormatUint(uint64(i), 16)
}
if i != 0 {
s += "+0x" + strconv.Uitob64(uint64(i), 16)
s += "+0x" + strconv.FormatUint(uint64(i), 16)
}
return s
}

View File

@ -20,39 +20,39 @@ var fileTests = []fileTest{
"testdata/gcc-386-mingw-obj",
FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
[]*SectionHeader{
&SectionHeader{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
&SectionHeader{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
&SectionHeader{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
&SectionHeader{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},
&SectionHeader{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},
&SectionHeader{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},
&SectionHeader{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},
&SectionHeader{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},
&SectionHeader{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},
&SectionHeader{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},
&SectionHeader{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
&SectionHeader{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},
{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},
{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},
{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},
{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},
{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},
{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},
{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
},
},
{
"testdata/gcc-386-mingw-exec",
FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
[]*SectionHeader{
&SectionHeader{Name: ".text", VirtualSize: 0xcd8, VirtualAddress: 0x1000, Size: 0xe00, Offset: 0x400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x60500060},
&SectionHeader{Name: ".data", VirtualSize: 0x10, VirtualAddress: 0x2000, Size: 0x200, Offset: 0x1200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
&SectionHeader{Name: ".rdata", VirtualSize: 0x120, VirtualAddress: 0x3000, Size: 0x200, Offset: 0x1400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x40300040},
&SectionHeader{Name: ".bss", VirtualSize: 0xdc, VirtualAddress: 0x4000, Size: 0x0, Offset: 0x0, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0400080},
&SectionHeader{Name: ".idata", VirtualSize: 0x3c8, VirtualAddress: 0x5000, Size: 0x400, Offset: 0x1600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
&SectionHeader{Name: ".CRT", VirtualSize: 0x18, VirtualAddress: 0x6000, Size: 0x200, Offset: 0x1a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
&SectionHeader{Name: ".tls", VirtualSize: 0x20, VirtualAddress: 0x7000, Size: 0x200, Offset: 0x1c00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
&SectionHeader{Name: ".debug_aranges", VirtualSize: 0x20, VirtualAddress: 0x8000, Size: 0x200, Offset: 0x1e00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_pubnames", VirtualSize: 0x51, VirtualAddress: 0x9000, Size: 0x200, Offset: 0x2000, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_pubtypes", VirtualSize: 0x91, VirtualAddress: 0xa000, Size: 0x200, Offset: 0x2200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_info", VirtualSize: 0xe22, VirtualAddress: 0xb000, Size: 0x1000, Offset: 0x2400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_abbrev", VirtualSize: 0x157, VirtualAddress: 0xc000, Size: 0x200, Offset: 0x3400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_line", VirtualSize: 0x144, VirtualAddress: 0xd000, Size: 0x200, Offset: 0x3600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
&SectionHeader{Name: ".debug_frame", VirtualSize: 0x34, VirtualAddress: 0xe000, Size: 0x200, Offset: 0x3800, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42300000},
&SectionHeader{Name: ".debug_loc", VirtualSize: 0x38, VirtualAddress: 0xf000, Size: 0x200, Offset: 0x3a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".text", VirtualSize: 0xcd8, VirtualAddress: 0x1000, Size: 0xe00, Offset: 0x400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x60500060},
{Name: ".data", VirtualSize: 0x10, VirtualAddress: 0x2000, Size: 0x200, Offset: 0x1200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
{Name: ".rdata", VirtualSize: 0x120, VirtualAddress: 0x3000, Size: 0x200, Offset: 0x1400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x40300040},
{Name: ".bss", VirtualSize: 0xdc, VirtualAddress: 0x4000, Size: 0x0, Offset: 0x0, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0400080},
{Name: ".idata", VirtualSize: 0x3c8, VirtualAddress: 0x5000, Size: 0x400, Offset: 0x1600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
{Name: ".CRT", VirtualSize: 0x18, VirtualAddress: 0x6000, Size: 0x200, Offset: 0x1a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
{Name: ".tls", VirtualSize: 0x20, VirtualAddress: 0x7000, Size: 0x200, Offset: 0x1c00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040},
{Name: ".debug_aranges", VirtualSize: 0x20, VirtualAddress: 0x8000, Size: 0x200, Offset: 0x1e00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_pubnames", VirtualSize: 0x51, VirtualAddress: 0x9000, Size: 0x200, Offset: 0x2000, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_pubtypes", VirtualSize: 0x91, VirtualAddress: 0xa000, Size: 0x200, Offset: 0x2200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_info", VirtualSize: 0xe22, VirtualAddress: 0xb000, Size: 0x1000, Offset: 0x2400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_abbrev", VirtualSize: 0x157, VirtualAddress: 0xc000, Size: 0x200, Offset: 0x3400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_line", VirtualSize: 0x144, VirtualAddress: 0xd000, Size: 0x200, Offset: 0x3600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
{Name: ".debug_frame", VirtualSize: 0x34, VirtualAddress: 0xe000, Size: 0x200, Offset: 0x3800, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42300000},
{Name: ".debug_loc", VirtualSize: 0x38, VirtualAddress: 0xf000, Size: 0x200, Offset: 0x3a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000},
},
},
}

View File

@ -168,7 +168,7 @@ func (e *encoder) Close() error {
type CorruptInputError int64
func (e CorruptInputError) Error() string {
return "illegal ascii85 data at input byte " + strconv.Itoa64(int64(e))
return "illegal ascii85 data at input byte " + strconv.FormatInt(int64(e), 10)
}
// Decode decodes src into dst, returning both the number

View File

@ -225,19 +225,19 @@ func TestUTCTime(t *testing.T) {
ret, err := parseUTCTime([]byte(test.in))
if err != nil {
if test.ok {
t.Errorf("#%d: parseUTCTime(%q) = error %v", i, err)
t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
}
continue
}
if !test.ok {
t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i)
t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
continue
}
const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
have := ret.Format(format)
want := test.out.Format(format)
if have != want {
t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", test.in, have, want)
t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
}
}
}

View File

@ -98,7 +98,7 @@ func parseFieldParameters(str string) (ret fieldParameters) {
case part == "printable":
ret.stringType = tagPrintableString
case strings.HasPrefix(part, "default:"):
i, err := strconv.Atoi64(part[8:])
i, err := strconv.ParseInt(part[8:], 10, 64)
if err == nil {
ret.defaultValue = new(int64)
*ret.defaultValue = i

View File

@ -216,7 +216,7 @@ func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 }
type CorruptInputError int64
func (e CorruptInputError) Error() string {
return "illegal base32 data at input byte " + strconv.Itoa64(int64(e))
return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
}
// decode is like Decode but returns an additional 'end' value, which

View File

@ -203,7 +203,7 @@ func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 }
type CorruptInputError int64
func (e CorruptInputError) Error() string {
return "illegal base64 data at input byte " + strconv.Itoa64(int64(e))
return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
}
// decode is like Decode but returns an additional 'end' value, which

View File

@ -15,7 +15,7 @@ import (
type CorruptInputError int64
func (e CorruptInputError) Error() string {
return "illegal git85 data at input byte " + strconv.Itoa64(int64(e))
return "illegal git85 data at input byte " + strconv.FormatInt(int64(e), 10)
}
const encode = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"

View File

@ -119,7 +119,9 @@ func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTyp
switch st := actual; st.Kind() {
case reflect.Struct:
for i := 0; i < st.NumField(); i++ {
enc.sendType(w, state, st.Field(i).Type)
if isExported(st.Field(i).Name) {
enc.sendType(w, state, st.Field(i).Type)
}
}
case reflect.Array, reflect.Slice:
enc.sendType(w, state, st.Elem())

View File

@ -662,3 +662,19 @@ func TestSequentialDecoder(t *testing.T) {
}
}
}
// Should be able to have unrepresentable fields (chan, func) as long as they
// are unexported.
type Bug2 struct {
A int
b chan int
}
func TestUnexportedChan(t *testing.T) {
b := Bug2{23, make(chan int)}
var stream bytes.Buffer
enc := NewEncoder(&stream)
if err := enc.Encode(b); err != nil {
t.Fatalf("error encoding unexported channel: %s", err)
}
}

View File

@ -642,7 +642,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) {
default:
d.error(&UnmarshalTypeError{"number", v.Type()})
case reflect.Interface:
n, err := strconv.Atof64(s)
n, err := strconv.ParseFloat(s, 64)
if err != nil {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break
@ -650,7 +650,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) {
v.Set(reflect.ValueOf(n))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n, err := strconv.Atoi64(s)
n, err := strconv.ParseInt(s, 10, 64)
if err != nil || v.OverflowInt(n) {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break
@ -658,7 +658,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) {
v.SetInt(n)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
n, err := strconv.Atoui64(s)
n, err := strconv.ParseUint(s, 10, 64)
if err != nil || v.OverflowUint(n) {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break
@ -666,7 +666,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) {
v.SetUint(n)
case reflect.Float32, reflect.Float64:
n, err := strconv.AtofN(s, v.Type().Bits())
n, err := strconv.ParseFloat(s, v.Type().Bits())
if err != nil || v.OverflowFloat(n) {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break
@ -798,7 +798,7 @@ func (d *decodeState) literalInterface() interface{} {
if c != '-' && (c < '0' || c > '9') {
d.error(errPhase)
}
n, err := strconv.Atof64(string(item))
n, err := strconv.ParseFloat(string(item), 64)
if err != nil {
d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.TypeOf(0.0)})
}
@ -813,7 +813,7 @@ func getu4(s []byte) rune {
if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
return -1
}
r, err := strconv.Btoui64(string(s[2:6]), 16)
r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
if err != nil {
return -1
}

View File

@ -345,12 +345,12 @@ var allValue = All{
"18": {Tag: "tag18"},
},
MapP: map[string]*Small{
"19": &Small{Tag: "tag19"},
"19": {Tag: "tag19"},
"20": nil,
},
EmptyMap: map[string]Small{},
Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}},
SliceP: []*Small{&Small{Tag: "tag22"}, nil, &Small{Tag: "tag23"}},
SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
EmptySlice: []Small{},
StringSlice: []string{"str24", "str25", "str26"},
ByteSlice: []byte{27, 28, 29},

View File

@ -275,13 +275,13 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
writeString(e, strconv.Itoa64(v.Int()))
writeString(e, strconv.FormatInt(v.Int(), 10))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
writeString(e, strconv.Uitoa64(v.Uint()))
writeString(e, strconv.FormatUint(v.Uint(), 10))
case reflect.Float32, reflect.Float64:
writeString(e, strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits()))
writeString(e, strconv.FormatFloat(v.Float(), 'g', -1, v.Type().Bits()))
case reflect.String:
if quoted {

View File

@ -173,15 +173,15 @@ func (p *printer) marshalValue(val reflect.Value, name string) error {
switch k := val.Kind(); k {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p.WriteString(strconv.Itoa64(val.Int()))
p.WriteString(strconv.FormatInt(val.Int(), 10))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p.WriteString(strconv.Uitoa64(val.Uint()))
p.WriteString(strconv.FormatUint(val.Uint(), 10))
case reflect.Float32, reflect.Float64:
p.WriteString(strconv.Ftoa64(val.Float(), 'g', -1))
p.WriteString(strconv.FormatFloat(val.Float(), 'g', -1, 64))
case reflect.String:
Escape(p, []byte(val.String()))
case reflect.Bool:
p.WriteString(strconv.Btoa(val.Bool()))
p.WriteString(strconv.FormatBool(val.Bool()))
case reflect.Array:
// will be [...]byte
bytes := make([]byte, val.Len())

View File

@ -160,19 +160,19 @@ var marshalTests = []struct {
Age: 1,
Drive: ImprobabilityDrive,
Passenger: []*Passenger{
&Passenger{
{
Name: []string{"Zaphod", "Beeblebrox"},
Weight: 7.25,
},
&Passenger{
{
Name: []string{"Trisha", "McMillen"},
Weight: 5.5,
},
&Passenger{
{
Name: []string{"Ford", "Prefect"},
Weight: 7,
},
&Passenger{
{
Name: []string{"Arthur", "Dent"},
Weight: 6.75,
},
@ -326,12 +326,12 @@ var marshalErrorTests = []struct {
"question": "What do you get when you multiply six by nine?",
"answer": "42",
},
Err: "xml: unsupported type: map[string] string",
Err: "xml: unsupported type: map[string]string",
Kind: reflect.Map,
},
{
Value: map[*Ship]bool{nil: false},
Err: "xml: unsupported type: map[*xml.Ship] bool",
Err: "xml: unsupported type: map[*xml.Ship]bool",
Kind: reflect.Map,
},
}

View File

@ -486,19 +486,19 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
// Helper functions for integer and unsigned integer conversions
var itmp int64
getInt64 := func() bool {
itmp, err = strconv.Atoi64(string(src))
itmp, err = strconv.ParseInt(string(src), 10, 64)
// TODO: should check sizes
return err == nil
}
var utmp uint64
getUint64 := func() bool {
utmp, err = strconv.Atoui64(string(src))
utmp, err = strconv.ParseUint(string(src), 10, 64)
// TODO: check for overflow?
return err == nil
}
var ftmp float64
getFloat64 := func() bool {
ftmp, err = strconv.Atof64(string(src))
ftmp, err = strconv.ParseFloat(string(src), 64)
// TODO: check for overflow?
return err == nil
}
@ -525,7 +525,7 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
}
t.SetFloat(ftmp)
case reflect.Bool:
value, err := strconv.Atob(strings.TrimSpace(string(src)))
value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
if err != nil {
return err
}

View File

@ -889,9 +889,9 @@ Input:
var n uint64
var err error
if i >= 3 && s[1] == 'x' {
n, err = strconv.Btoui64(s[2:], 16)
n, err = strconv.ParseUint(s[2:], 16, 64)
} else {
n, err = strconv.Btoui64(s[1:], 10)
n, err = strconv.ParseUint(s[1:], 10, 64)
}
if err == nil && n <= unicode.MaxRune {
text = string(n)

View File

@ -226,7 +226,7 @@ func parseDecomposition(s string, skipfirst bool) (a []rune, e error) {
decomp = decomp[1:]
}
for _, d := range decomp {
point, err := strconv.Btoui64(d, 16)
point, err := strconv.ParseUint(d, 16, 64)
if err != nil {
return a, err
}
@ -240,7 +240,7 @@ func parseCharacter(line string) {
if len(field) != NumField {
logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField)
}
x, err := strconv.Btoui64(field[FCodePoint], 16)
x, err := strconv.ParseUint(field[FCodePoint], 16, 64)
point := int(x)
if err != nil {
logger.Fatalf("%.5s...: %s", line, err)
@ -264,7 +264,7 @@ func parseCharacter(line string) {
if state != SLast {
firstChar = lastChar
}
x, err = strconv.Atoui64(field[FCanonicalCombiningClass])
x, err = strconv.ParseUint(field[FCanonicalCombiningClass], 10, 64)
if err != nil {
logger.Fatalf("%U: bad ccc field: %s", int(x), err)
}
@ -336,7 +336,7 @@ func parseExclusion(line string) int {
if len(matches) != 2 {
logger.Fatalf("%s: %d matches (expected 1)\n", line, len(matches))
}
point, err := strconv.Btoui64(matches[1], 16)
point, err := strconv.ParseUint(matches[1], 16, 64)
if err != nil {
logger.Fatalf("%.5s...: %s", line, err)
}
@ -792,13 +792,13 @@ func testDerived() {
continue
}
rng := strings.Split(qc[1], "..")
i, err := strconv.Btoui64(rng[0], 16)
i, err := strconv.ParseUint(rng[0], 16, 64)
if err != nil {
log.Fatal(err)
}
j := i
if len(rng) > 1 {
j, err = strconv.Btoui64(rng[1], 16)
j, err = strconv.ParseUint(rng[1], 16, 64)
if err != nil {
log.Fatal(err)
}

View File

@ -171,7 +171,7 @@ func loadTestData() {
counter++
for j := 1; j < len(m)-1; j++ {
for _, split := range strings.Split(m[j], " ") {
r, err := strconv.Btoui64(split, 16)
r, err := strconv.ParseUint(split, 16, 64)
if err != nil {
logger.Fatal(err)
}

View File

@ -95,7 +95,7 @@ func convertAssign(dest, src interface{}) error {
switch dv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
s := asString(src)
i64, err := strconv.Atoi64(s)
i64, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
@ -106,7 +106,7 @@ func convertAssign(dest, src interface{}) error {
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
s := asString(src)
u64, err := strconv.Atoui64(s)
u64, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
@ -117,7 +117,7 @@ func convertAssign(dest, src interface{}) error {
return nil
case reflect.Float32, reflect.Float64:
s := asString(src)
f64, err := strconv.Atof64(s)
f64, err := strconv.ParseFloat(s, 64)
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}

View File

@ -54,13 +54,13 @@ func (boolType) ConvertValue(src interface{}) (interface{}, error) {
case bool:
return s, nil
case string:
b, err := strconv.Atob(s)
b, err := strconv.ParseBool(s)
if err != nil {
return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
}
return b, nil
case []byte:
b, err := strconv.Atob(string(s))
b, err := strconv.ParseBool(string(s))
if err != nil {
return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
}

View File

@ -77,12 +77,12 @@ var DefaultCipherOrder = []string{
var cipherModes = map[string]*cipherMode{
// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
// are defined in the order specified in the RFC.
"aes128-ctr": &cipherMode{16, aes.BlockSize, 0, newAESCTR},
"aes192-ctr": &cipherMode{24, aes.BlockSize, 0, newAESCTR},
"aes256-ctr": &cipherMode{32, aes.BlockSize, 0, newAESCTR},
"aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
"aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
"aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
// They are defined in the order specified in the RFC.
"arcfour128": &cipherMode{16, 0, 1536, newRC4},
"arcfour256": &cipherMode{32, 0, 1536, newRC4},
"arcfour128": {16, 0, 1536, newRC4},
"arcfour256": {32, 0, 1536, newRC4},
}

View File

@ -200,7 +200,7 @@ func (c *ClientConn) mainLoop() {
peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 {
packet = packet[9:]
c.getChan(peersId).data <- packet[:length]
c.getChan(peersId).stdout.data <- packet[:length]
}
case msgChannelExtendedData:
if len(packet) < 13 {
@ -215,7 +215,7 @@ func (c *ClientConn) mainLoop() {
// for stderr on interactive sessions. Other data types are
// silently discarded.
if datatype == 1 {
c.getChan(peersId).dataExt <- packet[:length]
c.getChan(peersId).stderr.data <- packet[:length]
}
}
default:
@ -228,9 +228,9 @@ func (c *ClientConn) mainLoop() {
c.getChan(msg.PeersId).msg <- msg
case *channelCloseMsg:
ch := c.getChan(msg.PeersId)
close(ch.win)
close(ch.data)
close(ch.dataExt)
close(ch.stdin.win)
close(ch.stdout.data)
close(ch.stderr.data)
c.chanlist.remove(msg.PeersId)
case *channelEOFMsg:
c.getChan(msg.PeersId).msg <- msg
@ -241,7 +241,7 @@ func (c *ClientConn) mainLoop() {
case *channelRequestMsg:
c.getChan(msg.PeersId).msg <- msg
case *windowAdjustMsg:
c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes)
c.getChan(msg.PeersId).stdin.win <- int(msg.AdditionalBytes)
default:
fmt.Printf("mainLoop: unhandled message %T: %v\n", msg, msg)
}
@ -290,21 +290,49 @@ func (c *ClientConfig) rand() io.Reader {
type clientChan struct {
packetWriter
id, peersId uint32
data chan []byte // receives the payload of channelData messages
dataExt chan []byte // receives the payload of channelExtendedData messages
win chan int // receives window adjustments
stdin *chanWriter // receives window adjustments
stdout *chanReader // receives the payload of channelData messages
stderr *chanReader // receives the payload of channelExtendedData messages
msg chan interface{} // incoming messages
}
// newClientChan returns a partially constructed *clientChan
// using the local id provided. To be usable clientChan.peersId
// needs to be assigned once known.
func newClientChan(t *transport, id uint32) *clientChan {
return &clientChan{
c := &clientChan{
packetWriter: t,
id: id,
data: make(chan []byte, 16),
dataExt: make(chan []byte, 16),
win: make(chan int, 16),
msg: make(chan interface{}, 16),
}
c.stdin = &chanWriter{
win: make(chan int, 16),
clientChan: c,
}
c.stdout = &chanReader{
data: make(chan []byte, 16),
clientChan: c,
}
c.stderr = &chanReader{
data: make(chan []byte, 16),
clientChan: c,
}
return c
}
// waitForChannelOpenResponse, if successful, fills out
// the peerId and records any initial window advertisement.
func (c *clientChan) waitForChannelOpenResponse() error {
switch msg := (<-c.msg).(type) {
case *channelOpenConfirmMsg:
// fixup peersId field
c.peersId = msg.MyId
c.stdin.win <- int(msg.MyWindow)
return nil
case *channelOpenFailureMsg:
return errors.New(safeString(msg.Message))
}
return errors.New("unexpected packet")
}
// Close closes the channel. This does not close the underlying connection.
@ -355,10 +383,9 @@ func (c *chanlist) remove(id uint32) {
// A chanWriter represents the stdin of a remote process.
type chanWriter struct {
win chan int // receives window adjustments
peersId uint32 // the peer's id
rwin int // current rwin size
packetWriter // for sending channelDataMsg
win chan int // receives window adjustments
rwin int // current rwin size
clientChan *clientChan // the channel backing this writer
}
// Write writes data to the remote process's standard input.
@ -372,12 +399,13 @@ func (w *chanWriter) Write(data []byte) (n int, err error) {
w.rwin += win
continue
}
peersId := w.clientChan.peersId
n = len(data)
packet := make([]byte, 0, 9+n)
packet = append(packet, msgChannelData,
byte(w.peersId>>24), byte(w.peersId>>16), byte(w.peersId>>8), byte(w.peersId),
byte(peersId>>24), byte(peersId>>16), byte(peersId>>8), byte(peersId),
byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
err = w.writePacket(append(packet, data...))
err = w.clientChan.writePacket(append(packet, data...))
w.rwin -= n
return
}
@ -385,7 +413,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) {
}
func (w *chanWriter) Close() error {
return w.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.peersId}))
return w.clientChan.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.clientChan.peersId}))
}
// A chanReader represents stdout or stderr of a remote process.
@ -393,10 +421,9 @@ type chanReader struct {
// TODO(dfc) a fixed size channel may not be the right data structure.
// If writes to this channel block, they will block mainLoop, making
// it unable to receive new messages from the remote side.
data chan []byte // receives data from remote
peersId uint32 // the peer's id
packetWriter // for sending windowAdjustMsg
buf []byte
data chan []byte // receives data from remote
clientChan *clientChan // the channel backing this reader
buf []byte
}
// Read reads data from the remote process's stdout or stderr.
@ -407,10 +434,10 @@ func (r *chanReader) Read(data []byte) (int, error) {
n := copy(data, r.buf)
r.buf = r.buf[n:]
msg := windowAdjustMsg{
PeersId: r.peersId,
PeersId: r.clientChan.peersId,
AdditionalBytes: uint32(n),
}
return n, r.writePacket(marshal(msgChannelWindowAdjust, msg))
return n, r.clientChan.writePacket(marshal(msgChannelWindowAdjust, msg))
}
r.buf, ok = <-r.data
if !ok {

View File

@ -9,7 +9,7 @@ import (
"io"
)
// authenticate authenticates with the remote server. See RFC 4252.
// authenticate authenticates with the remote server. See RFC 4252.
func (c *ClientConn) authenticate(session []byte) error {
// initiate user auth session
if err := c.writePacket(marshal(msgServiceRequest, serviceRequestMsg{serviceUserAuth})); err != nil {
@ -24,7 +24,7 @@ func (c *ClientConn) authenticate(session []byte) error {
return err
}
// during the authentication phase the client first attempts the "none" method
// then any untried methods suggested by the server.
// then any untried methods suggested by the server.
tried, remain := make(map[string]bool), make(map[string]bool)
for auth := ClientAuth(new(noneAuth)); auth != nil; {
ok, methods, err := auth.auth(session, c.config.User, c.transport, c.config.rand())
@ -57,9 +57,9 @@ func (c *ClientConn) authenticate(session []byte) error {
// A ClientAuth represents an instance of an RFC 4252 authentication method.
type ClientAuth interface {
// auth authenticates user over transport t.
// auth authenticates user over transport t.
// Returns true if authentication is successful.
// If authentication is not successful, a []string of alternative
// If authentication is not successful, a []string of alternative
// method names is returned.
auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error)
@ -79,19 +79,7 @@ func (n *noneAuth) auth(session []byte, user string, t *transport, rand io.Reade
return false, nil, err
}
packet, err := t.readPacket()
if err != nil {
return false, nil, err
}
switch packet[0] {
case msgUserAuthSuccess:
return true, nil, nil
case msgUserAuthFailure:
msg := decode(packet).(*userAuthFailureMsg)
return false, msg.Methods, nil
}
return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
return handleAuthResponse(t)
}
func (n *noneAuth) method() string {
@ -127,19 +115,7 @@ func (p *passwordAuth) auth(session []byte, user string, t *transport, rand io.R
return false, nil, err
}
packet, err := t.readPacket()
if err != nil {
return false, nil, err
}
switch packet[0] {
case msgUserAuthSuccess:
return true, nil, nil
case msgUserAuthFailure:
msg := decode(packet).(*userAuthFailureMsg)
return false, msg.Methods, nil
}
return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
return handleAuthResponse(t)
}
func (p *passwordAuth) method() string {
@ -159,7 +135,7 @@ func ClientAuthPassword(impl ClientPassword) ClientAuth {
// ClientKeyring implements access to a client key ring.
type ClientKeyring interface {
// Key returns the i'th rsa.Publickey or dsa.Publickey, or nil if
// Key returns the i'th rsa.Publickey or dsa.Publickey, or nil if
// no key exists at i.
Key(i int) (key interface{}, err error)
@ -173,27 +149,28 @@ type publickeyAuth struct {
ClientKeyring
}
type publickeyAuthMsg struct {
User string
Service string
Method string
// HasSig indicates to the reciver packet that the auth request is signed and
// should be used for authentication of the request.
HasSig bool
Algoname string
Pubkey string
// Sig is defined as []byte so marshal will exclude it during validateKey
Sig []byte `ssh:"rest"`
}
func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) {
type publickeyAuthMsg struct {
User string
Service string
Method string
// HasSig indicates to the reciver packet that the auth request is signed and
// should be used for authentication of the request.
HasSig bool
Algoname string
Pubkey string
// Sig is defined as []byte so marshal will exclude it during the query phase
Sig []byte `ssh:"rest"`
}
// Authentication is performed in two stages. The first stage sends an
// enquiry to test if each key is acceptable to the remote. The second
// stage attempts to authenticate with the valid keys obtained in the
// stage attempts to authenticate with the valid keys obtained in the
// first stage.
var index int
// a map of public keys to their index in the keyring
// a map of public keys to their index in the keyring
validKeys := make(map[int]interface{})
for {
key, err := p.Key(index)
@ -204,33 +181,13 @@ func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io.
// no more keys in the keyring
break
}
pubkey := serializePublickey(key)
algoname := algoName(key)
msg := publickeyAuthMsg{
User: user,
Service: serviceSSH,
Method: p.method(),
HasSig: false,
Algoname: algoname,
Pubkey: string(pubkey),
}
if err := t.writePacket(marshal(msgUserAuthRequest, msg)); err != nil {
return false, nil, err
}
packet, err := t.readPacket()
if err != nil {
return false, nil, err
}
switch packet[0] {
case msgUserAuthPubKeyOk:
msg := decode(packet).(*userAuthPubKeyOkMsg)
if msg.Algo != algoname || msg.PubKey != string(pubkey) {
continue
}
if ok, err := p.validateKey(key, user, t); ok {
validKeys[index] = key
case msgUserAuthFailure:
default:
return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
} else {
if err != nil {
return false, nil, err
}
}
index++
}
@ -265,26 +222,63 @@ func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io.
if err := t.writePacket(p); err != nil {
return false, nil, err
}
packet, err := t.readPacket()
success, methods, err := handleAuthResponse(t)
if err != nil {
return false, nil, err
}
switch packet[0] {
case msgUserAuthSuccess:
return true, nil, nil
case msgUserAuthFailure:
msg := decode(packet).(*userAuthFailureMsg)
methods = msg.Methods
continue
case msgDisconnect:
return false, nil, io.EOF
default:
return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
if success {
return success, methods, err
}
}
return false, methods, nil
}
// validateKey validates the key provided it is acceptable to the server.
func (p *publickeyAuth) validateKey(key interface{}, user string, t *transport) (bool, error) {
pubkey := serializePublickey(key)
algoname := algoName(key)
msg := publickeyAuthMsg{
User: user,
Service: serviceSSH,
Method: p.method(),
HasSig: false,
Algoname: algoname,
Pubkey: string(pubkey),
}
if err := t.writePacket(marshal(msgUserAuthRequest, msg)); err != nil {
return false, err
}
return p.confirmKeyAck(key, t)
}
func (p *publickeyAuth) confirmKeyAck(key interface{}, t *transport) (bool, error) {
pubkey := serializePublickey(key)
algoname := algoName(key)
for {
packet, err := t.readPacket()
if err != nil {
return false, err
}
switch packet[0] {
case msgUserAuthBanner:
// TODO(gpaul): add callback to present the banner to the user
case msgUserAuthPubKeyOk:
msg := decode(packet).(*userAuthPubKeyOkMsg)
if msg.Algo != algoname || msg.PubKey != string(pubkey) {
return false, nil
}
return true, nil
case msgUserAuthFailure:
return false, nil
default:
return false, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
}
}
panic("unreachable")
}
func (p *publickeyAuth) method() string {
return "publickey"
}
@ -293,3 +287,30 @@ func (p *publickeyAuth) method() string {
func ClientAuthPublickey(impl ClientKeyring) ClientAuth {
return &publickeyAuth{impl}
}
// handleAuthResponse returns whether the preceding authentication request succeeded
// along with a list of remaining authentication methods to try next and
// an error if an unexpected response was received.
func handleAuthResponse(t *transport) (bool, []string, error) {
for {
packet, err := t.readPacket()
if err != nil {
return false, nil, err
}
switch packet[0] {
case msgUserAuthBanner:
// TODO: add callback to present the banner to the user
case msgUserAuthFailure:
msg := decode(packet).(*userAuthFailureMsg)
return false, msg.Methods, nil
case msgUserAuthSuccess:
return true, nil, nil
case msgDisconnect:
return false, nil, io.EOF
default:
return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]}
}
}
panic("unreachable")
}

View File

@ -7,17 +7,20 @@ package ssh
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/dsa"
"crypto/rsa"
_ "crypto/sha1"
"crypto/x509"
"encoding/pem"
"errors"
"io"
"io/ioutil"
"math/big"
"testing"
)
const _pem = `-----BEGIN RSA PRIVATE KEY-----
// private key for mock server
const testServerPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA19lGVsTqIT5iiNYRgnoY1CwkbETW5cq+Rzk5v/kTlf31XpSU
70HVWkbTERECjaYdXM2gGcbb+sxpq6GtXf1M3kVomycqhxwhPv4Cr6Xp4WT/jkFx
9z+FFzpeodGJWjOH6L2H5uX1Cvr9EDdQp9t9/J32/qBFntY8GwoUI/y/1MSTmMiF
@ -45,25 +48,32 @@ gqnBycHj6AhEycjda75cs+0zybZvN4x65KZHOGW/O/7OAWEcZP5TPb3zf9ned3Hl
NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw==
-----END RSA PRIVATE KEY-----`
// reused internally by tests
var serverConfig = new(ServerConfig)
func init() {
if err := serverConfig.SetRSAPrivateKey([]byte(_pem)); err != nil {
panic("unable to set private key: " + err.Error())
}
}
const testClientPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld
r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ
tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC
nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW
2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB
y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr
rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg==
-----END RSA PRIVATE KEY-----`
// keychain implements the ClientPublickey interface
type keychain struct {
keys []*rsa.PrivateKey
keys []interface{}
}
func (k *keychain) Key(i int) (interface{}, error) {
if i < 0 || i >= len(k.keys) {
return nil, nil
}
return k.keys[i].PublicKey, nil
switch key := k.keys[i].(type) {
case *rsa.PrivateKey:
return key.PublicKey, nil
case *dsa.PrivateKey:
return key.PublicKey, nil
}
panic("unknown key type")
}
func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
@ -71,7 +81,11 @@ func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err err
h := hashFunc.New()
h.Write(data)
digest := h.Sum(nil)
return rsa.SignPKCS1v15(rand, k.keys[i], hashFunc, digest)
switch key := k.keys[i].(type) {
case *rsa.PrivateKey:
return rsa.SignPKCS1v15(rand, key, hashFunc, digest)
}
return nil, errors.New("unknown key type")
}
func (k *keychain) loadPEM(file string) error {
@ -91,61 +105,6 @@ func (k *keychain) loadPEM(file string) error {
return nil
}
var pkey *rsa.PrivateKey
func init() {
var err error
pkey, err = rsa.GenerateKey(rand.Reader, 512)
if err != nil {
panic("unable to generate public key")
}
}
func TestClientAuthPublickey(t *testing.T) {
k := new(keychain)
k.keys = append(k.keys, pkey)
serverConfig.PubKeyCallback = func(user, algo string, pubkey []byte) bool {
expected := []byte(serializePublickey(k.keys[0].PublicKey))
algoname := algoName(k.keys[0].PublicKey)
return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected)
}
serverConfig.PasswordCallback = nil
l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
if err != nil {
t.Fatalf("unable to listen: %s", err)
}
defer l.Close()
done := make(chan bool, 1)
go func() {
c, err := l.Accept()
if err != nil {
t.Fatal(err)
}
defer c.Close()
if err := c.Handshake(); err != nil {
t.Error(err)
}
done <- true
}()
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPublickey(k),
},
}
c, err := Dial("tcp", l.Addr().String(), config)
if err != nil {
t.Fatalf("unable to dial remote side: %s", err)
}
defer c.Close()
<-done
}
// password implements the ClientPassword interface
type password string
@ -153,96 +112,146 @@ func (p password) Password(user string) (string, error) {
return string(p), nil
}
func TestClientAuthPassword(t *testing.T) {
pw := password("tiger")
serverConfig.PasswordCallback = func(user, pass string) bool {
return user == "testuser" && pass == string(pw)
// reused internally by tests
var (
rsakey *rsa.PrivateKey
dsakey *dsa.PrivateKey
clientKeychain = new(keychain)
clientPassword = password("tiger")
serverConfig = &ServerConfig{
PasswordCallback: func(user, pass string) bool {
return user == "testuser" && pass == string(clientPassword)
},
PubKeyCallback: func(user, algo string, pubkey []byte) bool {
key := clientKeychain.keys[0].(*rsa.PrivateKey).PublicKey
expected := []byte(serializePublickey(key))
algoname := algoName(key)
return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected)
},
}
serverConfig.PubKeyCallback = nil
)
func init() {
if err := serverConfig.SetRSAPrivateKey([]byte(testServerPrivateKey)); err != nil {
panic("unable to set private key: " + err.Error())
}
block, _ := pem.Decode([]byte(testClientPrivateKey))
rsakey, _ = x509.ParsePKCS1PrivateKey(block.Bytes)
clientKeychain.keys = append(clientKeychain.keys, rsakey)
dsakey = new(dsa.PrivateKey)
// taken from crypto/dsa/dsa_test.go
dsakey.P, _ = new(big.Int).SetString("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF", 16)
dsakey.Q, _ = new(big.Int).SetString("E1D3391245933D68A0714ED34BBCB7A1F422B9C1", 16)
dsakey.G, _ = new(big.Int).SetString("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA", 16)
dsakey.Y, _ = new(big.Int).SetString("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2", 16)
dsakey.X, _ = new(big.Int).SetString("5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A", 16)
}
// newMockAuthServer creates a new Server bound to
// the loopback interface. The server exits after
// processing one handshake.
func newMockAuthServer(t *testing.T) string {
l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
if err != nil {
t.Fatalf("unable to listen: %s", err)
t.Fatalf("unable to newMockAuthServer: %s", err)
}
defer l.Close()
done := make(chan bool)
go func() {
defer l.Close()
c, err := l.Accept()
defer c.Close()
if err != nil {
t.Fatal(err)
t.Errorf("Unable to accept incoming connection: %v", err)
return
}
if err := c.Handshake(); err != nil {
t.Error(err)
// not Errorf because this is expected to
// fail for some tests.
t.Logf("Handshaking error: %v", err)
return
}
defer c.Close()
done <- true
}()
return l.Addr().String()
}
func TestClientAuthPublickey(t *testing.T) {
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPassword(pw),
ClientAuthPublickey(clientKeychain),
},
}
c, err := Dial("tcp", l.Addr().String(), config)
c, err := Dial("tcp", newMockAuthServer(t), config)
if err != nil {
t.Fatalf("unable to dial remote side: %s", err)
}
defer c.Close()
<-done
c.Close()
}
func TestClientAuthPasswordAndPublickey(t *testing.T) {
pw := password("tiger")
serverConfig.PasswordCallback = func(user, pass string) bool {
return user == "testuser" && pass == string(pw)
func TestClientAuthPassword(t *testing.T) {
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPassword(clientPassword),
},
}
k := new(keychain)
k.keys = append(k.keys, pkey)
serverConfig.PubKeyCallback = func(user, algo string, pubkey []byte) bool {
expected := []byte(serializePublickey(k.keys[0].PublicKey))
algoname := algoName(k.keys[0].PublicKey)
return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected)
}
l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
c, err := Dial("tcp", newMockAuthServer(t), config)
if err != nil {
t.Fatalf("unable to listen: %s", err)
t.Fatalf("unable to dial remote side: %s", err)
}
defer l.Close()
done := make(chan bool)
go func() {
c, err := l.Accept()
if err != nil {
t.Fatal(err)
}
if err := c.Handshake(); err != nil {
t.Error(err)
}
defer c.Close()
done <- true
}()
c.Close()
}
func TestClientAuthWrongPassword(t *testing.T) {
wrongPw := password("wrong")
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPassword(wrongPw),
ClientAuthPublickey(k),
ClientAuthPublickey(clientKeychain),
},
}
c, err := Dial("tcp", l.Addr().String(), config)
c, err := Dial("tcp", newMockAuthServer(t), config)
if err != nil {
t.Fatalf("unable to dial remote side: %s", err)
}
defer c.Close()
<-done
c.Close()
}
// the mock server will only authenticate ssh-rsa keys
func TestClientAuthInvalidPublickey(t *testing.T) {
kc := new(keychain)
kc.keys = append(kc.keys, dsakey)
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPublickey(kc),
},
}
c, err := Dial("tcp", newMockAuthServer(t), config)
if err == nil {
c.Close()
t.Fatalf("dsa private key should not have authenticated with rsa public key")
}
}
// the client should authenticate with the second key
func TestClientAuthRSAandDSA(t *testing.T) {
kc := new(keychain)
kc.keys = append(kc.keys, dsakey, rsakey)
config := &ClientConfig{
User: "testuser",
Auth: []ClientAuth{
ClientAuthPublickey(kc),
},
}
c, err := Dial("tcp", newMockAuthServer(t), config)
if err != nil {
t.Fatalf("client could not authenticate with rsa key: %v", err)
}
c.Close()
}

View File

@ -8,15 +8,15 @@ import (
"testing"
)
var strings = map[string]string{
"\x20\x0d\x0a": "\x20\x0d\x0a",
"flibble": "flibble",
"new\x20line": "new\x20line",
"123456\x07789": "123456 789",
"\t\t\x10\r\n": "\t\t \r\n",
}
func TestSafeString(t *testing.T) {
strings := map[string]string{
"\x20\x0d\x0a": "\x20\x0d\x0a",
"flibble": "flibble",
"new\x20line": "new\x20line",
"123456\x07789": "123456 789",
"\t\t\x10\r\n": "\t\t \r\n",
}
for s, expected := range strings {
actual := safeString(s)
if expected != actual {

View File

@ -285,13 +285,8 @@ func (s *Session) stdin() error {
s.Stdin = new(bytes.Buffer)
}
s.copyFuncs = append(s.copyFuncs, func() error {
w := &chanWriter{
packetWriter: s,
peersId: s.peersId,
win: s.win,
}
_, err := io.Copy(w, s.Stdin)
if err1 := w.Close(); err == nil {
_, err := io.Copy(s.clientChan.stdin, s.Stdin)
if err1 := s.clientChan.stdin.Close(); err == nil {
err = err1
}
return err
@ -304,12 +299,7 @@ func (s *Session) stdout() error {
s.Stdout = ioutil.Discard
}
s.copyFuncs = append(s.copyFuncs, func() error {
r := &chanReader{
packetWriter: s,
peersId: s.peersId,
data: s.data,
}
_, err := io.Copy(s.Stdout, r)
_, err := io.Copy(s.Stdout, s.clientChan.stdout)
return err
})
return nil
@ -320,12 +310,7 @@ func (s *Session) stderr() error {
s.Stderr = ioutil.Discard
}
s.copyFuncs = append(s.copyFuncs, func() error {
r := &chanReader{
packetWriter: s,
peersId: s.peersId,
data: s.dataExt,
}
_, err := io.Copy(s.Stderr, r)
_, err := io.Copy(s.Stderr, s.clientChan.stderr)
return err
})
return nil
@ -398,19 +383,11 @@ func (c *ClientConn) NewSession() (*Session, error) {
c.chanlist.remove(ch.id)
return nil, err
}
// wait for response
msg := <-ch.msg
switch msg := msg.(type) {
case *channelOpenConfirmMsg:
ch.peersId = msg.MyId
ch.win <- int(msg.MyWindow)
return &Session{
clientChan: ch,
}, nil
case *channelOpenFailureMsg:
if err := ch.waitForChannelOpenResponse(); err != nil {
c.chanlist.remove(ch.id)
return nil, fmt.Errorf("ssh: channel open failed: %s", msg.Message)
return nil, fmt.Errorf("ssh: unable to open session: %v", err)
}
c.chanlist.remove(ch.id)
return nil, fmt.Errorf("ssh: unexpected message %T: %v", msg, msg)
return &Session{
clientChan: ch,
}, nil
}

View File

@ -61,7 +61,7 @@ func dial(t *testing.T) *ClientConn {
WantReply bool
Status uint32
}
// TODO(dfc) casting to the concrete type should not be
// TODO(dfc) converting to the concrete type should not be
// necessary to send a packet.
msg := exitMsg{
PeersId: ch.(*channel).theirId,

View File

@ -6,6 +6,7 @@ package ssh
import (
"errors"
"fmt"
"io"
"net"
)
@ -42,20 +43,21 @@ func (c *ClientConn) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, err
}, nil
}
// RFC 4254 7.2
type channelOpenDirectMsg struct {
ChanType string
PeersId uint32
PeersWindow uint32
MaxPacketSize uint32
raddr string
rport uint32
laddr string
lport uint32
}
// dial opens a direct-tcpip connection to the remote server. laddr and raddr are passed as
// strings and are expected to be resolveable at the remote end.
func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tcpchan, error) {
// RFC 4254 7.2
type channelOpenDirectMsg struct {
ChanType string
PeersId uint32
PeersWindow uint32
MaxPacketSize uint32
raddr string
rport uint32
laddr string
lport uint32
}
ch := c.newChan(c.transport)
if err := c.writePacket(marshal(msgChannelOpen, channelOpenDirectMsg{
ChanType: "direct-tcpip",
@ -70,30 +72,14 @@ func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tc
c.chanlist.remove(ch.id)
return nil, err
}
// wait for response
switch msg := (<-ch.msg).(type) {
case *channelOpenConfirmMsg:
ch.peersId = msg.MyId
ch.win <- int(msg.MyWindow)
case *channelOpenFailureMsg:
if err := ch.waitForChannelOpenResponse(); err != nil {
c.chanlist.remove(ch.id)
return nil, errors.New("ssh: error opening remote TCP connection: " + msg.Message)
default:
c.chanlist.remove(ch.id)
return nil, errors.New("ssh: unexpected packet")
return nil, fmt.Errorf("ssh: unable to open direct tcpip connection: %v", err)
}
return &tcpchan{
clientChan: ch,
Reader: &chanReader{
packetWriter: ch,
peersId: ch.peersId,
data: ch.data,
},
Writer: &chanWriter{
packetWriter: ch,
peersId: ch.peersId,
win: ch.win,
},
Reader: ch.stdout,
Writer: ch.stdin,
}, nil
}

View File

@ -305,7 +305,7 @@ func (p *gcParser) parseArrayType() Type {
lit := p.expect(scanner.Int)
p.expect(']')
elt := p.parseType()
n, err := strconv.Atoui64(lit)
n, err := strconv.ParseUint(lit, 10, 64)
if err != nil {
p.error(err)
}
@ -323,7 +323,7 @@ func (p *gcParser) parseMapType() Type {
return &Map{Key: key, Elt: elt}
}
// Name = identifier | "?" .
// Name = identifier | "?" | ExportedName .
//
func (p *gcParser) parseName() (name string) {
switch p.tok {
@ -333,6 +333,9 @@ func (p *gcParser) parseName() (name string) {
case '?':
// anonymous
p.next()
case '@':
// exported name prefixed with package path
_, name = p.parseExportedName()
default:
p.error("name expected")
}
@ -619,10 +622,11 @@ func (p *gcParser) parseNumber() Const {
// exponent (base 2)
p.next()
sign, val = p.parseInt()
exp, err := strconv.Atoui(val)
exp64, err := strconv.ParseUint(val, 10, 0)
if err != nil {
p.error(err)
}
exp := uint(exp64)
if sign == "-" {
denom := big.NewInt(1)
denom.Lsh(denom, exp)
@ -747,7 +751,7 @@ func (p *gcParser) parseFuncDecl() {
}
}
// MethodDecl = "func" Receiver identifier Signature .
// MethodDecl = "func" Receiver Name Signature .
// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ].
//
func (p *gcParser) parseMethodDecl() {
@ -755,7 +759,7 @@ func (p *gcParser) parseMethodDecl() {
p.expect('(')
p.parseParameter() // receiver
p.expect(')')
p.expect(scanner.Ident)
p.parseName() // unexported method names in imports are qualified with their package.
p.parseSignature()
if p.tok == '{' {
p.parseFuncBody()

View File

@ -44,7 +44,7 @@ type Int struct {
mu sync.Mutex
}
func (v *Int) String() string { return strconv.Itoa64(v.i) }
func (v *Int) String() string { return strconv.FormatInt(v.i, 10) }
func (v *Int) Add(delta int64) {
v.mu.Lock()
@ -64,7 +64,7 @@ type Float struct {
mu sync.Mutex
}
func (v *Float) String() string { return strconv.Ftoa64(v.f, 'g', -1) }
func (v *Float) String() string { return strconv.FormatFloat(v.f, 'g', -1, 64) }
// Add adds delta to v.
func (v *Float) Add(delta float64) {

View File

@ -79,7 +79,7 @@ func newBoolValue(val bool, p *bool) *boolValue {
}
func (b *boolValue) Set(s string) bool {
v, err := strconv.Atob(s)
v, err := strconv.ParseBool(s)
*b = boolValue(v)
return err == nil
}
@ -95,7 +95,7 @@ func newIntValue(val int, p *int) *intValue {
}
func (i *intValue) Set(s string) bool {
v, err := strconv.Btoi64(s, 0)
v, err := strconv.ParseInt(s, 0, 64)
*i = intValue(v)
return err == nil
}
@ -111,7 +111,7 @@ func newInt64Value(val int64, p *int64) *int64Value {
}
func (i *int64Value) Set(s string) bool {
v, err := strconv.Btoi64(s, 0)
v, err := strconv.ParseInt(s, 0, 64)
*i = int64Value(v)
return err == nil
}
@ -127,7 +127,7 @@ func newUintValue(val uint, p *uint) *uintValue {
}
func (i *uintValue) Set(s string) bool {
v, err := strconv.Btoui64(s, 0)
v, err := strconv.ParseUint(s, 0, 64)
*i = uintValue(v)
return err == nil
}
@ -143,7 +143,7 @@ func newUint64Value(val uint64, p *uint64) *uint64Value {
}
func (i *uint64Value) Set(s string) bool {
v, err := strconv.Btoui64(s, 0)
v, err := strconv.ParseUint(s, 0, 64)
*i = uint64Value(v)
return err == nil
}
@ -174,7 +174,7 @@ func newFloat64Value(val float64, p *float64) *float64Value {
}
func (f *float64Value) Set(s string) bool {
v, err := strconv.Atof64(s)
v, err := strconv.ParseFloat(s, 64)
*f = float64Value(v)
return err == nil
}

View File

@ -89,18 +89,22 @@
If an operand implements interface Formatter, that interface
can be used for fine control of formatting.
Next, if an operand implements the error interface, the Error method
If the format (which is implicitly %v for Println etc.) is valid
for a string (%s %q %v %x %X), the following two rules also apply:
1. If an operand implements the error interface, the Error method
will be used to convert the object to a string, which will then
be formatted as required by the verb (if any).
Finally, if an operand implements method String() string that method
2. If an operand implements method String() string, that method
will be used to convert the object to a string, which will then
be formatted as required by the verb (if any).
To avoid recursion in cases such as
type X int
func (x X) String() string { return Sprintf("%d", x) }
cast the value before recurring:
func (x X) String() string { return Sprintf("%d", int(x)) }
type X string
func (x X) String() string { return Sprintf("<%s>", x) }
convert the value before recurring:
func (x X) String() string { return Sprintf("<%s>", string(x)) }
Format errors:

View File

@ -12,6 +12,7 @@ import (
"runtime" // for the malloc count test only
"strings"
"testing"
"time"
)
type (
@ -352,7 +353,7 @@ var fmttests = []struct {
{"%s", I(23), `<23>`},
{"%q", I(23), `"<23>"`},
{"%x", I(23), `3c32333e`},
{"%d", I(23), `%!d(string=<23>)`},
{"%d", I(23), `23`}, // Stringer applies only to string formats.
// go syntax
{"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
@ -361,8 +362,8 @@ var fmttests = []struct {
{"%#v", make(chan int), "(chan int)(0xPTR)"},
{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
{"%#v", 1000000000, "1000000000"},
{"%#v", map[string]int{"a": 1}, `map[string] int{"a":1}`},
{"%#v", map[string]B{"a": {1, 2}}, `map[string] fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
{"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
{"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
{"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
{"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
{"%#v", []int(nil), `[]int(nil)`},
@ -371,8 +372,8 @@ var fmttests = []struct {
{"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
{"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
{"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
{"%#v", map[int]byte(nil), `map[int] uint8(nil)`},
{"%#v", map[int]byte{}, `map[int] uint8{}`},
{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
{"%#v", map[int]byte{}, `map[int]uint8{}`},
// slices with other formats
{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
@ -430,6 +431,10 @@ var fmttests = []struct {
{"%p", make([]int, 1), "0xPTR"},
{"%p", 27, "%!p(int=27)"}, // not a pointer at all
// %d on Stringer should give integer if possible
{"%s", time.Time{}.Month(), "January"},
{"%d", time.Time{}.Month(), "1"},
// erroneous things
{"%s %", "hello", "hello %!(NOVERB)"},
{"%s %.2", "hello", "hello %!(NOVERB)"},
@ -495,69 +500,84 @@ func BenchmarkSprintfPrefixedInt(b *testing.B) {
}
}
func BenchmarkSprintfFloat(b *testing.B) {
for i := 0; i < b.N; i++ {
Sprintf("%g", 5.23184)
}
}
func TestCountMallocs(t *testing.T) {
if testing.Short() {
return
}
const N = 100
runtime.UpdateMemStats()
mallocs := 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
Sprintf("")
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/100)
Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
Sprintf("xxx")
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/100)
Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
Sprintf("%x", i)
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/100)
Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
Sprintf("%s", "hello")
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/100)
Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
Sprintf("%x %x", i, i)
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/100)
Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < N; i++ {
Sprintf("%g", 3.14159)
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Sprintf(\"%%g\"): %d\n", mallocs/N)
buf := new(bytes.Buffer)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
buf.Reset()
Fprintf(buf, "%x %x %x", i, i, i)
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/100)
Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/N)
runtime.UpdateMemStats()
mallocs = 0 - runtime.MemStats.Mallocs
for i := 0; i < 100; i++ {
for i := 0; i < N; i++ {
buf.Reset()
Fprintf(buf, "%s", "hello")
}
runtime.UpdateMemStats()
mallocs += runtime.MemStats.Mallocs
Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/100)
Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/N)
}
type flagPrinter struct{}
@ -772,9 +792,9 @@ var panictests = []struct {
out string
}{
// String
{"%d", (*Panic)(nil), "<nil>"}, // nil pointer special case
{"%d", Panic{io.ErrUnexpectedEOF}, "%d(PANIC=unexpected EOF)"},
{"%d", Panic{3}, "%d(PANIC=3)"},
{"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
{"%s", Panic{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
{"%s", Panic{3}, "%s(PANIC=3)"},
// GoString
{"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
{"%#v", Panic{io.ErrUnexpectedEOF}, "%v(PANIC=unexpected EOF)"},

View File

@ -360,44 +360,44 @@ func (f *fmt) plusSpace(s string) {
}
// fmt_e64 formats a float64 in the form -1.23e+12.
func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'e', doPrec(f, 6))) }
func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'e', doPrec(f, 6), 64)) }
// fmt_E64 formats a float64 in the form -1.23E+12.
func (f *fmt) fmt_E64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'E', doPrec(f, 6))) }
func (f *fmt) fmt_E64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'E', doPrec(f, 6), 64)) }
// fmt_f64 formats a float64 in the form -1.23.
func (f *fmt) fmt_f64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'f', doPrec(f, 6))) }
func (f *fmt) fmt_f64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'f', doPrec(f, 6), 64)) }
// fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
func (f *fmt) fmt_g64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'g', doPrec(f, -1))) }
func (f *fmt) fmt_g64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'g', doPrec(f, -1), 64)) }
// fmt_g64 formats a float64 in the 'f' or 'E' form according to size.
func (f *fmt) fmt_G64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'G', doPrec(f, -1))) }
func (f *fmt) fmt_G64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'G', doPrec(f, -1), 64)) }
// fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
func (f *fmt) fmt_fb64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'b', 0)) }
func (f *fmt) fmt_fb64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'b', 0, 64)) }
// float32
// cannot defer to float64 versions
// because it will get rounding wrong in corner cases.
// fmt_e32 formats a float32 in the form -1.23e+12.
func (f *fmt) fmt_e32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'e', doPrec(f, 6))) }
func (f *fmt) fmt_e32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'e', doPrec(f, 6), 32)) }
// fmt_E32 formats a float32 in the form -1.23E+12.
func (f *fmt) fmt_E32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'E', doPrec(f, 6))) }
func (f *fmt) fmt_E32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'E', doPrec(f, 6), 32)) }
// fmt_f32 formats a float32 in the form -1.23.
func (f *fmt) fmt_f32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'f', doPrec(f, 6))) }
func (f *fmt) fmt_f32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'f', doPrec(f, 6), 32)) }
// fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
func (f *fmt) fmt_g32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'g', doPrec(f, -1))) }
func (f *fmt) fmt_g32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'g', doPrec(f, -1), 32)) }
// fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'G', doPrec(f, -1))) }
func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'G', doPrec(f, -1), 32)) }
// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.Ftoa32(v, 'b', 0)) }
func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.FormatFloat(float64(v), 'b', 0, 32)) }
// fmt_c64 formats a complex64 according to the verb.
func (f *fmt) fmt_c64(v complex64, verb rune) {

View File

@ -631,24 +631,30 @@ func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString
return
}
} else {
// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting wasString and handled and deferring catchPanic
// must happen before calling the method.
switch v := p.field.(type) {
case error:
wasString = false
handled = true
defer p.catchPanic(p.field, verb)
p.printField(v.Error(), verb, plus, false, depth)
return
// If a string is acceptable according to the format, see if
// the value satisfies one of the string-valued interfaces.
// Println etc. set verb to %v, which is "stringable".
switch verb {
case 'v', 's', 'x', 'X', 'q':
// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting wasString and handled, and deferring catchPanic,
// must happen before calling the method.
switch v := p.field.(type) {
case error:
wasString = false
handled = true
defer p.catchPanic(p.field, verb)
p.printField(v.Error(), verb, plus, false, depth)
return
case Stringer:
wasString = false
handled = true
defer p.catchPanic(p.field, verb)
p.printField(v.String(), verb, plus, false, depth)
return
case Stringer:
wasString = false
handled = true
defer p.catchPanic(p.field, verb)
p.printField(v.String(), verb, plus, false, depth)
return
}
}
}
handled = false

View File

@ -613,7 +613,7 @@ func (s *ss) scanInt(verb rune, bitSize int) int64 {
}
}
tok := s.scanNumber(digits, haveDigits)
i, err := strconv.Btoi64(tok, base)
i, err := strconv.ParseInt(tok, base, 64)
if err != nil {
s.error(err)
}
@ -643,7 +643,7 @@ func (s *ss) scanUint(verb rune, bitSize int) uint64 {
base, digits, haveDigits = s.scanBasePrefix()
}
tok := s.scanNumber(digits, haveDigits)
i, err := strconv.Btoui64(tok, base)
i, err := strconv.ParseUint(tok, base, 64)
if err != nil {
s.error(err)
}
@ -719,7 +719,7 @@ func (s *ss) convertFloat(str string, n int) float64 {
if p := strings.Index(str, "p"); p >= 0 {
// Atof doesn't handle power-of-2 exponents,
// but they're easy to evaluate.
f, err := strconv.AtofN(str[:p], n)
f, err := strconv.ParseFloat(str[:p], n)
if err != nil {
// Put full string into error.
if e, ok := err.(*strconv.NumError); ok {
@ -737,7 +737,7 @@ func (s *ss) convertFloat(str string, n int) float64 {
}
return math.Ldexp(f, n)
}
f, err := strconv.AtofN(str, n)
f, err := strconv.ParseFloat(str, n)
if err != nil {
s.error(err)
}

View File

@ -24,7 +24,7 @@ var tests = []struct {
// maps
{map[string]int{"a": 1},
`0 map[string] int (len = 1) {
`0 map[string]int (len = 1) {
1 . "a": 1
2 }`},

View File

@ -7,7 +7,6 @@
package doc
import (
"bytes"
"go/ast"
"io"
"regexp"
@ -85,39 +84,6 @@ func CommentText(comment *ast.CommentGroup) string {
return strings.Join(lines, "\n")
}
// Split bytes into lines.
func split(text []byte) [][]byte {
// count lines
n := 0
last := 0
for i, c := range text {
if c == '\n' {
last = i + 1
n++
}
}
if last < len(text) {
n++
}
// split
out := make([][]byte, n)
last = 0
n = 0
for i, c := range text {
if c == '\n' {
out[n] = text[last : i+1]
last = i + 1
n++
}
}
if last < len(text) {
out[n] = text[last:]
}
return out
}
var (
ldquo = []byte("&ldquo;")
rdquo = []byte("&rdquo;")
@ -125,13 +91,13 @@ var (
// Escape comment text for HTML. If nice is set,
// also turn `` into &ldquo; and '' into &rdquo;.
func commentEscape(w io.Writer, s []byte, nice bool) {
func commentEscape(w io.Writer, text string, nice bool) {
last := 0
if nice {
for i := 0; i < len(s)-1; i++ {
ch := s[i]
if ch == s[i+1] && (ch == '`' || ch == '\'') {
template.HTMLEscape(w, s[last:i])
for i := 0; i < len(text)-1; i++ {
ch := text[i]
if ch == text[i+1] && (ch == '`' || ch == '\'') {
template.HTMLEscape(w, []byte(text[last:i]))
last = i + 2
switch ch {
case '`':
@ -143,7 +109,7 @@ func commentEscape(w io.Writer, s []byte, nice bool) {
}
}
}
template.HTMLEscape(w, s[last:])
template.HTMLEscape(w, []byte(text[last:]))
}
const (
@ -183,9 +149,9 @@ var (
// and the word is converted into a link. If nice is set, the remaining text's
// appearance is improved where it makes sense (e.g., `` is turned into &ldquo;
// and '' into &rdquo;).
func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) {
func emphasize(w io.Writer, line string, words map[string]string, nice bool) {
for {
m := matchRx.FindSubmatchIndex(line)
m := matchRx.FindStringSubmatchIndex(line)
if m == nil {
break
}
@ -233,7 +199,7 @@ func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) {
commentEscape(w, line, nice)
}
func indentLen(s []byte) int {
func indentLen(s string) int {
i := 0
for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
i++
@ -241,9 +207,11 @@ func indentLen(s []byte) int {
return i
}
func isBlank(s []byte) bool { return len(s) == 0 || (len(s) == 1 && s[0] == '\n') }
func isBlank(s string) bool {
return len(s) == 0 || (len(s) == 1 && s[0] == '\n')
}
func commonPrefix(a, b []byte) []byte {
func commonPrefix(a, b string) string {
i := 0
for i < len(a) && i < len(b) && a[i] == b[i] {
i++
@ -251,7 +219,7 @@ func commonPrefix(a, b []byte) []byte {
return a[0:i]
}
func unindent(block [][]byte) {
func unindent(block []string) {
if len(block) == 0 {
return
}
@ -273,44 +241,39 @@ func unindent(block [][]byte) {
}
}
// heading returns the (possibly trimmed) line if it passes as a valid section
// heading; otherwise it returns nil.
func heading(line []byte) []byte {
line = bytes.TrimSpace(line)
// heading returns the trimmed line if it passes as a section heading;
// otherwise it returns the empty string.
func heading(line string) string {
line = strings.TrimSpace(line)
if len(line) == 0 {
return nil
return ""
}
// a heading must start with an uppercase letter
r, _ := utf8.DecodeRune(line)
r, _ := utf8.DecodeRuneInString(line)
if !unicode.IsLetter(r) || !unicode.IsUpper(r) {
return nil
return ""
}
// it must end in a letter, digit or ':'
r, _ = utf8.DecodeLastRune(line)
if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' {
return nil
}
// strip trailing ':', if any
if r == ':' {
line = line[0 : len(line)-1]
// it must end in a letter or digit:
r, _ = utf8.DecodeLastRuneInString(line)
if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
return ""
}
// exclude lines with illegal characters
if bytes.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
return nil
if strings.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
return ""
}
// allow "'" for possessive "'s" only
for b := line; ; {
i := bytes.IndexRune(b, '\'')
i := strings.IndexRune(b, '\'')
if i < 0 {
break
}
if i+1 >= len(b) || b[i+1] != 's' || (i+2 < len(b) && b[i+2] != ' ') {
return nil // not followed by "s "
return "" // not followed by "s "
}
b = b[i+2:]
}
@ -335,7 +298,7 @@ func heading(line []byte) []byte {
// Go identifiers that appear in the words map are italicized; if the corresponding
// map value is not the empty string, it is considered a URL and the word is converted
// into a link.
func ToHTML(w io.Writer, s []byte, words map[string]string) {
func ToHTML(w io.Writer, text string, words map[string]string) {
inpara := false
lastWasBlank := false
lastWasHeading := false
@ -353,7 +316,7 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) {
}
}
lines := split(s)
lines := strings.SplitAfter(text, "\n")
unindent(lines)
for i := 0; i < len(lines); {
line := lines[i]
@ -397,10 +360,10 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) {
// current line is non-blank, sourounded by blank lines
// and the next non-blank line is not indented: this
// might be a heading.
if head := heading(line); head != nil {
if head := heading(line); head != "" {
close()
w.Write(html_h)
template.HTMLEscape(w, head)
commentEscape(w, head, true) // nice text formatting
w.Write(html_endh)
i += 2
lastWasHeading = true

View File

@ -18,7 +18,8 @@ var headingTests = []struct {
{"Foo 42", true},
{"", false},
{"section", false},
{"A typical usage:", true},
{"A typical usage:", false},
{"This code:", false},
{"δ is Greek", false},
{"Foo §", false},
{"Fermat's Last Sentence", true},
@ -26,13 +27,13 @@ var headingTests = []struct {
{"'sX", false},
{"Ted 'Too' Bar", false},
{"Use n+m", false},
{"Scanning:", true},
{"Scanning:", false},
{"N:M", false},
}
func TestIsHeading(t *testing.T) {
for _, tt := range headingTests {
if h := heading([]byte(tt.line)); (h != nil) != tt.ok {
if h := heading(tt.line); (len(h) > 0) != tt.ok {
t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok)
}
}

View File

@ -43,7 +43,7 @@ func isGoFile(fi os.FileInfo) bool {
func appendHeadings(list []string, comment string) []string {
var buf bytes.Buffer
doc.ToHTML(&buf, []byte(comment), nil)
doc.ToHTML(&buf, comment, nil)
for s := buf.String(); ; {
i := strings.Index(s, html_h)
if i < 0 {

View File

@ -2026,7 +2026,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
// must have exactly one receiver
if par.NumFields() != 1 {
p.errorExpected(par.Opening, "exactly one receiver")
par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{par.Opening, par.Closing + 1}}}
par.List = []*ast.Field{{Type: &ast.BadExpr{par.Opening, par.Closing + 1}}}
return par
}
@ -2035,7 +2035,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
base := deref(recv.Type)
if _, isIdent := base.(*ast.Ident); !isIdent {
p.errorExpected(base.Pos(), "(unqualified) identifier")
par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{recv.Pos(), recv.End()}}}
par.List = []*ast.Field{{Type: &ast.BadExpr{recv.Pos(), recv.End()}}}
}
return par

View File

@ -354,7 +354,7 @@ func (p *printer) isOneLineFieldList(list []*ast.Field) bool {
}
func (p *printer) setLineComment(text string) {
p.setComment(&ast.CommentGroup{[]*ast.Comment{&ast.Comment{token.NoPos, text}}})
p.setComment(&ast.CommentGroup{[]*ast.Comment{{token.NoPos, text}}})
}
func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {

View File

@ -1999,7 +1999,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
if par.NumFields() != 1 {
p.errorExpected(pos, "exactly one receiver")
// TODO determine a better range for BadExpr below
par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{pos, pos}}}
par.List = []*ast.Field{{Type: &ast.BadExpr{pos, pos}}}
return par
}
@ -2008,7 +2008,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
base := deref(recv.Type)
if _, isIdent := base.(*ast.Ident); !isIdent {
p.errorExpected(base.Pos(), "(unqualified) identifier")
par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{recv.Pos(), recv.End()}}}
par.List = []*ast.Field{{Type: &ast.BadExpr{recv.Pos(), recv.End()}}}
}
return par

View File

@ -13,9 +13,9 @@ type Hash interface {
// It never returns an error.
io.Writer
// Sum appends the current hash in the same manner as append(), without
// changing the underlying hash state.
Sum(in []byte) []byte
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte
// Reset resets the hash to one with zero bytes written.
Reset()

View File

@ -515,7 +515,19 @@ func afterHeadIM(p *parser) bool {
implied bool
)
switch p.tok.Type {
case ErrorToken, TextToken:
case ErrorToken:
implied = true
framesetOK = true
case TextToken:
s := strings.TrimLeft(p.tok.Data, whitespace)
if len(s) < len(p.tok.Data) {
// Add the initial whitespace to the current node.
p.addText(p.tok.Data[:len(p.tok.Data)-len(s)])
if s == "" {
return true
}
p.tok.Data = s
}
implied = true
framesetOK = true
case StartTagToken:
@ -535,7 +547,8 @@ func afterHeadIM(p *parser) bool {
defer p.oe.pop()
return inHeadIM(p)
case "head":
// TODO.
// Ignore the token.
return true
default:
implied = true
framesetOK = true

View File

@ -167,6 +167,7 @@ func TestParser(t *testing.T) {
{"tests3.dat", -1},
{"tests4.dat", -1},
{"tests5.dat", -1},
{"tests6.dat", 7},
}
for _, tf := range testFiles {
f, err := os.Open("testdata/webkit/" + tf.filename)

View File

@ -14,63 +14,63 @@ func TestRenderer(t *testing.T) {
Type: ElementNode,
Data: "html",
Child: []*Node{
&Node{
{
Type: ElementNode,
Data: "head",
},
&Node{
{
Type: ElementNode,
Data: "body",
Child: []*Node{
&Node{
{
Type: TextNode,
Data: "0<1",
},
&Node{
{
Type: ElementNode,
Data: "p",
Attr: []Attribute{
Attribute{
{
Key: "id",
Val: "A",
},
Attribute{
{
Key: "foo",
Val: `abc"def`,
},
},
Child: []*Node{
&Node{
{
Type: TextNode,
Data: "2",
},
&Node{
{
Type: ElementNode,
Data: "b",
Attr: []Attribute{
Attribute{
{
Key: "empty",
Val: "",
},
},
Child: []*Node{
&Node{
{
Type: TextNode,
Data: "3",
},
},
},
&Node{
{
Type: ElementNode,
Data: "i",
Attr: []Attribute{
Attribute{
{
Key: "backslash",
Val: `\`,
},
},
Child: []*Node{
&Node{
{
Type: TextNode,
Data: "&4",
},
@ -78,19 +78,19 @@ func TestRenderer(t *testing.T) {
},
},
},
&Node{
{
Type: TextNode,
Data: "5",
},
&Node{
{
Type: ElementNode,
Data: "blockquote",
},
&Node{
{
Type: ElementNode,
Data: "br",
},
&Node{
{
Type: TextNode,
Data: "6",
},

View File

@ -113,7 +113,7 @@ func TestDecodeCSS(t *testing.T) {
func TestHexDecode(t *testing.T) {
for i := 0; i < 0x200000; i += 101 /* coprime with 16 */ {
s := strconv.Itob(i, 16)
s := strconv.FormatInt(int64(i), 16)
if got := int(hexDecode([]byte(s))); got != i {
t.Errorf("%s: want %d but got %d", s, i, got)
}

View File

@ -716,7 +716,7 @@ func (e *escaper) editTextNode(n *parse.TextNode, text []byte) {
// commit applies changes to actions and template calls needed to contextually
// autoescape content and adds any derived templates to the set.
func (e *escaper) commit() {
for name, _ := range e.output {
for name := range e.output {
e.template(name).Funcs(funcMap)
}
for _, t := range e.derived {

View File

@ -689,11 +689,11 @@ func TestEscapeSet(t *testing.T) {
data := dataItem{
Children: []*dataItem{
&dataItem{X: "foo"},
&dataItem{X: "<bar>"},
&dataItem{
{X: "foo"},
{X: "<bar>"},
{
Children: []*dataItem{
&dataItem{X: "baz"},
{X: "baz"},
},
},
},
@ -1597,7 +1597,7 @@ func TestRedundantFuncs(t *testing.T) {
for n0, m := range redundantFuncs {
f0 := funcMap[n0].(func(...interface{}) string)
for n1, _ := range m {
for n1 := range m {
f1 := funcMap[n1].(func(...interface{}) string)
for _, input := range inputs {
want := f0(input)

View File

@ -47,23 +47,22 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
return t.text.Execute(wr, data)
}
// ExecuteTemplate applies the template associated with t that has the given name
// to the specified data object and writes the output to wr.
// ExecuteTemplate applies the template associated with t that has the given
// name to the specified data object and writes the output to wr.
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) (err error) {
t.nameSpace.mu.Lock()
tmpl := t.set[name]
if tmpl == nil {
t.nameSpace.mu.Unlock()
return fmt.Errorf("template: no template %q associated with template %q", name, t.Name())
if (tmpl == nil) != (t.text.Lookup(name) == nil) {
panic("html/template internal error: template escaping out of sync")
}
if !tmpl.escaped {
if tmpl != nil && !tmpl.escaped {
err = escapeTemplates(tmpl, name)
}
t.nameSpace.mu.Unlock()
if err != nil {
return
}
return tmpl.text.ExecuteTemplate(wr, name, data)
return t.text.ExecuteTemplate(wr, name, data)
}
// Parse parses a string into a template. Nested template definitions
@ -106,7 +105,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) error {
// Clone is unimplemented.
func (t *Template) Clone(name string) error {
return fmt.Errorf("html/template: Add unimplemented")
return fmt.Errorf("html/template: Clone unimplemented")
}
// New allocates a new HTML template with the given name.

View File

@ -134,13 +134,22 @@ type Model interface {
Convert(c Color) Color
}
// ModelFunc is an adapter type to allow the use of a color conversion
// function as a Model. If f is such a function, ModelFunc(f) is a Model that
// invokes f to implement the conversion.
type ModelFunc func(Color) Color
// ModelFunc returns a Model that invokes f to implement the conversion.
func ModelFunc(f func(Color) Color) Model {
// Note: using *modelFunc as the implementation
// means that callers can still use comparisons
// like m == RGBAModel. This is not possible if
// we use the func value directly, because funcs
// are no longer comparable.
return &modelFunc{f}
}
func (f ModelFunc) Convert(c Color) Color {
return f(c)
type modelFunc struct {
f func(Color) Color
}
func (m *modelFunc) Convert(c Color) Color {
return m.f(c)
}
// RGBAModel is the Model for RGBA colors.

View File

@ -20,7 +20,7 @@ var (
)
// Uniform is an infinite-sized Image of uniform color.
// It implements both the color.Color and Image interfaces.
// It implements the color.Color, color.ColorModel, and Image interfaces.
type Uniform struct {
C color.Color
}
@ -30,7 +30,11 @@ func (c *Uniform) RGBA() (r, g, b, a uint32) {
}
func (c *Uniform) ColorModel() color.Model {
return color.ModelFunc(func(color.Color) color.Color { return c.C })
return c
}
func (c *Uniform) Convert(color.Color) color.Color {
return c.C
}
func (c *Uniform) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} }

View File

@ -429,7 +429,7 @@ func Encode(w io.Writer, m image.Image) error {
// also rejected.
mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy())
if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 {
return FormatError("invalid image size: " + strconv.Itoa64(mw) + "x" + strconv.Itoa64(mw))
return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mw, 10))
}
var e encoder

View File

@ -110,7 +110,7 @@ var _cos = [...]float64{
// Cos returns the cosine of x.
//
// Special conditions are:
// Special cases are:
// Cos(±Inf) = NaN
// Cos(NaN) = NaN
func Cos(x float64) float64 {

View File

@ -8,7 +8,7 @@ package math
// Sincos(x) returns Sin(x), Cos(x).
//
// Special conditions are:
// Special cases are:
// Sincos(±0) = ±0, 1
// Sincos(±Inf) = NaN, NaN
// Sincos(NaN) = NaN, NaN

View File

@ -17,6 +17,11 @@ package math
*/
// Sinh returns the hyperbolic sine of x.
//
// Special cases are:
// Sinh(±0) = ±0
// Sinh(±Inf) = ±Inf
// Sinh(NaN) = NaN
func Sinh(x float64) float64 {
// The coefficients are #2029 from Hart & Cheney. (20.36D)
const (
@ -56,6 +61,11 @@ func Sinh(x float64) float64 {
}
// Cosh returns the hyperbolic cosine of x.
//
// Special cases are:
// Cosh(±0) = 1
// Cosh(±Inf) = +Inf
// Cosh(NaN) = NaN
func Cosh(x float64) float64 {
if x < 0 {
x = -x

View File

@ -75,7 +75,7 @@ var _tanQ = [...]float64{
// Tan returns the tangent of x.
//
// Special conditions are:
// Special cases are:
// Tan(±0) = ±0
// Tan(±Inf) = NaN
// Tan(NaN) = NaN

View File

@ -12,6 +12,11 @@ package math
*/
// Tanh computes the hyperbolic tangent of x.
//
// Special cases are:
// Tanh(±0) = ±0
// Tanh(±Inf) = ±1
// Tanh(NaN) = NaN
func Tanh(x float64) float64 {
if x < 0 {
x = -x

View File

@ -70,7 +70,7 @@ func RequestFromMap(params map[string]string) (*http.Request, error) {
r.Host = params["HTTP_HOST"]
if lenstr := params["CONTENT_LENGTH"]; lenstr != "" {
clen, err := strconv.Atoi64(lenstr)
clen, err := strconv.ParseInt(lenstr, 10, 64)
if err != nil {
return nil, errors.New("cgi: bad CONTENT_LENGTH in environment: " + lenstr)
}

View File

@ -48,7 +48,7 @@ func (cr *chunkedReader) beginChunk() {
if cr.err != nil {
return
}
cr.n, cr.err = strconv.Btoui64(line, 16)
cr.n, cr.err = strconv.ParseUint(line, 16, 64)
if cr.err != nil {
return
}
@ -147,7 +147,7 @@ func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
return 0, nil
}
head := strconv.Itob(len(data), 16) + "\r\n"
head := strconv.FormatInt(int64(len(data)), 16) + "\r\n"
if _, err = io.WriteString(cw.Wire, head); err != nil {
return 0, err

View File

@ -81,14 +81,14 @@ var addCookieTests = []struct {
"",
},
{
[]*Cookie{&Cookie{Name: "cookie-1", Value: "v$1"}},
[]*Cookie{{Name: "cookie-1", Value: "v$1"}},
"cookie-1=v$1",
},
{
[]*Cookie{
&Cookie{Name: "cookie-1", Value: "v$1"},
&Cookie{Name: "cookie-2", Value: "v$2"},
&Cookie{Name: "cookie-3", Value: "v$3"},
{Name: "cookie-1", Value: "v$1"},
{Name: "cookie-2", Value: "v$2"},
{Name: "cookie-3", Value: "v$3"},
},
"cookie-1=v$1; cookie-2=v$2; cookie-3=v$3",
},
@ -113,11 +113,11 @@ var readSetCookiesTests = []struct {
}{
{
Header{"Set-Cookie": {"Cookie-1=v$1"}},
[]*Cookie{&Cookie{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}},
[]*Cookie{{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}},
},
{
Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}},
[]*Cookie{&Cookie{
[]*Cookie{{
Name: "NID",
Value: "99=YsDT5i3E-CXax-",
Path: "/",
@ -159,30 +159,30 @@ var readCookiesTests = []struct {
Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
"",
[]*Cookie{
&Cookie{Name: "Cookie-1", Value: "v$1"},
&Cookie{Name: "c2", Value: "v2"},
{Name: "Cookie-1", Value: "v$1"},
{Name: "c2", Value: "v2"},
},
},
{
Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
"c2",
[]*Cookie{
&Cookie{Name: "c2", Value: "v2"},
{Name: "c2", Value: "v2"},
},
},
{
Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
"",
[]*Cookie{
&Cookie{Name: "Cookie-1", Value: "v$1"},
&Cookie{Name: "c2", Value: "v2"},
{Name: "Cookie-1", Value: "v$1"},
{Name: "c2", Value: "v2"},
},
},
{
Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
"c2",
[]*Cookie{
&Cookie{Name: "c2", Value: "v2"},
{Name: "c2", Value: "v2"},
},
},
}

View File

@ -220,7 +220,7 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
w.Header().Set("Accept-Ranges", "bytes")
if w.Header().Get("Content-Encoding") == "" {
w.Header().Set("Content-Length", strconv.Itoa64(size))
w.Header().Set("Content-Length", strconv.FormatInt(size, 10))
}
w.WriteHeader(code)
@ -295,7 +295,7 @@ func parseRange(s string, size int64) ([]httpRange, error) {
if start == "" {
// If no start is specified, end specifies the
// range start relative to the end of the file.
i, err := strconv.Atoi64(end)
i, err := strconv.ParseInt(end, 10, 64)
if err != nil {
return nil, errors.New("invalid range")
}
@ -305,7 +305,7 @@ func parseRange(s string, size int64) ([]httpRange, error) {
r.start = size - i
r.length = size - r.start
} else {
i, err := strconv.Atoi64(start)
i, err := strconv.ParseInt(start, 10, 64)
if err != nil || i > size || i < 0 {
return nil, errors.New("invalid range")
}
@ -314,7 +314,7 @@ func parseRange(s string, size int64) ([]httpRange, error) {
// If no end is specified, range extends to end of the file.
r.length = size - r.start
} else {
i, err := strconv.Atoi64(end)
i, err := strconv.ParseInt(end, 10, 64)
if err != nil || r.start > i {
return nil, errors.New("invalid range")
}

View File

@ -50,7 +50,7 @@ func (cr *chunkedReader) beginChunk() {
if cr.err != nil {
return
}
cr.n, cr.err = strconv.Btoui64(line, 16)
cr.n, cr.err = strconv.ParseUint(line, 16, 64)
if cr.err != nil {
return
}
@ -149,7 +149,7 @@ func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
return 0, nil
}
head := strconv.Itob(len(data), 16) + "\r\n"
head := strconv.FormatInt(int64(len(data)), 16) + "\r\n"
if _, err = io.WriteString(cw.Wire, head); err != nil {
return 0, err

Some files were not shown because too many files have changed in this diff Show More