libgo: Update to weekly.2011-12-06.
From-SVN: r182338
This commit is contained in:
parent
ef0d4c4d99
commit
d536359059
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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[:]...)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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[:]...)
|
||||
}
|
||||
|
@ -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++ {
|
||||
|
@ -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[:]...)
|
||||
}
|
||||
|
@ -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]...)
|
||||
}
|
||||
|
@ -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]...)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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:]
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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!#$%&()*+-;<=>?@^_`{|}~"
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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},
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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},
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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)"},
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 }`},
|
||||
|
||||
|
@ -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("“")
|
||||
rdquo = []byte("”")
|
||||
@ -125,13 +91,13 @@ var (
|
||||
|
||||
// Escape comment text for HTML. If nice is set,
|
||||
// also turn `` into “ and '' into ”.
|
||||
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 “
|
||||
// and '' into ”).
|
||||
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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
4
libgo/go/go/printer/testdata/parser.go
vendored
4
libgo/go/go/printer/testdata/parser.go
vendored
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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}} }
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user