From cdc0ebbebe64d8fa601914945112db306c85c426 Mon Sep 17 00:00:00 2001 From: Håvard Haugen Date: Wed, 3 Feb 2016 23:41:55 +0100 Subject: encoding/json: respect json.Marshaler when encoding byte kind slices Fixes #13783. Change-Id: I0122c1f0cf4075acabf5f58241bded1835699dc1 Reviewed-on: https://go-review.googlesource.com/19725 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/encoding/json/encode.go | 4 ++- src/encoding/json/encode_test.go | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) (limited to 'src/encoding') diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index bcae6838cc..927f47b179 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -679,7 +679,9 @@ func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) { func newSliceEncoder(t reflect.Type) encoderFunc { // Byte slices get special treatment; arrays don't. - if t.Elem().Kind() == reflect.Uint8 { + if t.Elem().Kind() == reflect.Uint8 && + !t.Elem().Implements(marshalerType) && + !t.Elem().Implements(textMarshalerType) { return encodeByteSlice } enc := &sliceEncoder{newArrayEncoder(t)} diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index eed40a4272..eee59ccb49 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -6,6 +6,7 @@ package json import ( "bytes" + "fmt" "math" "reflect" "testing" @@ -537,6 +538,60 @@ func TestEncodeString(t *testing.T) { } } +type jsonbyte byte + +func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) } + +type textbyte byte + +func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) } + +type jsonint int + +func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) } + +type textint int + +func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) } + +func tenc(format string, a ...interface{}) ([]byte, error) { + var buf bytes.Buffer + fmt.Fprintf(&buf, format, a...) + return buf.Bytes(), nil +} + +// Issue 13783 +func TestEncodeBytekind(t *testing.T) { + testdata := []struct { + data interface{} + want string + }{ + {byte(7), "7"}, + {jsonbyte(7), `{"JB":7}`}, + {textbyte(4), `"TB:4"`}, + {jsonint(5), `{"JI":5}`}, + {textint(1), `"TI:1"`}, + {[]byte{0, 1}, `"AAE="`}, + {[]jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`}, + {[][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`}, + {[]textbyte{2, 3}, `["TB:2","TB:3"]`}, + {[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`}, + {[]textint{9, 3}, `["TI:9","TI:3"]`}, + {[]int{9, 3}, `[9,3]`}, + } + for _, d := range testdata { + js, err := Marshal(d.data) + if err != nil { + t.Error(err) + continue + } + got, want := string(js), d.want + if got != want { + t.Errorf("got %s, want %s", got, want) + } + } +} + func TestTextMarshalerMapKeysAreSorted(t *testing.T) { b, err := Marshal(map[unmarshalerText]int{ {"x", "y"}: 1, -- cgit v1.3 From 012557b3769f9286b9488fbfd4bddfeee66b6a55 Mon Sep 17 00:00:00 2001 From: Martin Möhrmann Date: Sun, 10 Apr 2016 08:48:55 +0200 Subject: all: replace magic 0x80 with named constant utf8.RuneSelf Change-Id: Id1c2e8e9d60588de866e8b6ca59cc83dd28f848f Reviewed-on: https://go-review.googlesource.com/21756 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/bufio/bufio.go | 2 +- src/cmd/compile/internal/gc/fmt.go | 2 +- src/encoding/asn1/asn1.go | 2 +- src/go/build/build.go | 2 +- src/go/build/read.go | 3 ++- src/go/scanner/scanner.go | 6 +++--- src/html/template/css.go | 2 +- src/net/http/cookiejar/punycode.go | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/encoding') diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go index d2ccc74f52..3b30b8b80c 100644 --- a/src/bufio/bufio.go +++ b/src/bufio/bufio.go @@ -266,7 +266,7 @@ func (b *Reader) ReadRune() (r rune, size int, err error) { return 0, 0, b.readErr() } r, size = rune(b.buf[b.r]), 1 - if r >= 0x80 { + if r >= utf8.RuneSelf { r, size = utf8.DecodeRune(b.buf[b.r:b.w]) } b.r += size diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index 19f109055d..41d696574c 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -337,7 +337,7 @@ func Vconv(v Val, flag FmtFlag) string { case CTRUNE: x := v.U.(*Mpint).Int64() - if ' ' <= x && x < 0x80 && x != '\\' && x != '\'' { + if ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'' { return fmt.Sprintf("'%c'", int(x)) } if 0 <= x && x < 1<<16 { diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go index bd2c96d887..2b5ad08551 100644 --- a/src/encoding/asn1/asn1.go +++ b/src/encoding/asn1/asn1.go @@ -393,7 +393,7 @@ func isPrintable(b byte) bool { // byte slice and returns it. func parseIA5String(bytes []byte) (ret string, err error) { for _, b := range bytes { - if b >= 0x80 { + if b >= utf8.RuneSelf { err = SyntaxError{"IA5String contains invalid character"} return } diff --git a/src/go/build/build.go b/src/go/build/build.go index e61d564fa3..04a41a6c2e 100644 --- a/src/go/build/build.go +++ b/src/go/build/build.go @@ -1266,7 +1266,7 @@ func safeCgoName(s string, spaces bool) bool { safe = safe[len(safeSpaces):] } for i := 0; i < len(s); i++ { - if c := s[i]; c < 0x80 && bytes.IndexByte(safe, c) < 0 { + if c := s[i]; c < utf8.RuneSelf && bytes.IndexByte(safe, c) < 0 { return false } } diff --git a/src/go/build/read.go b/src/go/build/read.go index d411c1980e..29b8cdc786 100644 --- a/src/go/build/read.go +++ b/src/go/build/read.go @@ -8,6 +8,7 @@ import ( "bufio" "errors" "io" + "unicode/utf8" ) type importReader struct { @@ -20,7 +21,7 @@ type importReader struct { } func isIdent(c byte) bool { - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= 0x80 + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf } var ( diff --git a/src/go/scanner/scanner.go b/src/go/scanner/scanner.go index 4041d9aa47..ce660c71d5 100644 --- a/src/go/scanner/scanner.go +++ b/src/go/scanner/scanner.go @@ -64,7 +64,7 @@ func (s *Scanner) next() { switch { case r == 0: s.error(s.offset, "illegal character NUL") - case r >= 0x80: + case r >= utf8.RuneSelf: // not ASCII r, w = utf8.DecodeRune(s.src[s.rdOffset:]) if r == utf8.RuneError && w == 1 { @@ -255,11 +255,11 @@ func (s *Scanner) findLineEnd() bool { } func isLetter(ch rune) bool { - return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) + return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch) } func isDigit(ch rune) bool { - return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) + return '0' <= ch && ch <= '9' || ch >= utf8.RuneSelf && unicode.IsDigit(ch) } func (s *Scanner) scanIdentifier() string { diff --git a/src/html/template/css.go b/src/html/template/css.go index 4c27cce85a..9154d8636d 100644 --- a/src/html/template/css.go +++ b/src/html/template/css.go @@ -243,7 +243,7 @@ func cssValueFilter(args ...interface{}) string { return filterFailsafe } default: - if c < 0x80 && isCSSNmchar(rune(c)) { + if c < utf8.RuneSelf && isCSSNmchar(rune(c)) { id = append(id, c) } } diff --git a/src/net/http/cookiejar/punycode.go b/src/net/http/cookiejar/punycode.go index ea7ceb5ef3..a9cc666e8c 100644 --- a/src/net/http/cookiejar/punycode.go +++ b/src/net/http/cookiejar/punycode.go @@ -37,7 +37,7 @@ func encode(prefix, s string) (string, error) { delta, n, bias := int32(0), initialN, initialBias b, remaining := int32(0), int32(0) for _, r := range s { - if r < 0x80 { + if r < utf8.RuneSelf { b++ output = append(output, byte(r)) } else { -- cgit v1.3 From 0da4dbe2322eb3b6224df35ce3e9fc83f104762b Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Thu, 14 Apr 2016 19:09:36 -0700 Subject: all: remove unnecessary type conversions cmd and runtime were handled separately, and I'm intentionally skipped syscall. This is the rest of the standard library. CL generated mechanically with github.com/mdempsky/unconvert. Change-Id: I9e0eff886974dedc37adb93f602064b83e469122 Reviewed-on: https://go-review.googlesource.com/22104 Reviewed-by: Brad Fitzpatrick Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot --- src/archive/tar/reader.go | 8 ++++---- src/archive/tar/writer.go | 2 +- src/bytes/reader.go | 2 +- src/compress/bzip2/bzip2.go | 8 ++++---- src/compress/flate/huffman_bit_writer.go | 2 +- src/compress/flate/reverse_bits.go | 2 +- src/compress/lzw/writer.go | 2 +- src/crypto/des/block.go | 2 +- src/crypto/tls/handshake_messages.go | 4 ++-- src/debug/dwarf/buf.go | 2 +- src/debug/dwarf/line.go | 2 +- src/debug/dwarf/typeunit.go | 4 ++-- src/debug/elf/elf.go | 4 ++-- src/debug/elf/file.go | 32 ++++++++++++++++---------------- src/debug/gosym/pclntab.go | 4 ++-- src/debug/gosym/symtab.go | 4 ++-- src/encoding/asn1/marshal.go | 6 +++--- src/encoding/binary/binary.go | 2 +- src/encoding/gob/encode.go | 2 +- src/go/ast/ast.go | 2 +- src/image/color/ycbcr.go | 18 +++++++++--------- src/image/draw/draw.go | 8 ++++---- src/math/big/float.go | 4 ++-- src/math/big/natconv.go | 2 +- src/math/big/ratconv.go | 2 +- src/net/interface_bsd.go | 4 ++-- src/net/mail/message.go | 2 +- src/net/parse.go | 4 ++-- src/os/exec_windows.go | 2 +- src/os/file_windows.go | 14 +++++++------- src/os/stat_darwin.go | 2 +- src/os/stat_dragonfly.go | 4 ++-- src/os/stat_freebsd.go | 2 +- src/os/stat_linux.go | 2 +- src/os/stat_nacl.go | 2 +- src/os/stat_netbsd.go | 4 ++-- src/os/stat_openbsd.go | 4 ++-- src/os/stat_plan9.go | 2 +- src/os/stat_solaris.go | 4 ++-- src/os/stat_windows.go | 2 +- src/os/types_windows.go | 2 +- src/reflect/type.go | 4 ++-- src/reflect/value.go | 26 +++++++++++++------------- src/regexp/onepass.go | 2 +- src/strconv/extfloat.go | 4 ++-- src/strings/reader.go | 2 +- src/sync/pool.go | 4 ++-- src/time/time.go | 8 ++++---- src/time/zoneinfo_windows.go | 2 +- src/unicode/letter.go | 2 +- 50 files changed, 120 insertions(+), 120 deletions(-) (limited to 'src/encoding') diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go index 741fe0152b..b924eeb568 100644 --- a/src/archive/tar/reader.go +++ b/src/archive/tar/reader.go @@ -306,7 +306,7 @@ func mergePAX(hdr *Header, headers map[string]string) error { if err != nil { return err } - hdr.Size = int64(size) + hdr.Size = size default: if strings.HasPrefix(k, paxXattr) { if hdr.Xattrs == nil { @@ -346,7 +346,7 @@ func parsePAXTime(t string) (time.Time, error) { // Right truncate nano_buf = nano_buf[:maxNanoSecondIntSize] } - nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0) + nanoseconds, err = strconv.ParseInt(nano_buf, 10, 0) if err != nil { return time.Time{}, err } @@ -378,14 +378,14 @@ func parsePAX(r io.Reader) (map[string]string, error) { } sbuf = residual - keyStr := string(key) + keyStr := key if keyStr == paxGNUSparseOffset || keyStr == paxGNUSparseNumBytes { // GNU sparse format 0.0 special key. Write to sparseMap instead of using the headers map. sparseMap.WriteString(value) sparseMap.Write([]byte{','}) } else { // Normal key. Set the value in the headers map. - headers[keyStr] = string(value) + headers[keyStr] = value } } if sparseMap.Len() != 0 { diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go index 600ee4be09..944b2d4952 100644 --- a/src/archive/tar/writer.go +++ b/src/archive/tar/writer.go @@ -278,7 +278,7 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error { return err } } - tw.nb = int64(hdr.Size) + tw.nb = hdr.Size tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize _, tw.err = tw.w.Write(header) diff --git a/src/bytes/reader.go b/src/bytes/reader.go index 7aa30578b3..aa39890f3b 100644 --- a/src/bytes/reader.go +++ b/src/bytes/reader.go @@ -114,7 +114,7 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) { case 0: abs = offset case 1: - abs = int64(r.i) + offset + abs = r.i + offset case 2: abs = int64(len(r.s)) + offset default: diff --git a/src/compress/bzip2/bzip2.go b/src/compress/bzip2/bzip2.go index 90e9aebab6..42788443bc 100644 --- a/src/compress/bzip2/bzip2.go +++ b/src/compress/bzip2/bzip2.go @@ -75,7 +75,7 @@ func (bz2 *reader) setup(needMagic bool) error { } bz2.fileCRC = 0 - bz2.blockSize = 100 * 1000 * (int(level) - '0') + bz2.blockSize = 100 * 1000 * (level - '0') if bz2.blockSize > len(bz2.tt) { bz2.tt = make([]uint32, bz2.blockSize) } @@ -293,7 +293,7 @@ func (bz2 *reader) readBlock() (err error) { if c >= numHuffmanTrees { return StructuralError("tree index too large") } - treeIndexes[i] = uint8(mtfTreeDecoder.Decode(c)) + treeIndexes[i] = mtfTreeDecoder.Decode(c) } // The list of symbols for the move-to-front transform is taken from @@ -399,7 +399,7 @@ func (bz2 *reader) readBlock() (err error) { return StructuralError("repeats past end of block") } for i := 0; i < repeat; i++ { - b := byte(mtf.First()) + b := mtf.First() bz2.tt[bufIndex] = uint32(b) bz2.c[b]++ bufIndex++ @@ -420,7 +420,7 @@ func (bz2 *reader) readBlock() (err error) { // it's always referenced with a run-length of 1. Thus 0 // doesn't need to be encoded and we have |v-1| in the next // line. - b := byte(mtf.Decode(int(v - 1))) + b := mtf.Decode(int(v - 1)) if bufIndex >= bz2.blockSize { return StructuralError("data exceeds block size") } diff --git a/src/compress/flate/huffman_bit_writer.go b/src/compress/flate/huffman_bit_writer.go index 23f242f88e..d0206e59cf 100644 --- a/src/compress/flate/huffman_bit_writer.go +++ b/src/compress/flate/huffman_bit_writer.go @@ -436,7 +436,7 @@ func (w *huffmanBitWriter) writeBlock(tokens []token, eof bool, input []byte) { } dynamicHeader := int64(3+5+5+4+(3*numCodegens)) + w.codegenEncoding.bitLength(w.codegenFreq[:]) + - int64(extraBits) + + extraBits + int64(w.codegenFreq[16]*2) + int64(w.codegenFreq[17]*3) + int64(w.codegenFreq[18]*7) diff --git a/src/compress/flate/reverse_bits.go b/src/compress/flate/reverse_bits.go index c1a02720d1..6b222900c1 100644 --- a/src/compress/flate/reverse_bits.go +++ b/src/compress/flate/reverse_bits.go @@ -44,5 +44,5 @@ func reverseUint16(v uint16) uint16 { } func reverseBits(number uint16, bitLength byte) uint16 { - return reverseUint16(number << uint8(16-bitLength)) + return reverseUint16(number << (16 - bitLength)) } diff --git a/src/compress/lzw/writer.go b/src/compress/lzw/writer.go index 7367c29651..6ddb335f31 100644 --- a/src/compress/lzw/writer.go +++ b/src/compress/lzw/writer.go @@ -119,7 +119,7 @@ func (e *encoder) incHi() error { if err := e.write(e, clear); err != nil { return err } - e.width = uint(e.litWidth) + 1 + e.width = e.litWidth + 1 e.hi = clear + 1 e.overflow = clear << 1 for i := range e.table { diff --git a/src/crypto/des/block.go b/src/crypto/des/block.go index 26355a22e7..99338d62a6 100644 --- a/src/crypto/des/block.go +++ b/src/crypto/des/block.go @@ -72,7 +72,7 @@ func init() { for i := 0; i < 4; i++ { for j := 0; j < 16; j++ { f := uint64(sBoxes[s][i][j]) << (4 * (7 - uint(s))) - f = permuteBlock(uint64(f), permutationFunction[:]) + f = permuteBlock(f, permutationFunction[:]) feistelBox[s][16*i+j] = uint32(f) } } diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go index 13d013a594..3f9a63b110 100644 --- a/src/crypto/tls/handshake_messages.go +++ b/src/crypto/tls/handshake_messages.go @@ -214,7 +214,7 @@ func (m *clientHelloMsg) marshal() []byte { z[4] = byte(l) z = z[5:] for _, pointFormat := range m.supportedPoints { - z[0] = byte(pointFormat) + z[0] = pointFormat z = z[1:] } } @@ -589,7 +589,7 @@ func (m *serverHelloMsg) marshal() []byte { z := x[39+len(m.sessionId):] z[0] = uint8(m.cipherSuite >> 8) z[1] = uint8(m.cipherSuite) - z[2] = uint8(m.compressionMethod) + z[2] = m.compressionMethod z = z[3:] if numExtensions > 0 { diff --git a/src/debug/dwarf/buf.go b/src/debug/dwarf/buf.go index 7443043c11..24d266db10 100644 --- a/src/debug/dwarf/buf.go +++ b/src/debug/dwarf/buf.go @@ -157,7 +157,7 @@ func (b *buf) addr() uint64 { case 4: return uint64(b.uint32()) case 8: - return uint64(b.uint64()) + return b.uint64() } b.error("unknown address size") return 0 diff --git a/src/debug/dwarf/line.go b/src/debug/dwarf/line.go index b3b91ade62..ed82feef92 100644 --- a/src/debug/dwarf/line.go +++ b/src/debug/dwarf/line.go @@ -361,7 +361,7 @@ func (r *LineReader) step(entry *LineEntry) bool { // Special opcode [DWARF2 6.2.5.1, DWARF4 6.2.5.1] adjustedOpcode := opcode - r.opcodeBase r.advancePC(adjustedOpcode / r.lineRange) - lineDelta := r.lineBase + int(adjustedOpcode)%r.lineRange + lineDelta := r.lineBase + adjustedOpcode%r.lineRange r.state.Line += lineDelta goto emit } diff --git a/src/debug/dwarf/typeunit.go b/src/debug/dwarf/typeunit.go index ed42547386..652e02d917 100644 --- a/src/debug/dwarf/typeunit.go +++ b/src/debug/dwarf/typeunit.go @@ -76,7 +76,7 @@ func (d *Data) parseTypes(name string, types []byte) error { data: b.bytes(int(n - (b.off - hdroff))), atable: atable, asize: int(asize), - vers: int(vers), + vers: vers, is64: dwarf64, }, toff: Offset(toff), @@ -101,7 +101,7 @@ func (d *Data) sigToType(sig uint64) (Type, error) { b := makeBuf(d, tu, tu.name, tu.off, tu.data) r := &typeUnitReader{d: d, tu: tu, b: b} - t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type), nil) + t, err := d.readType(tu.name, r, tu.toff, make(map[Offset]Type), nil) if err != nil { return nil, err } diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go index af881c2495..3f43d4d896 100644 --- a/src/debug/elf/elf.go +++ b/src/debug/elf/elf.go @@ -2060,8 +2060,8 @@ type Rela32 struct { Addend int32 /* Addend. */ } -func R_SYM32(info uint32) uint32 { return uint32(info >> 8) } -func R_TYPE32(info uint32) uint32 { return uint32(info & 0xff) } +func R_SYM32(info uint32) uint32 { return info >> 8 } +func R_TYPE32(info uint32) uint32 { return info & 0xff } func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ } // ELF32 Symbol. diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go index 8fbf23fe5a..c173ea9331 100644 --- a/src/debug/elf/file.go +++ b/src/debug/elf/file.go @@ -294,7 +294,7 @@ func NewFile(r io.ReaderAt) (*File, error) { } f.Type = Type(hdr.Type) f.Machine = Machine(hdr.Machine) - f.Entry = uint64(hdr.Entry) + f.Entry = hdr.Entry if v := Version(hdr.Version); v != f.Version { return nil, &FormatError{0, "mismatched ELF version", v} } @@ -341,12 +341,12 @@ func NewFile(r io.ReaderAt) (*File, error) { p.ProgHeader = ProgHeader{ Type: ProgType(ph.Type), Flags: ProgFlag(ph.Flags), - Off: uint64(ph.Off), - Vaddr: uint64(ph.Vaddr), - Paddr: uint64(ph.Paddr), - Filesz: uint64(ph.Filesz), - Memsz: uint64(ph.Memsz), - Align: uint64(ph.Align), + Off: ph.Off, + Vaddr: ph.Vaddr, + Paddr: ph.Paddr, + Filesz: ph.Filesz, + Memsz: ph.Memsz, + Align: ph.Align, } } p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz)) @@ -374,8 +374,8 @@ func NewFile(r io.ReaderAt) (*File, error) { Addr: uint64(sh.Addr), Offset: uint64(sh.Off), FileSize: uint64(sh.Size), - Link: uint32(sh.Link), - Info: uint32(sh.Info), + Link: sh.Link, + Info: sh.Info, Addralign: uint64(sh.Addralign), Entsize: uint64(sh.Entsize), } @@ -388,13 +388,13 @@ func NewFile(r io.ReaderAt) (*File, error) { s.SectionHeader = SectionHeader{ Type: SectionType(sh.Type), Flags: SectionFlag(sh.Flags), - Offset: uint64(sh.Off), - FileSize: uint64(sh.Size), - Addr: uint64(sh.Addr), - Link: uint32(sh.Link), - Info: uint32(sh.Info), - Addralign: uint64(sh.Addralign), - Entsize: uint64(sh.Entsize), + Offset: sh.Off, + FileSize: sh.Size, + Addr: sh.Addr, + Link: sh.Link, + Info: sh.Info, + Addralign: sh.Addralign, + Entsize: sh.Entsize, } } s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize)) diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go index 291f102262..e859d5aed5 100644 --- a/src/debug/gosym/pclntab.go +++ b/src/debug/gosym/pclntab.go @@ -207,8 +207,8 @@ func (t *LineTable) go12Funcs() []Func { funcs := make([]Func, n) for i := range funcs { f := &funcs[i] - f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):])) - f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):])) + f.Entry = t.uintptr(t.functab[2*i*int(t.ptrsize):]) + f.End = t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]) info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):] f.LineTable = t f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:])) diff --git a/src/debug/gosym/symtab.go b/src/debug/gosym/symtab.go index 49e154fd8e..c8fa9a0b38 100644 --- a/src/debug/gosym/symtab.go +++ b/src/debug/gosym/symtab.go @@ -294,8 +294,8 @@ func NewTable(symtab []byte, pcln *LineTable) (*Table, error) { t.Syms = t.Syms[0 : n+1] ts := &t.Syms[n] ts.Type = s.typ - ts.Value = uint64(s.value) - ts.GoType = uint64(s.gotype) + ts.Value = s.value + ts.GoType = s.gotype switch s.typ { default: // rewrite name to use . instead of · (c2 b7) diff --git a/src/encoding/asn1/marshal.go b/src/encoding/asn1/marshal.go index 2b796c4e75..30797ef099 100644 --- a/src/encoding/asn1/marshal.go +++ b/src/encoding/asn1/marshal.go @@ -315,9 +315,9 @@ func marshalUTCTime(out *forkableWriter, t time.Time) (err error) { switch { case 1950 <= year && year < 2000: - err = marshalTwoDigits(out, int(year-1900)) + err = marshalTwoDigits(out, year-1900) case 2000 <= year && year < 2050: - err = marshalTwoDigits(out, int(year-2000)) + err = marshalTwoDigits(out, year-2000) default: return StructuralError{"cannot represent time as UTCTime"} } @@ -435,7 +435,7 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter return out.WriteByte(0) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return marshalInt64(out, int64(v.Int())) + return marshalInt64(out, v.Int()) case reflect.Struct: t := v.Type() diff --git a/src/encoding/binary/binary.go b/src/encoding/binary/binary.go index ada5768695..46c6add062 100644 --- a/src/encoding/binary/binary.go +++ b/src/encoding/binary/binary.go @@ -269,7 +269,7 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error { case *uint8: b[0] = *v case uint8: - b[0] = byte(v) + b[0] = v case []uint8: bs = v case *int16: diff --git a/src/encoding/gob/encode.go b/src/encoding/gob/encode.go index 2b3a556eac..50cd6adb46 100644 --- a/src/encoding/gob/encode.go +++ b/src/encoding/gob/encode.go @@ -127,7 +127,7 @@ func (state *encoderState) encodeInt(i int64) { } else { x = uint64(i << 1) } - state.encodeUint(uint64(x)) + state.encodeUint(x) } // encOp is the signature of an encoding operator for a given type. diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go index 5ab4283826..cca2d48bbd 100644 --- a/src/go/ast/ast.go +++ b/src/go/ast/ast.go @@ -99,7 +99,7 @@ func (g *CommentGroup) Text() string { } comments := make([]string, len(g.List)) for i, c := range g.List { - comments[i] = string(c.Text) + comments[i] = c.Text } lines := make([]string, 0, 10) // most comments are less than 10 lines diff --git a/src/image/color/ycbcr.go b/src/image/color/ycbcr.go index d2c5b569a7..2e985fece1 100644 --- a/src/image/color/ycbcr.go +++ b/src/image/color/ycbcr.go @@ -237,10 +237,10 @@ func RGBToCMYK(r, g, b uint8) (uint8, uint8, uint8, uint8) { // CMYKToRGB converts a CMYK quadruple to an RGB triple. func CMYKToRGB(c, m, y, k uint8) (uint8, uint8, uint8) { - w := uint32(0xffff - uint32(k)*0x101) - r := uint32(0xffff-uint32(c)*0x101) * w / 0xffff - g := uint32(0xffff-uint32(m)*0x101) * w / 0xffff - b := uint32(0xffff-uint32(y)*0x101) * w / 0xffff + w := 0xffff - uint32(k)*0x101 + r := (0xffff - uint32(c)*0x101) * w / 0xffff + g := (0xffff - uint32(m)*0x101) * w / 0xffff + b := (0xffff - uint32(y)*0x101) * w / 0xffff return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8) } @@ -256,11 +256,11 @@ func (c CMYK) RGBA() (uint32, uint32, uint32, uint32) { // This code is a copy of the CMYKToRGB function above, except that it // returns values in the range [0, 0xffff] instead of [0, 0xff]. - w := uint32(0xffff - uint32(c.K)*0x101) - r := uint32(0xffff-uint32(c.C)*0x101) * w / 0xffff - g := uint32(0xffff-uint32(c.M)*0x101) * w / 0xffff - b := uint32(0xffff-uint32(c.Y)*0x101) * w / 0xffff - return uint32(r), uint32(g), uint32(b), 0xffff + w := 0xffff - uint32(c.K)*0x101 + r := (0xffff - uint32(c.C)*0x101) * w / 0xffff + g := (0xffff - uint32(c.M)*0x101) * w / 0xffff + b := (0xffff - uint32(c.Y)*0x101) * w / 0xffff + return r, g, b, 0xffff } // CMYKModel is the Model for CMYK colors. diff --git a/src/image/draw/draw.go b/src/image/draw/draw.go index 94e3575663..6a16cd39cf 100644 --- a/src/image/draw/draw.go +++ b/src/image/draw/draw.go @@ -634,10 +634,10 @@ func drawPaletted(dst Image, r image.Rectangle, src image.Image, sp image.Point, if !floydSteinberg { continue } - er -= int32(palette[bestIndex][0]) - eg -= int32(palette[bestIndex][1]) - eb -= int32(palette[bestIndex][2]) - ea -= int32(palette[bestIndex][3]) + er -= palette[bestIndex][0] + eg -= palette[bestIndex][1] + eb -= palette[bestIndex][2] + ea -= palette[bestIndex][3] } else { out.R = uint16(er) diff --git a/src/math/big/float.go b/src/math/big/float.go index 4b8ad388d3..7a9c2b3dfb 100644 --- a/src/math/big/float.go +++ b/src/math/big/float.go @@ -1008,9 +1008,9 @@ func (x *Float) Float64() (float64, Accuracy) { if r.form == inf || e > emax { // overflow if x.neg { - return float64(math.Inf(-1)), Below + return math.Inf(-1), Below } - return float64(math.Inf(+1)), Above + return math.Inf(+1), Above } // e <= emax diff --git a/src/math/big/natconv.go b/src/math/big/natconv.go index d2ce667fb6..e216bd288c 100644 --- a/src/math/big/natconv.go +++ b/src/math/big/natconv.go @@ -302,7 +302,7 @@ func (x nat) itoa(neg bool, base int) []byte { } } else { - bb, ndigits := maxPow(Word(b)) + bb, ndigits := maxPow(b) // construct table of successive squares of bb*leafSize to use in subdivisions // result (table != nil) <=> (len(x) > leafSize > 0) diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go index 57df124e88..7c127f8585 100644 --- a/src/math/big/ratconv.go +++ b/src/math/big/ratconv.go @@ -178,7 +178,7 @@ func scanExponent(r io.ByteScanner, binExpOk bool) (exp int64, base int, err err } break // i > 0 } - digits = append(digits, byte(ch)) + digits = append(digits, ch) } // i > 0 => we have at least one digit diff --git a/src/net/interface_bsd.go b/src/net/interface_bsd.go index b173fbcefc..17c6dd3dcd 100644 --- a/src/net/interface_bsd.go +++ b/src/net/interface_bsd.go @@ -61,13 +61,13 @@ func newLink(m *syscall.InterfaceMessage) (*Interface, error) { m.Data = m.Data[unsafe.Offsetof(sa.Data):] var name [syscall.IFNAMSIZ]byte for i := 0; i < int(sa.Nlen); i++ { - name[i] = byte(m.Data[i]) + name[i] = m.Data[i] } ifi.Name = string(name[:sa.Nlen]) ifi.MTU = int(m.Header.Data.Mtu) addr := make([]byte, sa.Alen) for i := 0; i < int(sa.Alen); i++ { - addr[i] = byte(m.Data[int(sa.Nlen)+i]) + addr[i] = m.Data[int(sa.Nlen)+i] } ifi.HardwareAddr = addr[:sa.Alen] } diff --git a/src/net/mail/message.go b/src/net/mail/message.go index 9e3a103a4f..b40a314e33 100644 --- a/src/net/mail/message.go +++ b/src/net/mail/message.go @@ -477,7 +477,7 @@ func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err er if i < p.len() && p.s[i] > 127 { return "", errNonASCII } - atom, p.s = string(p.s[:i]), p.s[i:] + atom, p.s = p.s[:i], p.s[i:] if !permissive { if strings.HasPrefix(atom, ".") { return "", errors.New("mail: leading dot in atom") diff --git a/src/net/parse.go b/src/net/parse.go index eaaa1edf30..ed82a7769b 100644 --- a/src/net/parse.go +++ b/src/net/parse.go @@ -105,14 +105,14 @@ func splitAtBytes(s string, t string) []string { for i := 0; i < len(s); i++ { if byteIndex(t, s[i]) >= 0 { if last < i { - a[n] = string(s[last:i]) + a[n] = s[last:i] n++ } last = i + 1 } } if last < len(s) { - a[n] = string(s[last:]) + a[n] = s[last:] n++ } return a[0:n] diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go index 3264271b2e..72b5a93199 100644 --- a/src/os/exec_windows.go +++ b/src/os/exec_windows.go @@ -104,7 +104,7 @@ func init() { defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv)))) Args = make([]string, argc) for i, v := range (*argv)[:argc] { - Args[i] = string(syscall.UTF16ToString((*v)[:])) + Args[i] = syscall.UTF16ToString((*v)[:]) } } diff --git a/src/os/file_windows.go b/src/os/file_windows.go index 7d04477d42..137f24a0a9 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -181,9 +181,9 @@ func (file *file) close() error { } var e error if file.isdir() { - e = syscall.FindClose(syscall.Handle(file.fd)) + e = syscall.FindClose(file.fd) } else { - e = syscall.CloseHandle(syscall.Handle(file.fd)) + e = syscall.CloseHandle(file.fd) } var err error if e != nil { @@ -216,7 +216,7 @@ func (file *File) readdir(n int) (fi []FileInfo, err error) { d := &file.dirinfo.data for n != 0 && !file.dirinfo.isempty { if file.dirinfo.needdata { - e := syscall.FindNextFile(syscall.Handle(file.fd), d) + e := syscall.FindNextFile(file.fd, d) if e != nil { if e == syscall.ERROR_NO_MORE_FILES { break @@ -230,7 +230,7 @@ func (file *File) readdir(n int) (fi []FileInfo, err error) { } } file.dirinfo.needdata = true - name := string(syscall.UTF16ToString(d.FileName[0:])) + name := syscall.UTF16ToString(d.FileName[0:]) if name == "." || name == ".." { // Useless names continue } @@ -288,7 +288,7 @@ func (f *File) readConsole(b []byte) (n int, err error) { } wchars := make([]uint16, nwc) pwc := &wchars[0] - nwc, err = windows.MultiByteToWideChar(acp, 2, pmb, int32(nmb), pwc, int32(nwc)) + nwc, err = windows.MultiByteToWideChar(acp, 2, pmb, int32(nmb), pwc, nwc) if err != nil { return 0, err } @@ -335,7 +335,7 @@ func (f *File) pread(b []byte, off int64) (n int, err error) { Offset: uint32(off), } var done uint32 - e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o) + e = syscall.ReadFile(f.fd, b, &done, &o) if e != nil { if e == syscall.ERROR_HANDLE_EOF { // end of file @@ -415,7 +415,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { Offset: uint32(off), } var done uint32 - e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o) + e = syscall.WriteFile(f.fd, b, &done, &o) if e != nil { return 0, e } diff --git a/src/os/stat_darwin.go b/src/os/stat_darwin.go index 9dc7a99fb7..74214cefa4 100644 --- a/src/os/stat_darwin.go +++ b/src/os/stat_darwin.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtimespec) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { diff --git a/src/os/stat_dragonfly.go b/src/os/stat_dragonfly.go index 69e63230eb..217bc6726d 100644 --- a/src/os/stat_dragonfly.go +++ b/src/os/stat_dragonfly.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtim) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { @@ -42,7 +42,7 @@ func fillFileStatFromSys(fs *fileStat, name string) { } func timespecToTime(ts syscall.Timespec) time.Time { - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) + return time.Unix(ts.Sec, ts.Nsec) } // For testing. diff --git a/src/os/stat_freebsd.go b/src/os/stat_freebsd.go index e9d38aa722..bab4ffa798 100644 --- a/src/os/stat_freebsd.go +++ b/src/os/stat_freebsd.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtimespec) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { diff --git a/src/os/stat_linux.go b/src/os/stat_linux.go index 69e63230eb..d36afa9ffd 100644 --- a/src/os/stat_linux.go +++ b/src/os/stat_linux.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtim) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { diff --git a/src/os/stat_nacl.go b/src/os/stat_nacl.go index d3bed14e43..0c53f2faa4 100644 --- a/src/os/stat_nacl.go +++ b/src/os/stat_nacl.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtime, fs.sys.MtimeNsec) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { diff --git a/src/os/stat_netbsd.go b/src/os/stat_netbsd.go index e9d38aa722..11ebcacab8 100644 --- a/src/os/stat_netbsd.go +++ b/src/os/stat_netbsd.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtimespec) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { @@ -42,7 +42,7 @@ func fillFileStatFromSys(fs *fileStat, name string) { } func timespecToTime(ts syscall.Timespec) time.Time { - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) + return time.Unix(ts.Sec, int64(ts.Nsec)) } // For testing. diff --git a/src/os/stat_openbsd.go b/src/os/stat_openbsd.go index 69e63230eb..9df2d7f773 100644 --- a/src/os/stat_openbsd.go +++ b/src/os/stat_openbsd.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtim) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { @@ -42,7 +42,7 @@ func fillFileStatFromSys(fs *fileStat, name string) { } func timespecToTime(ts syscall.Timespec) time.Time { - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) + return time.Unix(ts.Sec, int64(ts.Nsec)) } // For testing. diff --git a/src/os/stat_plan9.go b/src/os/stat_plan9.go index a2df5fe139..96f056c111 100644 --- a/src/os/stat_plan9.go +++ b/src/os/stat_plan9.go @@ -20,7 +20,7 @@ func sameFile(fs1, fs2 *fileStat) bool { func fileInfoFromStat(d *syscall.Dir) FileInfo { fs := &fileStat{ name: d.Name, - size: int64(d.Length), + size: d.Length, modTime: time.Unix(int64(d.Mtime), 0), sys: d, } diff --git a/src/os/stat_solaris.go b/src/os/stat_solaris.go index 69e63230eb..217bc6726d 100644 --- a/src/os/stat_solaris.go +++ b/src/os/stat_solaris.go @@ -11,7 +11,7 @@ import ( func fillFileStatFromSys(fs *fileStat, name string) { fs.name = basename(name) - fs.size = int64(fs.sys.Size) + fs.size = fs.sys.Size fs.modTime = timespecToTime(fs.sys.Mtim) fs.mode = FileMode(fs.sys.Mode & 0777) switch fs.sys.Mode & syscall.S_IFMT { @@ -42,7 +42,7 @@ func fillFileStatFromSys(fs *fileStat, name string) { } func timespecToTime(ts syscall.Timespec) time.Time { - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) + return time.Unix(ts.Sec, ts.Nsec) } // For testing. diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go index b8f97ad60a..e55eeb0fdd 100644 --- a/src/os/stat_windows.go +++ b/src/os/stat_windows.go @@ -35,7 +35,7 @@ func (file *File) Stat() (FileInfo, error) { } var d syscall.ByHandleFileInformation - err = syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d) + err = syscall.GetFileInformationByHandle(file.fd, &d) if err != nil { return nil, &PathError{"GetFileInformationByHandle", file.name, err} } diff --git a/src/os/types_windows.go b/src/os/types_windows.go index 900d444b0e..ad4e863fcb 100644 --- a/src/os/types_windows.go +++ b/src/os/types_windows.go @@ -73,7 +73,7 @@ func (fs *fileStat) loadFileId() error { } defer syscall.CloseHandle(h) var i syscall.ByHandleFileInformation - err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i) + err = syscall.GetFileInformationByHandle(h, &i) if err != nil { return err } diff --git a/src/reflect/type.go b/src/reflect/type.go index 3c7affcd7f..b8c778cc2b 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -967,7 +967,7 @@ func (t *rtype) Out(i int) Type { } func (t *funcType) in() []*rtype { - uadd := uintptr(unsafe.Sizeof(*t)) + uadd := unsafe.Sizeof(*t) if t.tflag&tflagUncommon != 0 { uadd += unsafe.Sizeof(uncommonType{}) } @@ -975,7 +975,7 @@ func (t *funcType) in() []*rtype { } func (t *funcType) out() []*rtype { - uadd := uintptr(unsafe.Sizeof(*t)) + uadd := unsafe.Sizeof(*t) if t.tflag&tflagUncommon != 0 { uadd += unsafe.Sizeof(uncommonType{}) } diff --git a/src/reflect/value.go b/src/reflect/value.go index d72c14e9e1..d4d317436a 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -666,7 +666,7 @@ func (v Value) Cap() int { case Array: return v.typ.Len() case Chan: - return int(chancap(v.pointer())) + return chancap(v.pointer()) case Slice: // Slice is always bigger than a word; assume flagIndir. return (*sliceHeader)(v.ptr).Cap @@ -885,7 +885,7 @@ func (v Value) Int() int64 { case Int32: return int64(*(*int32)(p)) case Int64: - return int64(*(*int64)(p)) + return *(*int64)(p) } panic(&ValueError{"reflect.Value.Int", v.kind()}) } @@ -1436,7 +1436,7 @@ func (v Value) SetCap(n int) { v.mustBeAssignable() v.mustBe(Slice) s := (*sliceHeader)(v.ptr) - if n < int(s.Len) || n > int(s.Cap) { + if n < s.Len || n > s.Cap { panic("reflect: slice capacity out of range in SetCap") } s.Cap = n @@ -1538,7 +1538,7 @@ func (v Value) Slice(i, j int) Value { case Slice: typ = (*sliceType)(unsafe.Pointer(v.typ)) s := (*sliceHeader)(v.ptr) - base = unsafe.Pointer(s.Data) + base = s.Data cap = s.Cap case String: @@ -1710,7 +1710,7 @@ func (v Value) Uint() uint64 { case Uint32: return uint64(*(*uint32)(p)) case Uint64: - return uint64(*(*uint64)(p)) + return *(*uint64)(p) case Uintptr: return uint64(*(*uintptr)(p)) } @@ -2267,13 +2267,13 @@ func makeInt(f flag, bits uint64, t Type) Value { ptr := unsafe_New(typ) switch typ.size { case 1: - *(*uint8)(unsafe.Pointer(ptr)) = uint8(bits) + *(*uint8)(ptr) = uint8(bits) case 2: - *(*uint16)(unsafe.Pointer(ptr)) = uint16(bits) + *(*uint16)(ptr) = uint16(bits) case 4: - *(*uint32)(unsafe.Pointer(ptr)) = uint32(bits) + *(*uint32)(ptr) = uint32(bits) case 8: - *(*uint64)(unsafe.Pointer(ptr)) = bits + *(*uint64)(ptr) = bits } return Value{typ, ptr, f | flagIndir | flag(typ.Kind())} } @@ -2285,9 +2285,9 @@ func makeFloat(f flag, v float64, t Type) Value { ptr := unsafe_New(typ) switch typ.size { case 4: - *(*float32)(unsafe.Pointer(ptr)) = float32(v) + *(*float32)(ptr) = float32(v) case 8: - *(*float64)(unsafe.Pointer(ptr)) = v + *(*float64)(ptr) = v } return Value{typ, ptr, f | flagIndir | flag(typ.Kind())} } @@ -2299,9 +2299,9 @@ func makeComplex(f flag, v complex128, t Type) Value { ptr := unsafe_New(typ) switch typ.size { case 8: - *(*complex64)(unsafe.Pointer(ptr)) = complex64(v) + *(*complex64)(ptr) = complex64(v) case 16: - *(*complex128)(unsafe.Pointer(ptr)) = v + *(*complex128)(ptr) = v } return Value{typ, ptr, f | flagIndir | flag(typ.Kind())} } diff --git a/src/regexp/onepass.go b/src/regexp/onepass.go index 5b82f9666e..4991954820 100644 --- a/src/regexp/onepass.go +++ b/src/regexp/onepass.go @@ -450,7 +450,7 @@ func makeOnePass(p *onePassProg) *onePassProg { for !instQueue.empty() { visitQueue.clear() pc := instQueue.next() - if !check(uint32(pc), m) { + if !check(pc, m) { p = notOnePass break } diff --git a/src/strconv/extfloat.go b/src/strconv/extfloat.go index 019b4eebdc..7033e96c39 100644 --- a/src/strconv/extfloat.go +++ b/src/strconv/extfloat.go @@ -311,9 +311,9 @@ func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc boo var extrabits uint if f.exp <= denormalExp { // f.mant * 2^f.exp is smaller than 2^(flt.bias+1). - extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp)) + extrabits = 63 - flt.mantbits + 1 + uint(denormalExp-f.exp) } else { - extrabits = uint(63 - flt.mantbits) + extrabits = 63 - flt.mantbits } halfway := uint64(1) << (extrabits - 1) diff --git a/src/strings/reader.go b/src/strings/reader.go index 737873c099..74eed4d574 100644 --- a/src/strings/reader.go +++ b/src/strings/reader.go @@ -113,7 +113,7 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) { case 0: abs = offset case 1: - abs = int64(r.i) + offset + abs = r.i + offset case 2: abs = int64(len(r.s)) + offset default: diff --git a/src/sync/pool.go b/src/sync/pool.go index 4fb1a1af9d..2acf505f3c 100644 --- a/src/sync/pool.go +++ b/src/sync/pool.go @@ -179,8 +179,8 @@ func (p *Pool) pinSlow() *poolLocal { // If GOMAXPROCS changes between GCs, we re-allocate the array and lose the old one. size := runtime.GOMAXPROCS(0) local := make([]poolLocal, size) - atomic.StorePointer((*unsafe.Pointer)(&p.local), unsafe.Pointer(&local[0])) // store-release - atomic.StoreUintptr(&p.localSize, uintptr(size)) // store-release + atomic.StorePointer(&p.local, unsafe.Pointer(&local[0])) // store-release + atomic.StoreUintptr(&p.localSize, uintptr(size)) // store-release return &local[pid] } diff --git a/src/time/time.go b/src/time/time.go index 4b9a0db730..92d635eec5 100644 --- a/src/time/time.go +++ b/src/time/time.go @@ -606,7 +606,7 @@ func (d Duration) Hours() float64 { // Add returns the time t+d. func (t Time) Add(d Duration) Time { t.sec += int64(d / 1e9) - nsec := int32(t.nsec) + int32(d%1e9) + nsec := t.nsec + int32(d%1e9) if nsec >= 1e9 { t.sec++ nsec -= 1e9 @@ -623,7 +623,7 @@ func (t Time) Add(d Duration) Time { // will be returned. // To compute t-d for a duration d, use t.Add(-d). func (t Time) Sub(u Time) Duration { - d := Duration(t.sec-u.sec)*Second + Duration(int32(t.nsec)-int32(u.nsec)) + d := Duration(t.sec-u.sec)*Second + Duration(t.nsec-u.nsec) // Check for overflow or underflow. switch { case u.Add(d).Equal(t): @@ -1125,7 +1125,7 @@ func (t Time) Round(d Duration) Time { // but it's still here in case we change our minds. func div(t Time, d Duration) (qmod2 int, r Duration) { neg := false - nsec := int32(t.nsec) + nsec := t.nsec if t.sec < 0 { // Operate on absolute value. neg = true @@ -1159,7 +1159,7 @@ func div(t Time, d Duration) (qmod2 int, r Duration) { tmp := (sec >> 32) * 1e9 u1 := tmp >> 32 u0 := tmp << 32 - tmp = uint64(sec&0xFFFFFFFF) * 1e9 + tmp = (sec & 0xFFFFFFFF) * 1e9 u0x, u0 := u0, u0+tmp if u0 < u0x { u1++ diff --git a/src/time/zoneinfo_windows.go b/src/time/zoneinfo_windows.go index bcb8ccd563..c753119d5d 100644 --- a/src/time/zoneinfo_windows.go +++ b/src/time/zoneinfo_windows.go @@ -83,7 +83,7 @@ func extractCAPS(desc string) string { var short []rune for _, c := range desc { if 'A' <= c && c <= 'Z' { - short = append(short, rune(c)) + short = append(short, c) } } return string(short) diff --git a/src/unicode/letter.go b/src/unicode/letter.go index 8443ee51a2..ffa083eb57 100644 --- a/src/unicode/letter.go +++ b/src/unicode/letter.go @@ -217,7 +217,7 @@ func to(_case int, r rune, caseRange []CaseRange) rune { m := lo + (hi-lo)/2 cr := caseRange[m] if rune(cr.Lo) <= r && r <= rune(cr.Hi) { - delta := rune(cr.Delta[_case]) + delta := cr.Delta[_case] if delta > MaxRune { // In an Upper-Lower sequence, which always starts with // an UpperCase letter, the real deltas always look like: -- cgit v1.3 From 462aa7ec7b854f5a1bb4f633cb439eb67bced625 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 13 Apr 2016 18:14:52 +0000 Subject: encoding/json: update docs to not use misuse the term "object" In JSON terminology, "object" is a collect of key/value pairs. But a JSON object is only one type of JSON value (others are string, number, array, true, false, null). This updates the Go docs (at least the public godoc) to not use "object" when we mean any JSON value. Change-Id: Ieb1c456c703693714d63d9d09d306f4d9e8f4597 Reviewed-on: https://go-review.googlesource.com/22003 Reviewed-by: Andrew Gerrand --- src/encoding/json/decode.go | 2 +- src/encoding/json/encode.go | 12 ++++++------ src/encoding/json/stream.go | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/encoding') diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index a7ff8cf3dc..434edf8ea4 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -97,7 +97,7 @@ func Unmarshal(data []byte, v interface{}) error { return d.unmarshal(v) } -// Unmarshaler is the interface implemented by objects +// Unmarshaler is the interface implemented by types // that can unmarshal a JSON description of themselves. // The input can be assumed to be a valid encoding of // a JSON value. UnmarshalJSON must copy the JSON data diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 927f47b179..0088f25ab8 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package json implements encoding and decoding of JSON objects as defined in -// RFC 4627. The mapping between JSON objects and Go values is described +// Package json implements encoding and decoding of JSON as defined in +// RFC 4627. The mapping between JSON and Go values is described // in the documentation for the Marshal and Unmarshal functions. // // See "JSON and Go" for an introduction to this package: @@ -52,7 +52,7 @@ import ( // // Array and slice values encode as JSON arrays, except that // []byte encodes as a base64-encoded string, and a nil slice -// encodes as the null JSON object. +// encodes as the null JSON value. // // Struct values encode as JSON objects. Each exported struct field // becomes a member of the object unless @@ -121,10 +121,10 @@ import ( // keys, subject to the UTF-8 coercion described for string values above. // // Pointer values encode as the value pointed to. -// A nil pointer encodes as the null JSON object. +// A nil pointer encodes as the null JSON value. // // Interface values encode as the value contained in the interface. -// A nil interface value encodes as the null JSON object. +// A nil interface value encodes as the null JSON value. // // Channel, complex, and function values cannot be encoded in JSON. // Attempting to encode such a value causes Marshal to return @@ -192,7 +192,7 @@ func HTMLEscape(dst *bytes.Buffer, src []byte) { } } -// Marshaler is the interface implemented by objects that +// Marshaler is the interface implemented by types that // can marshal themselves into valid JSON. type Marshaler interface { MarshalJSON() ([]byte, error) diff --git a/src/encoding/json/stream.go b/src/encoding/json/stream.go index b740d32a7d..422837bb63 100644 --- a/src/encoding/json/stream.go +++ b/src/encoding/json/stream.go @@ -10,7 +10,7 @@ import ( "io" ) -// A Decoder reads and decodes JSON objects from an input stream. +// A Decoder reads and decodes JSON values from an input stream. type Decoder struct { r io.Reader buf []byte @@ -164,7 +164,7 @@ func nonSpace(b []byte) bool { return false } -// An Encoder writes JSON objects to an output stream. +// An Encoder writes JSON values to an output stream. type Encoder struct { w io.Writer err error @@ -218,14 +218,14 @@ func (enc *Encoder) Encode(v interface{}) error { return err } -// Indent sets the encoder to format each encoded object with Indent. +// Indent sets the encoder to format each encoded value with Indent. func (enc *Encoder) Indent(prefix, indent string) { enc.indentBuf = new(bytes.Buffer) enc.indentPrefix = prefix enc.indentValue = indent } -// RawMessage is a raw encoded JSON object. +// RawMessage is a raw encoded JSON value. // It implements Marshaler and Unmarshaler and can // be used to delay JSON decoding or precompute a JSON encoding. type RawMessage []byte -- cgit v1.3 From 8082828ed0b07225c50a991dbe2a176346fba3b8 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Thu, 21 Apr 2016 12:43:22 -0700 Subject: encoding/gob: document compatibility Fixes #13808. Change-Id: Ifbd5644da995a812438a405485c9e08b4503a313 Reviewed-on: https://go-review.googlesource.com/22352 Reviewed-by: Ian Lance Taylor --- src/encoding/gob/doc.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/encoding') diff --git a/src/encoding/gob/doc.go b/src/encoding/gob/doc.go index cf878f4502..6f86d84891 100644 --- a/src/encoding/gob/doc.go +++ b/src/encoding/gob/doc.go @@ -254,6 +254,12 @@ In summary, a gob stream looks like where * signifies zero or more repetitions and the type id of a value must be predefined or be defined before the value in the stream. +Compatibility: Any future changes to the package will endeavor to maintain +compatibility with streams encoded using previous versions. That is, any released +version of this package should be able to decode data written with any previously +released version, subject to issues such as security fixes. See the Go compatibility +document for background: https://golang.org/doc/go1compat + See "Gobs of data" for a design discussion of the gob wire format: https://blog.golang.org/gobs-of-data */ -- cgit v1.3 From ab52ad894f453a02153fb2bc106d08c47ba643b6 Mon Sep 17 00:00:00 2001 From: Caleb Spare Date: Sat, 9 Apr 2016 21:18:22 -0700 Subject: encoding/json: add Encoder.DisableHTMLEscaping This provides a way to disable the escaping of <, >, and & in JSON strings. Fixes #14749. Change-Id: I1afeb0244455fc8b06c6cce920444532f229555b Reviewed-on: https://go-review.googlesource.com/21796 Run-TryBot: Caleb Spare TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/encoding/json/encode.go | 139 +++++++++++++++++++++------------------ src/encoding/json/encode_test.go | 56 ++++++++-------- src/encoding/json/stream.go | 15 +++-- src/encoding/json/stream_test.go | 33 ++++++++++ 4 files changed, 150 insertions(+), 93 deletions(-) (limited to 'src/encoding') diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 0088f25ab8..d8c779869b 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -49,6 +49,7 @@ import ( // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" // to keep some browsers from misinterpreting JSON output as HTML. // Ampersand "&" is also escaped to "\u0026" for the same reason. +// This escaping can be disabled using an Encoder with DisableHTMLEscaping. // // Array and slice values encode as JSON arrays, except that // []byte encodes as a base64-encoded string, and a nil slice @@ -136,7 +137,7 @@ import ( // func Marshal(v interface{}) ([]byte, error) { e := &encodeState{} - err := e.marshal(v) + err := e.marshal(v, encOpts{escapeHTML: true}) if err != nil { return nil, err } @@ -259,7 +260,7 @@ func newEncodeState() *encodeState { return new(encodeState) } -func (e *encodeState) marshal(v interface{}) (err error) { +func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) { defer func() { if r := recover(); r != nil { if _, ok := r.(runtime.Error); ok { @@ -271,7 +272,7 @@ func (e *encodeState) marshal(v interface{}) (err error) { err = r.(error) } }() - e.reflectValue(reflect.ValueOf(v)) + e.reflectValue(reflect.ValueOf(v), opts) return nil } @@ -297,11 +298,18 @@ func isEmptyValue(v reflect.Value) bool { return false } -func (e *encodeState) reflectValue(v reflect.Value) { - valueEncoder(v)(e, v, false) +func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) { + valueEncoder(v)(e, v, opts) } -type encoderFunc func(e *encodeState, v reflect.Value, quoted bool) +type encOpts struct { + // quoted causes primitive fields to be encoded inside JSON strings. + quoted bool + // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings. + escapeHTML bool +} + +type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts) var encoderCache struct { sync.RWMutex @@ -333,9 +341,9 @@ func typeEncoder(t reflect.Type) encoderFunc { } var wg sync.WaitGroup wg.Add(1) - encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) { + encoderCache.m[t] = func(e *encodeState, v reflect.Value, opts encOpts) { wg.Wait() - f(e, v, quoted) + f(e, v, opts) } encoderCache.Unlock() @@ -405,11 +413,11 @@ func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { } } -func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) { +func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) { e.WriteString("null") } -func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { +func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.Kind() == reflect.Ptr && v.IsNil() { e.WriteString("null") return @@ -418,14 +426,14 @@ func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { b, err := m.MarshalJSON() if err == nil { // copy JSON into buffer, checking validity. - err = compact(&e.Buffer, b, true) + err = compact(&e.Buffer, b, opts.escapeHTML) } if err != nil { e.error(&MarshalerError{v.Type(), err}) } } -func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { +func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) { va := v.Addr() if va.IsNil() { e.WriteString("null") @@ -442,7 +450,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { } } -func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { +func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.Kind() == reflect.Ptr && v.IsNil() { e.WriteString("null") return @@ -452,10 +460,10 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { if err != nil { e.error(&MarshalerError{v.Type(), err}) } - e.stringBytes(b) + e.stringBytes(b, opts.escapeHTML) } -func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { +func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { va := v.Addr() if va.IsNil() { e.WriteString("null") @@ -466,11 +474,11 @@ func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { if err != nil { e.error(&MarshalerError{v.Type(), err}) } - e.stringBytes(b) + e.stringBytes(b, opts.escapeHTML) } -func boolEncoder(e *encodeState, v reflect.Value, quoted bool) { - if quoted { +func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) { + if opts.quoted { e.WriteByte('"') } if v.Bool() { @@ -478,46 +486,46 @@ func boolEncoder(e *encodeState, v reflect.Value, quoted bool) { } else { e.WriteString("false") } - if quoted { + if opts.quoted { e.WriteByte('"') } } -func intEncoder(e *encodeState, v reflect.Value, quoted bool) { +func intEncoder(e *encodeState, v reflect.Value, opts encOpts) { b := strconv.AppendInt(e.scratch[:0], v.Int(), 10) - if quoted { + if opts.quoted { e.WriteByte('"') } e.Write(b) - if quoted { + if opts.quoted { e.WriteByte('"') } } -func uintEncoder(e *encodeState, v reflect.Value, quoted bool) { +func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) { b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10) - if quoted { + if opts.quoted { e.WriteByte('"') } e.Write(b) - if quoted { + if opts.quoted { e.WriteByte('"') } } type floatEncoder int // number of bits -func (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { +func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { f := v.Float() if math.IsInf(f, 0) || math.IsNaN(f) { e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))}) } b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, int(bits)) - if quoted { + if opts.quoted { e.WriteByte('"') } e.Write(b) - if quoted { + if opts.quoted { e.WriteByte('"') } } @@ -527,7 +535,7 @@ var ( float64Encoder = (floatEncoder(64)).encode ) -func stringEncoder(e *encodeState, v reflect.Value, quoted bool) { +func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.Type() == numberType { numStr := v.String() // In Go1.5 the empty string encodes to "0", while this is not a valid number literal @@ -541,26 +549,26 @@ func stringEncoder(e *encodeState, v reflect.Value, quoted bool) { e.WriteString(numStr) return } - if quoted { + if opts.quoted { sb, err := Marshal(v.String()) if err != nil { e.error(err) } - e.string(string(sb)) + e.string(string(sb), opts.escapeHTML) } else { - e.string(v.String()) + e.string(v.String(), opts.escapeHTML) } } -func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) { +func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.IsNil() { e.WriteString("null") return } - e.reflectValue(v.Elem()) + e.reflectValue(v.Elem(), opts) } -func unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) { +func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) { e.error(&UnsupportedTypeError{v.Type()}) } @@ -569,7 +577,7 @@ type structEncoder struct { fieldEncs []encoderFunc } -func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { +func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { e.WriteByte('{') first := true for i, f := range se.fields { @@ -582,9 +590,10 @@ func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { } else { e.WriteByte(',') } - e.string(f.name) + e.string(f.name, opts.escapeHTML) e.WriteByte(':') - se.fieldEncs[i](e, fv, f.quoted) + opts.quoted = f.quoted + se.fieldEncs[i](e, fv, opts) } e.WriteByte('}') } @@ -605,7 +614,7 @@ type mapEncoder struct { elemEnc encoderFunc } -func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) { +func (me *mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { if v.IsNil() { e.WriteString("null") return @@ -627,9 +636,9 @@ func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) { if i > 0 { e.WriteByte(',') } - e.string(kv.s) + e.string(kv.s, opts.escapeHTML) e.WriteByte(':') - me.elemEnc(e, v.MapIndex(kv.v), false) + me.elemEnc(e, v.MapIndex(kv.v), opts) } e.WriteByte('}') } @@ -642,7 +651,7 @@ func newMapEncoder(t reflect.Type) encoderFunc { return me.encode } -func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) { +func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) { if v.IsNil() { e.WriteString("null") return @@ -669,12 +678,12 @@ type sliceEncoder struct { arrayEnc encoderFunc } -func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) { +func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { if v.IsNil() { e.WriteString("null") return } - se.arrayEnc(e, v, false) + se.arrayEnc(e, v, opts) } func newSliceEncoder(t reflect.Type) encoderFunc { @@ -692,14 +701,14 @@ type arrayEncoder struct { elemEnc encoderFunc } -func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) { +func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { e.WriteByte('[') n := v.Len() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } - ae.elemEnc(e, v.Index(i), false) + ae.elemEnc(e, v.Index(i), opts) } e.WriteByte(']') } @@ -713,12 +722,12 @@ type ptrEncoder struct { elemEnc encoderFunc } -func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { +func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { if v.IsNil() { e.WriteString("null") return } - pe.elemEnc(e, v.Elem(), quoted) + pe.elemEnc(e, v.Elem(), opts) } func newPtrEncoder(t reflect.Type) encoderFunc { @@ -730,11 +739,11 @@ type condAddrEncoder struct { canAddrEnc, elseEnc encoderFunc } -func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { +func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { if v.CanAddr() { - ce.canAddrEnc(e, v, quoted) + ce.canAddrEnc(e, v, opts) } else { - ce.elseEnc(e, v, quoted) + ce.elseEnc(e, v, opts) } } @@ -812,13 +821,14 @@ func (sv byString) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } func (sv byString) Less(i, j int) bool { return sv[i].s < sv[j].s } // NOTE: keep in sync with stringBytes below. -func (e *encodeState) string(s string) int { +func (e *encodeState) string(s string, escapeHTML bool) int { len0 := e.Len() e.WriteByte('"') start := 0 for i := 0; i < len(s); { if b := s[i]; b < utf8.RuneSelf { - if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' { + if 0x20 <= b && b != '\\' && b != '"' && + (!escapeHTML || b != '<' && b != '>' && b != '&') { i++ continue } @@ -839,10 +849,11 @@ func (e *encodeState) string(s string) int { e.WriteByte('\\') e.WriteByte('t') default: - // This encodes bytes < 0x20 except for \n and \r, - // as well as <, > and &. The latter are escaped because they - // can lead to security holes when user-controlled strings - // are rendered into JSON and served to some browsers. + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. e.WriteString(`\u00`) e.WriteByte(hex[b>>4]) e.WriteByte(hex[b&0xF]) @@ -888,13 +899,14 @@ func (e *encodeState) string(s string) int { } // NOTE: keep in sync with string above. -func (e *encodeState) stringBytes(s []byte) int { +func (e *encodeState) stringBytes(s []byte, escapeHTML bool) int { len0 := e.Len() e.WriteByte('"') start := 0 for i := 0; i < len(s); { if b := s[i]; b < utf8.RuneSelf { - if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' { + if 0x20 <= b && b != '\\' && b != '"' && + (!escapeHTML || b != '<' && b != '>' && b != '&') { i++ continue } @@ -915,10 +927,11 @@ func (e *encodeState) stringBytes(s []byte) int { e.WriteByte('\\') e.WriteByte('t') default: - // This encodes bytes < 0x20 except for \n and \r, - // as well as <, >, and &. The latter are escaped because they - // can lead to security holes when user-controlled strings - // are rendered into JSON and served to some browsers. + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. e.WriteString(`\u00`) e.WriteByte(hex[b>>4]) e.WriteByte(hex[b&0xF]) diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index eee59ccb49..b484022a70 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -376,41 +376,45 @@ func TestDuplicatedFieldDisappears(t *testing.T) { func TestStringBytes(t *testing.T) { // Test that encodeState.stringBytes and encodeState.string use the same encoding. - es := &encodeState{} var r []rune for i := '\u0000'; i <= unicode.MaxRune; i++ { r = append(r, i) } s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too - es.string(s) - esBytes := &encodeState{} - esBytes.stringBytes([]byte(s)) + for _, escapeHTML := range []bool{true, false} { + es := &encodeState{} + es.string(s, escapeHTML) - enc := es.Buffer.String() - encBytes := esBytes.Buffer.String() - if enc != encBytes { - i := 0 - for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] { - i++ - } - enc = enc[i:] - encBytes = encBytes[i:] - i = 0 - for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] { - i++ - } - enc = enc[:len(enc)-i] - encBytes = encBytes[:len(encBytes)-i] + esBytes := &encodeState{} + esBytes.stringBytes([]byte(s), escapeHTML) - if len(enc) > 20 { - enc = enc[:20] + "..." - } - if len(encBytes) > 20 { - encBytes = encBytes[:20] + "..." - } + enc := es.Buffer.String() + encBytes := esBytes.Buffer.String() + if enc != encBytes { + i := 0 + for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] { + i++ + } + enc = enc[i:] + encBytes = encBytes[i:] + i = 0 + for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] { + i++ + } + enc = enc[:len(enc)-i] + encBytes = encBytes[:len(encBytes)-i] - t.Errorf("encodings differ at %#q vs %#q", enc, encBytes) + if len(enc) > 20 { + enc = enc[:20] + "..." + } + if len(encBytes) > 20 { + encBytes = encBytes[:20] + "..." + } + + t.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q", + escapeHTML, enc, encBytes) + } } } diff --git a/src/encoding/json/stream.go b/src/encoding/json/stream.go index 422837bb63..d6b2992e9b 100644 --- a/src/encoding/json/stream.go +++ b/src/encoding/json/stream.go @@ -166,8 +166,9 @@ func nonSpace(b []byte) bool { // An Encoder writes JSON values to an output stream. type Encoder struct { - w io.Writer - err error + w io.Writer + err error + escapeHTML bool indentBuf *bytes.Buffer indentPrefix string @@ -176,7 +177,7 @@ type Encoder struct { // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { - return &Encoder{w: w} + return &Encoder{w: w, escapeHTML: true} } // Encode writes the JSON encoding of v to the stream, @@ -189,7 +190,7 @@ func (enc *Encoder) Encode(v interface{}) error { return enc.err } e := newEncodeState() - err := e.marshal(v) + err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML}) if err != nil { return err } @@ -225,6 +226,12 @@ func (enc *Encoder) Indent(prefix, indent string) { enc.indentValue = indent } +// DisableHTMLEscaping causes the encoder not to escape angle brackets +// ("<" and ">") or ampersands ("&") in JSON strings. +func (enc *Encoder) DisableHTMLEscaping() { + enc.escapeHTML = false +} + // RawMessage is a raw encoded JSON value. // It implements Marshaler and Unmarshaler and can // be used to delay JSON decoding or precompute a JSON encoding. diff --git a/src/encoding/json/stream_test.go b/src/encoding/json/stream_test.go index db25708f4c..3516ac3b83 100644 --- a/src/encoding/json/stream_test.go +++ b/src/encoding/json/stream_test.go @@ -87,6 +87,39 @@ func TestEncoderIndent(t *testing.T) { } } +func TestEncoderDisableHTMLEscaping(t *testing.T) { + var c C + var ct CText + for _, tt := range []struct { + name string + v interface{} + wantEscape string + want string + }{ + {"c", c, `"\u003c\u0026\u003e"`, `"<&>"`}, + {"ct", ct, `"\"\u003c\u0026\u003e\""`, `"\"<&>\""`}, + {`"<&>"`, "<&>", `"\u003c\u0026\u003e"`, `"<&>"`}, + } { + var buf bytes.Buffer + enc := NewEncoder(&buf) + if err := enc.Encode(tt.v); err != nil { + t.Fatalf("Encode(%s): %s", tt.name, err) + } + if got := strings.TrimSpace(buf.String()); got != tt.wantEscape { + t.Errorf("Encode(%s) = %#q, want %#q", tt.name, got, tt.wantEscape) + } + buf.Reset() + enc.DisableHTMLEscaping() + if err := enc.Encode(tt.v); err != nil { + t.Fatalf("DisableHTMLEscaping Encode(%s): %s", tt.name, err) + } + if got := strings.TrimSpace(buf.String()); got != tt.want { + t.Errorf("DisableHTMLEscaping Encode(%s) = %#q, want %#q", + tt.name, got, tt.want) + } + } +} + func TestDecoder(t *testing.T) { for i := 0; i <= len(streamTest); i++ { // Use stream without newlines as input, -- cgit v1.3